diff --git a/openmp/libomptarget/include/Utilities.h b/openmp/libomptarget/include/Utilities.h --- a/openmp/libomptarget/include/Utilities.h +++ b/openmp/libomptarget/include/Utilities.h @@ -19,6 +19,7 @@ #include "Debug.h" #include +#include #include #include #include @@ -129,6 +130,36 @@ using StringEnvar = Envar; using BoolEnvar = Envar; +/// Utility class for thread-safe reference counting. Any class that needs +/// objects' reference counting can inherit from this entity or have it as a +/// class data member. +template +struct RefCountTy { + /// Create a refcount object initialized to zero. + RefCountTy() : Refs(0) {} + + ~RefCountTy() { assert(Refs == 0 && "Destroying with non-zero refcount"); } + + /// Increase the reference count atomically. + void increase() { Refs.fetch_add(1, MemoryOrder); } + + /// Decrease the reference count and return whether it became zero. Decreasing + /// the counter in more units than it was previously increased results in + /// undefined behavior. + bool decrease() { + Ty Prev = Refs.fetch_sub(1, MemoryOrder); + assert(Prev > 0 && "Invalid refcount"); + return (Prev == 1); + } + + Ty get() const { return Refs.load(MemoryOrder); } + +private: + /// The atomic reference counter. + std::atomic Refs; +}; + template <> inline bool StringParser::parse(const char *ValueStr, bool &Result) { std::string Value(ValueStr);