1/* 2 * Copyright (c) 2012-15 Advanced Micro Devices, Inc. 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 29#ifndef __MEM_RUBY_COMMON_WRITEMASK_HH__ 30#define __MEM_RUBY_COMMON_WRITEMASK_HH__ 31 32#include <cassert> 33#include <iomanip> 34#include <iostream> 35#include <vector> 36 37#include "mem/ruby/common/TypeDefines.hh" 38#include "mem/ruby/system/RubySystem.hh" 39 40class WriteMask 41{ 42 public: 43 WriteMask() 44 : mSize(RubySystem::getBlockSizeBytes()), mMask(mSize, false), 45 mAtomic(false) 46 {} 47 48 WriteMask(int size) 49 : mSize(size), mMask(size, false), mAtomic(false) 50 {} 51 52 WriteMask(int size, std::vector<bool> & mask) 53 : mSize(size), mMask(mask), mAtomic(false) 54 {} 55 56 WriteMask(int size, std::vector<bool> &mask, 57 std::vector<std::pair<int, AtomicOpFunctor*> > atomicOp) 58 : mSize(size), mMask(mask), mAtomic(true), mAtomicOp(atomicOp) 59 {} 60 61 ~WriteMask() 62 {} 63 64 void 65 clear() 66 { 67 mMask = std::vector<bool>(mSize, false); 68 } 69 70 bool 71 test(int offset) 72 { 73 assert(offset < mSize); 74 return mMask[offset]; 75 } 76 77 void 78 setMask(int offset, int len) 79 { 80 assert(mSize >= (offset + len)); 81 for (int i = 0; i < len; i++) { 82 mMask[offset + i] = true; 83 } 84 } 85 void 86 fillMask() 87 { 88 for (int i = 0; i < mSize; i++) { 89 mMask[i] = true; 90 } 91 } 92 93 bool 94 getMask(int offset, int len) const 95 { 96 bool tmp = true; 97 assert(mSize >= (offset + len)); 98 for (int i = 0; i < len; i++) { 99 tmp = tmp & mMask.at(offset + i); 100 } 101 return tmp; 102 } 103 104 bool 105 isOverlap(const WriteMask &readMask) const 106 { 107 bool tmp = false; 108 assert(mSize == readMask.mSize); 109 for (int i = 0; i < mSize; i++) { 110 if (readMask.mMask.at(i)) { 111 tmp = tmp | mMask.at(i); 112 } 113 } 114 return tmp; 115 } 116 117 bool 118 cmpMask(const WriteMask &readMask) const 119 { 120 bool tmp = true; 121 assert(mSize == readMask.mSize); 122 for (int i = 0; i < mSize; i++) { 123 if (readMask.mMask.at(i)) { 124 tmp = tmp & mMask.at(i); 125 } 126 } 127 return tmp; 128 } 129 130 bool isEmpty() const 131 { 132 for (int i = 0; i < mSize; i++) { 133 if (mMask.at(i)) { 134 return false; 135 } 136 } 137 return true; 138 } 139 140 bool 141 isFull() const 142 { 143 for (int i = 0; i < mSize; i++) { 144 if (!mMask.at(i)) { 145 return false; 146 } 147 } 148 return true; 149 } 150 151 void 152 orMask(const WriteMask & writeMask) 153 { 154 assert(mSize == writeMask.mSize); 155 for (int i = 0; i < mSize; i++) { 156 mMask[i] = (mMask.at(i)) | (writeMask.mMask.at(i)); 157 } 158 159 if (writeMask.mAtomic) { 160 mAtomic = true; 161 mAtomicOp = writeMask.mAtomicOp; 162 } 163 } 164 165 void print(std::ostream& out) const; 166 167 void 168 performAtomic(uint8_t * p) const 169 { 170 for (int i = 0; i < mAtomicOp.size(); i++) { 171 int offset = mAtomicOp[i].first; 172 AtomicOpFunctor *fnctr = mAtomicOp[i].second; 173 (*fnctr)(&p[offset]); 174 } 175 } 176 177 void 178 performAtomic(DataBlock & blk) const 179 { 180 for (int i = 0; i < mAtomicOp.size(); i++) { 181 int offset = mAtomicOp[i].first; 182 uint8_t *p = blk.getDataMod(offset); 183 AtomicOpFunctor *fnctr = mAtomicOp[i].second; 184 (*fnctr)(p); 185 } 186 } 187 private: 188 int mSize; 189 std::vector<bool> mMask; 190 bool mAtomic; 191 std::vector<std::pair<int, AtomicOpFunctor*> > mAtomicOp; 192}; 193 194inline std::ostream& 195operator<<(std::ostream& out, const WriteMask& obj) 196{ 197 obj.print(out); 198 out << std::flush; 199 return out; 200} 201 202#endif // __MEM_RUBY_COMMON_WRITEMASK_HH__ 203