1/**
2 * Copyright (c) 2018 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Daniel Carvalho
29 */
30
31/** @file
32 * Implementation of a simple superblock class. Each superblock consists of a
33 * number of compressed cache blocks limited by the maximum compression factor
34 * that may or may not be present in the cache.
35 */
36
37#include "mem/cache/tags/super_blk.hh"
38
39#include "base/logging.hh"
40
41CompressionBlk::CompressionBlk()
42    : SectorSubBlk(), _size(0), _decompressionLatency(0)
43{
44}
45
46bool
47CompressionBlk::isCompressed() const
48{
49    return (status & BlkCompressed) != 0;
50}
51
52void
53CompressionBlk::setCompressed()
54{
55    status |= BlkCompressed;
56}
57
58void
59CompressionBlk::setUncompressed()
60{
61    status &= ~BlkCompressed;
62}
63
64std::size_t
65CompressionBlk::getSizeBits() const
66{
67    return _size;
68}
69
70void
71CompressionBlk::setSizeBits(const std::size_t size)
72{
73    _size = size;
74}
75
76Cycles
77CompressionBlk::getDecompressionLatency() const
78{
79    return _decompressionLatency;
80}
81
82void
83CompressionBlk::setDecompressionLatency(const Cycles lat)
84{
85    _decompressionLatency = lat;
86}
87
88std::string
89CompressionBlk::print() const
90{
91    return csprintf("%s compressed: %d size: %llu decompression latency: %d",
92                    SectorSubBlk::print(), isCompressed(), getSizeBits(),
93                    getDecompressionLatency());
94}
95
96bool
97SuperBlk::isCompressed(const CompressionBlk* ignored_blk) const
98{
99    for (const auto& blk : blks) {
100        if (blk->isValid() && (blk != ignored_blk)) {
101            return static_cast<CompressionBlk*>(blk)->isCompressed();
102        }
103    }
104
105    // An invalid block is seen as compressed
106    return true;
107}
108
109bool
110SuperBlk::canCoAllocate(const std::size_t compressed_size) const
111{
112    // Simple co-allocation function: at most numBlocksPerSector blocks that
113    // compress at least to (100/numBlocksPerSector)% of their original size
114    // can share a superblock
115    return (compressed_size <= (blkSize * 8) / blks.size());
116}
117
118void
119SuperBlk::setBlkSize(const std::size_t blk_size)
120{
121    assert(blkSize == 0);
122    blkSize = blk_size;
123}
124