sim,base: make checkpointMapIn warn if an unknown key is found
[gem5.git] / src / base / amo.hh
1 /*
2 * Copyright (c) 2015-2017 Advanced Micro Devices, Inc.
3 * All rights reserved.
4 *
5 * Copyright (c) 2003-2005 The Regents of The University of Michigan
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met: redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer;
12 * redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution;
15 * neither the name of the copyright holders nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #ifndef __BASE_AMO_HH__
33 #define __BASE_AMO_HH__
34
35 #include <array>
36 #include <cstdint>
37 #include <functional>
38 #include <memory>
39
40 struct AtomicOpFunctor
41 {
42 /**
43 * @ingroup api_atomic_op
44 * @{
45 */
46 virtual void operator()(uint8_t *p) = 0;
47 virtual AtomicOpFunctor* clone() = 0;
48 /** @} */ // end of api_atomic_op
49 virtual ~AtomicOpFunctor() {}
50 };
51
52 template <class T>
53 struct TypedAtomicOpFunctor : public AtomicOpFunctor
54 {
55 void operator()(uint8_t *p) { execute((T *)p); }
56 virtual AtomicOpFunctor* clone() = 0;
57 /**
58 * @ingroup api_atomic_op
59 */
60 virtual void execute(T * p) = 0;
61 };
62
63 template<typename T>
64 class AtomicGeneric2Op : public TypedAtomicOpFunctor<T>
65 {
66 public:
67 AtomicGeneric2Op(T _a, std::function<void(T*,T)> _op)
68 : a(_a), op(_op)
69 {}
70 AtomicOpFunctor* clone() override
71 {
72 return new AtomicGeneric2Op<T>(*this);
73 }
74 void execute(T *b) override
75 {
76 op(b, a);
77 }
78 private:
79 T a;
80 std::function<void(T*,T)> op;
81 };
82
83 template<typename T>
84 class AtomicGeneric3Op : public TypedAtomicOpFunctor<T>
85 {
86 public:
87 AtomicGeneric3Op(T _a, T _c, std::function<void(T*, T, T)> _op)
88 : a(_a), c(_c), op(_op)
89 {}
90 AtomicOpFunctor* clone() override
91 {
92 return new AtomicGeneric3Op<T>(*this);
93 }
94 void execute(T *b) override
95 {
96 op(b, a, c);
97 }
98 private:
99 T a;
100 T c;
101 std::function<void(T*, T, T)> op;
102 };
103
104 template<typename T>
105 class AtomicGenericPair3Op : public TypedAtomicOpFunctor<T>
106 {
107 public:
108 AtomicGenericPair3Op(std::array<T, 2>& _a, std::array<T, 2> _c,
109 std::function<void(T*, std::array<T, 2>&, std::array<T, 2>)> _op)
110 : a(_a), c(_c), op(_op)
111 {}
112 AtomicOpFunctor* clone() override
113 {
114 return new AtomicGenericPair3Op<T>(*this);
115 }
116 void execute(T* b) override
117 {
118 op(b, a, c);
119 }
120 private:
121 std::array<T, 2> a;
122 std::array<T, 2> c;
123 std::function<void(T*, std::array<T, 2>&, std::array<T, 2>)> op;
124 };
125
126 template<typename T>
127 class AtomicOpAnd : public TypedAtomicOpFunctor<T>
128 {
129 public:
130 T a;
131 AtomicOpAnd(T _a) : a(_a) { }
132 void execute(T *b) { *b &= a; }
133 AtomicOpFunctor* clone () { return new AtomicOpAnd(a); }
134 };
135
136 template<typename T>
137 class AtomicOpOr : public TypedAtomicOpFunctor<T>
138 {
139 public:
140 T a;
141 AtomicOpOr(T _a) : a(_a) { }
142 void execute(T *b) { *b |= a; }
143 AtomicOpFunctor* clone () { return new AtomicOpOr(a); }
144 };
145
146 template<typename T>
147 class AtomicOpXor : public TypedAtomicOpFunctor<T>
148 {
149 public:
150 T a;
151 AtomicOpXor(T _a) : a(_a) {}
152 void execute(T *b) { *b ^= a; }
153 AtomicOpFunctor* clone () { return new AtomicOpXor(a); }
154 };
155
156 template<typename T>
157 class AtomicOpExch : public TypedAtomicOpFunctor<T>
158 {
159 public:
160 T a;
161 AtomicOpExch(T _a) : a(_a) { }
162 void execute(T *b) { *b = a; }
163 AtomicOpFunctor* clone () { return new AtomicOpExch(a); }
164 };
165
166 template<typename T>
167 class AtomicOpAdd : public TypedAtomicOpFunctor<T>
168 {
169 public:
170 T a;
171 AtomicOpAdd(T _a) : a(_a) { }
172 void execute(T *b) { *b += a; }
173 AtomicOpFunctor* clone () { return new AtomicOpAdd(a); }
174 };
175
176 template<typename T>
177 class AtomicOpSub : public TypedAtomicOpFunctor<T>
178 {
179 public:
180 T a;
181 AtomicOpSub(T _a) : a(_a) { }
182 void execute(T *b) { *b -= a; }
183 AtomicOpFunctor* clone () { return new AtomicOpSub(a); }
184 };
185
186 template<typename T>
187 class AtomicOpInc : public TypedAtomicOpFunctor<T>
188 {
189 public:
190 AtomicOpInc() { }
191 void execute(T *b) { *b += 1; }
192 AtomicOpFunctor* clone () { return new AtomicOpInc(); }
193 };
194
195 template<typename T>
196 class AtomicOpDec : public TypedAtomicOpFunctor<T>
197 {
198 public:
199 AtomicOpDec() {}
200 void execute(T *b) { *b -= 1; }
201 AtomicOpFunctor* clone () { return new AtomicOpDec(); }
202 };
203
204 template<typename T>
205 class AtomicOpMax : public TypedAtomicOpFunctor<T>
206 {
207 public:
208 T a;
209 AtomicOpMax(T _a) : a(_a) { }
210
211 void
212 execute(T *b)
213 {
214 if (a > *b)
215 *b = a;
216 }
217 AtomicOpFunctor* clone () { return new AtomicOpMax(a); }
218 };
219
220 template<typename T>
221 class AtomicOpMin : public TypedAtomicOpFunctor<T>
222 {
223 public:
224 T a;
225 AtomicOpMin(T _a) : a(_a) {}
226
227 void
228 execute(T *b)
229 {
230 if (a < *b)
231 *b = a;
232 }
233 AtomicOpFunctor* clone () { return new AtomicOpMin(a); }
234 };
235
236 /**
237 * @ingroup api_atomic_op
238 */
239 typedef std::unique_ptr<AtomicOpFunctor> AtomicOpFunctorPtr;
240
241 #endif // __BASE_AMO_HH__