Change-Id: I8014d729611721dd15ee27a974acbab2744c5e82 Signed-off-by: Hoa Nguyen <hoanguyen@ucdavis.edu> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/33274 Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu> Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu> Tested-by: kokoro <noreply+kokoro@google.com>
242 lines
6.0 KiB
C++
242 lines
6.0 KiB
C++
/*
|
|
* Copyright (c) 2015-2017 Advanced Micro Devices, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met: redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer;
|
|
* redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution;
|
|
* neither the name of the copyright holders nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef __BASE_AMO_HH__
|
|
#define __BASE_AMO_HH__
|
|
|
|
#include <array>
|
|
#include <cstdint>
|
|
#include <functional>
|
|
#include <memory>
|
|
|
|
struct AtomicOpFunctor
|
|
{
|
|
/**
|
|
* @ingroup api_atomic_op
|
|
* @{
|
|
*/
|
|
virtual void operator()(uint8_t *p) = 0;
|
|
virtual AtomicOpFunctor* clone() = 0;
|
|
/** @} */ // end of api_atomic_op
|
|
virtual ~AtomicOpFunctor() {}
|
|
};
|
|
|
|
template <class T>
|
|
struct TypedAtomicOpFunctor : public AtomicOpFunctor
|
|
{
|
|
void operator()(uint8_t *p) { execute((T *)p); }
|
|
virtual AtomicOpFunctor* clone() = 0;
|
|
/**
|
|
* @ingroup api_atomic_op
|
|
*/
|
|
virtual void execute(T * p) = 0;
|
|
};
|
|
|
|
template<typename T>
|
|
class AtomicGeneric2Op : public TypedAtomicOpFunctor<T>
|
|
{
|
|
public:
|
|
AtomicGeneric2Op(T _a, std::function<void(T*,T)> _op)
|
|
: a(_a), op(_op)
|
|
{}
|
|
AtomicOpFunctor* clone() override
|
|
{
|
|
return new AtomicGeneric2Op<T>(*this);
|
|
}
|
|
void execute(T *b) override
|
|
{
|
|
op(b, a);
|
|
}
|
|
private:
|
|
T a;
|
|
std::function<void(T*,T)> op;
|
|
};
|
|
|
|
template<typename T>
|
|
class AtomicGeneric3Op : public TypedAtomicOpFunctor<T>
|
|
{
|
|
public:
|
|
AtomicGeneric3Op(T _a, T _c, std::function<void(T*, T, T)> _op)
|
|
: a(_a), c(_c), op(_op)
|
|
{}
|
|
AtomicOpFunctor* clone() override
|
|
{
|
|
return new AtomicGeneric3Op<T>(*this);
|
|
}
|
|
void execute(T *b) override
|
|
{
|
|
op(b, a, c);
|
|
}
|
|
private:
|
|
T a;
|
|
T c;
|
|
std::function<void(T*, T, T)> op;
|
|
};
|
|
|
|
template<typename T>
|
|
class AtomicGenericPair3Op : public TypedAtomicOpFunctor<T>
|
|
{
|
|
public:
|
|
AtomicGenericPair3Op(std::array<T, 2>& _a, std::array<T, 2> _c,
|
|
std::function<void(T*, std::array<T, 2>&, std::array<T, 2>)> _op)
|
|
: a(_a), c(_c), op(_op)
|
|
{}
|
|
AtomicOpFunctor* clone() override
|
|
{
|
|
return new AtomicGenericPair3Op<T>(*this);
|
|
}
|
|
void execute(T* b) override
|
|
{
|
|
op(b, a, c);
|
|
}
|
|
private:
|
|
std::array<T, 2> a;
|
|
std::array<T, 2> c;
|
|
std::function<void(T*, std::array<T, 2>&, std::array<T, 2>)> op;
|
|
};
|
|
|
|
template<typename T>
|
|
class AtomicOpAnd : public TypedAtomicOpFunctor<T>
|
|
{
|
|
public:
|
|
T a;
|
|
AtomicOpAnd(T _a) : a(_a) { }
|
|
void execute(T *b) { *b &= a; }
|
|
AtomicOpFunctor* clone () { return new AtomicOpAnd(a); }
|
|
};
|
|
|
|
template<typename T>
|
|
class AtomicOpOr : public TypedAtomicOpFunctor<T>
|
|
{
|
|
public:
|
|
T a;
|
|
AtomicOpOr(T _a) : a(_a) { }
|
|
void execute(T *b) { *b |= a; }
|
|
AtomicOpFunctor* clone () { return new AtomicOpOr(a); }
|
|
};
|
|
|
|
template<typename T>
|
|
class AtomicOpXor : public TypedAtomicOpFunctor<T>
|
|
{
|
|
public:
|
|
T a;
|
|
AtomicOpXor(T _a) : a(_a) {}
|
|
void execute(T *b) { *b ^= a; }
|
|
AtomicOpFunctor* clone () { return new AtomicOpXor(a); }
|
|
};
|
|
|
|
template<typename T>
|
|
class AtomicOpExch : public TypedAtomicOpFunctor<T>
|
|
{
|
|
public:
|
|
T a;
|
|
AtomicOpExch(T _a) : a(_a) { }
|
|
void execute(T *b) { *b = a; }
|
|
AtomicOpFunctor* clone () { return new AtomicOpExch(a); }
|
|
};
|
|
|
|
template<typename T>
|
|
class AtomicOpAdd : public TypedAtomicOpFunctor<T>
|
|
{
|
|
public:
|
|
T a;
|
|
AtomicOpAdd(T _a) : a(_a) { }
|
|
void execute(T *b) { *b += a; }
|
|
AtomicOpFunctor* clone () { return new AtomicOpAdd(a); }
|
|
};
|
|
|
|
template<typename T>
|
|
class AtomicOpSub : public TypedAtomicOpFunctor<T>
|
|
{
|
|
public:
|
|
T a;
|
|
AtomicOpSub(T _a) : a(_a) { }
|
|
void execute(T *b) { *b -= a; }
|
|
AtomicOpFunctor* clone () { return new AtomicOpSub(a); }
|
|
};
|
|
|
|
template<typename T>
|
|
class AtomicOpInc : public TypedAtomicOpFunctor<T>
|
|
{
|
|
public:
|
|
AtomicOpInc() { }
|
|
void execute(T *b) { *b += 1; }
|
|
AtomicOpFunctor* clone () { return new AtomicOpInc(); }
|
|
};
|
|
|
|
template<typename T>
|
|
class AtomicOpDec : public TypedAtomicOpFunctor<T>
|
|
{
|
|
public:
|
|
AtomicOpDec() {}
|
|
void execute(T *b) { *b -= 1; }
|
|
AtomicOpFunctor* clone () { return new AtomicOpDec(); }
|
|
};
|
|
|
|
template<typename T>
|
|
class AtomicOpMax : public TypedAtomicOpFunctor<T>
|
|
{
|
|
public:
|
|
T a;
|
|
AtomicOpMax(T _a) : a(_a) { }
|
|
|
|
void
|
|
execute(T *b)
|
|
{
|
|
if (a > *b)
|
|
*b = a;
|
|
}
|
|
AtomicOpFunctor* clone () { return new AtomicOpMax(a); }
|
|
};
|
|
|
|
template<typename T>
|
|
class AtomicOpMin : public TypedAtomicOpFunctor<T>
|
|
{
|
|
public:
|
|
T a;
|
|
AtomicOpMin(T _a) : a(_a) {}
|
|
|
|
void
|
|
execute(T *b)
|
|
{
|
|
if (a < *b)
|
|
*b = a;
|
|
}
|
|
AtomicOpFunctor* clone () { return new AtomicOpMin(a); }
|
|
};
|
|
|
|
/**
|
|
* @ingroup api_atomic_op
|
|
*/
|
|
typedef std::unique_ptr<AtomicOpFunctor> AtomicOpFunctorPtr;
|
|
|
|
#endif // __BASE_AMO_HH__
|