2 * Copyright (c) 2015-2017 Advanced Micro Devices, Inc.
5 * Copyright (c) 2003-2005 The Regents of The University of Michigan
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.
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.
32 #ifndef __BASE_AMO_HH__
33 #define __BASE_AMO_HH__
40 struct AtomicOpFunctor
43 * @ingroup api_atomic_op
46 virtual void operator()(uint8_t *p) = 0;
47 virtual AtomicOpFunctor* clone() = 0;
48 /** @} */ // end of api_atomic_op
49 virtual ~AtomicOpFunctor() {}
53 struct TypedAtomicOpFunctor : public AtomicOpFunctor
55 void operator()(uint8_t *p) { execute((T *)p); }
56 virtual AtomicOpFunctor* clone() = 0;
58 * @ingroup api_atomic_op
60 virtual void execute(T * p) = 0;
64 class AtomicGeneric2Op : public TypedAtomicOpFunctor<T>
67 AtomicGeneric2Op(T _a, std::function<void(T*,T)> _op)
70 AtomicOpFunctor* clone() override
72 return new AtomicGeneric2Op<T>(*this);
74 void execute(T *b) override
80 std::function<void(T*,T)> op;
84 class AtomicGeneric3Op : public TypedAtomicOpFunctor<T>
87 AtomicGeneric3Op(T _a, T _c, std::function<void(T*, T, T)> _op)
88 : a(_a), c(_c), op(_op)
90 AtomicOpFunctor* clone() override
92 return new AtomicGeneric3Op<T>(*this);
94 void execute(T *b) override
101 std::function<void(T*, T, T)> op;
105 class AtomicGenericPair3Op : public TypedAtomicOpFunctor<T>
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)
112 AtomicOpFunctor* clone() override
114 return new AtomicGenericPair3Op<T>(*this);
116 void execute(T* b) override
123 std::function<void(T*, std::array<T, 2>&, std::array<T, 2>)> op;
127 class AtomicOpAnd : public TypedAtomicOpFunctor<T>
131 AtomicOpAnd(T _a) : a(_a) { }
132 void execute(T *b) { *b &= a; }
133 AtomicOpFunctor* clone () { return new AtomicOpAnd(a); }
137 class AtomicOpOr : public TypedAtomicOpFunctor<T>
141 AtomicOpOr(T _a) : a(_a) { }
142 void execute(T *b) { *b |= a; }
143 AtomicOpFunctor* clone () { return new AtomicOpOr(a); }
147 class AtomicOpXor : public TypedAtomicOpFunctor<T>
151 AtomicOpXor(T _a) : a(_a) {}
152 void execute(T *b) { *b ^= a; }
153 AtomicOpFunctor* clone () { return new AtomicOpXor(a); }
157 class AtomicOpExch : public TypedAtomicOpFunctor<T>
161 AtomicOpExch(T _a) : a(_a) { }
162 void execute(T *b) { *b = a; }
163 AtomicOpFunctor* clone () { return new AtomicOpExch(a); }
167 class AtomicOpAdd : public TypedAtomicOpFunctor<T>
171 AtomicOpAdd(T _a) : a(_a) { }
172 void execute(T *b) { *b += a; }
173 AtomicOpFunctor* clone () { return new AtomicOpAdd(a); }
177 class AtomicOpSub : public TypedAtomicOpFunctor<T>
181 AtomicOpSub(T _a) : a(_a) { }
182 void execute(T *b) { *b -= a; }
183 AtomicOpFunctor* clone () { return new AtomicOpSub(a); }
187 class AtomicOpInc : public TypedAtomicOpFunctor<T>
191 void execute(T *b) { *b += 1; }
192 AtomicOpFunctor* clone () { return new AtomicOpInc(); }
196 class AtomicOpDec : public TypedAtomicOpFunctor<T>
200 void execute(T *b) { *b -= 1; }
201 AtomicOpFunctor* clone () { return new AtomicOpDec(); }
205 class AtomicOpMax : public TypedAtomicOpFunctor<T>
209 AtomicOpMax(T _a) : a(_a) { }
217 AtomicOpFunctor* clone () { return new AtomicOpMax(a); }
221 class AtomicOpMin : public TypedAtomicOpFunctor<T>
225 AtomicOpMin(T _a) : a(_a) {}
233 AtomicOpFunctor* clone () { return new AtomicOpMin(a); }
237 * @ingroup api_atomic_op
239 typedef std::unique_ptr<AtomicOpFunctor> AtomicOpFunctorPtr;
241 #endif // __BASE_AMO_HH__