diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/poco/Foundation/include/Poco/AtomicCounter.h | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/poco/Foundation/include/Poco/AtomicCounter.h')
-rw-r--r-- | contrib/libs/poco/Foundation/include/Poco/AtomicCounter.h | 417 |
1 files changed, 417 insertions, 0 deletions
diff --git a/contrib/libs/poco/Foundation/include/Poco/AtomicCounter.h b/contrib/libs/poco/Foundation/include/Poco/AtomicCounter.h new file mode 100644 index 0000000000..4c7c7884f0 --- /dev/null +++ b/contrib/libs/poco/Foundation/include/Poco/AtomicCounter.h @@ -0,0 +1,417 @@ +// +// AtomicCounter.h +// +// Library: Foundation +// Package: Core +// Module: AtomicCounter +// +// Definition of the AtomicCounter class. +// +// Copyright (c) 2009, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef Foundation_AtomicCounter_INCLUDED +#define Foundation_AtomicCounter_INCLUDED + + +#include "Poco/Foundation.h" +#if POCO_OS == POCO_OS_WINDOWS_NT + #include "Poco/UnWindows.h" +#elif POCO_OS == POCO_OS_MAC_OS_X + #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 || __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 || __TV_OS_VERSION_MAX_ALLOWED >= 100000 || __WATCH_OS_VERSION_MAX_ALLOWED >= 30000 + #if __cplusplus >= 201103L + #ifndef POCO_HAVE_STD_ATOMICS + #define POCO_HAVE_STD_ATOMICS + #endif + #else + #include <libkern/OSAtomic.h> + #endif + #else + #include <libkern/OSAtomic.h> + #endif +#elif ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2) || __GNUC__ > 4) && (defined(__x86_64__) || defined(__i386__)) + #if !defined(POCO_HAVE_GCC_ATOMICS) && !defined(POCO_NO_GCC_ATOMICS) + #define POCO_HAVE_GCC_ATOMICS + #endif +#elif ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) || __GNUC__ > 4) + #if !defined(POCO_HAVE_GCC_ATOMICS) && !defined(POCO_NO_GCC_ATOMICS) + #define POCO_HAVE_GCC_ATOMICS + #endif +#endif // POCO_OS +#include "Poco/Mutex.h" +#ifdef POCO_HAVE_STD_ATOMICS +#include <atomic> +#endif + + +namespace Poco { + + +class Foundation_API AtomicCounter + /// This class implements a simple counter, which + /// provides atomic operations that are safe to + /// use in a multithreaded environment. + /// + /// Typical usage of AtomicCounter is for implementing + /// reference counting and similar things. + /// + /// On some platforms, the implementation of AtomicCounter + /// is based on atomic primitives specific to the platform + /// (such as InterlockedIncrement, etc. on Windows), and + /// thus very efficient. On platforms that do not support + /// atomic primitives, operations are guarded by a FastMutex. + /// + /// The following platforms currently have atomic + /// primitives: + /// - Windows + /// - Mac OS X + /// - GCC 4.1+ (Intel platforms only) +{ +public: + typedef int ValueType; /// The underlying integer type. + + AtomicCounter(); + /// Creates a new AtomicCounter and initializes it to zero. + + explicit AtomicCounter(ValueType initialValue); + /// Creates a new AtomicCounter and initializes it with + /// the given value. + + AtomicCounter(const AtomicCounter& counter); + /// Creates the counter by copying another one. + + ~AtomicCounter(); + /// Destroys the AtomicCounter. + + AtomicCounter& operator = (const AtomicCounter& counter); + /// Assigns the value of another AtomicCounter. + + AtomicCounter& operator = (ValueType value); + /// Assigns a value to the counter. + + operator ValueType () const; + /// Returns the value of the counter. + + ValueType value() const; + /// Returns the value of the counter. + + ValueType operator ++ (); // prefix + /// Increments the counter and returns the result. + + ValueType operator ++ (int); // postfix + /// Increments the counter and returns the previous value. + + ValueType operator -- (); // prefix + /// Decrements the counter and returns the result. + + ValueType operator -- (int); // postfix + /// Decrements the counter and returns the previous value. + + bool operator ! () const; + /// Returns true if the counter is zero, false otherwise. + +private: +#if defined(POCO_HAVE_STD_ATOMICS) + typedef std::atomic<int> ImplType; +#elif POCO_OS == POCO_OS_WINDOWS_NT + typedef volatile LONG ImplType; +#elif POCO_OS == POCO_OS_MAC_OS_X + typedef int32_t ImplType; +#elif defined(POCO_HAVE_GCC_ATOMICS) + typedef int ImplType; +#else // generic implementation based on FastMutex + struct ImplType + { + mutable FastMutex mutex; + volatile int value; + }; +#endif // POCO_OS + + ImplType _counter; +}; + + +// +// inlines +// + + +#if defined(POCO_HAVE_STD_ATOMICS) +// +// C++11 atomics +// +inline AtomicCounter::operator AtomicCounter::ValueType () const +{ + return _counter.load(); +} + + +inline AtomicCounter::ValueType AtomicCounter::value() const +{ + return _counter.load(); +} + + +inline AtomicCounter::ValueType AtomicCounter::operator ++ () // prefix +{ + return ++_counter; +} + + +inline AtomicCounter::ValueType AtomicCounter::operator ++ (int) // postfix +{ + return _counter++; +} + + +inline AtomicCounter::ValueType AtomicCounter::operator -- () // prefix +{ + return --_counter; +} + + +inline AtomicCounter::ValueType AtomicCounter::operator -- (int) // postfix +{ + return _counter--; +} + + +inline bool AtomicCounter::operator ! () const +{ + return _counter.load() == 0; +} + + +#elif POCO_OS == POCO_OS_WINDOWS_NT +// +// Windows +// +inline AtomicCounter::operator AtomicCounter::ValueType () const +{ + return _counter; +} + + +inline AtomicCounter::ValueType AtomicCounter::value() const +{ + return _counter; +} + + +inline AtomicCounter::ValueType AtomicCounter::operator ++ () // prefix +{ + return InterlockedIncrement(&_counter); +} + + +inline AtomicCounter::ValueType AtomicCounter::operator ++ (int) // postfix +{ + ValueType result = InterlockedIncrement(&_counter); + return --result; +} + + +inline AtomicCounter::ValueType AtomicCounter::operator -- () // prefix +{ + return InterlockedDecrement(&_counter); +} + + +inline AtomicCounter::ValueType AtomicCounter::operator -- (int) // postfix +{ + ValueType result = InterlockedDecrement(&_counter); + return ++result; +} + + +inline bool AtomicCounter::operator ! () const +{ + return _counter == 0; +} + + +#elif POCO_OS == POCO_OS_MAC_OS_X +// +// Mac OS X +// +inline AtomicCounter::operator AtomicCounter::ValueType () const +{ + return _counter; +} + + +inline AtomicCounter::ValueType AtomicCounter::value() const +{ + return _counter; +} + + +inline AtomicCounter::ValueType AtomicCounter::operator ++ () // prefix +{ + return OSAtomicIncrement32(&_counter); +} + + +inline AtomicCounter::ValueType AtomicCounter::operator ++ (int) // postfix +{ + ValueType result = OSAtomicIncrement32(&_counter); + return --result; +} + + +inline AtomicCounter::ValueType AtomicCounter::operator -- () // prefix +{ + return OSAtomicDecrement32(&_counter); +} + + +inline AtomicCounter::ValueType AtomicCounter::operator -- (int) // postfix +{ + ValueType result = OSAtomicDecrement32(&_counter); + return ++result; +} + + +inline bool AtomicCounter::operator ! () const +{ + return _counter == 0; +} + +#elif defined(POCO_HAVE_GCC_ATOMICS) +// +// GCC 4.1+ atomic builtins. +// +inline AtomicCounter::operator AtomicCounter::ValueType () const +{ + return _counter; +} + + +inline AtomicCounter::ValueType AtomicCounter::value() const +{ + return _counter; +} + + +inline AtomicCounter::ValueType AtomicCounter::operator ++ () // prefix +{ + return __sync_add_and_fetch(&_counter, 1); +} + + +inline AtomicCounter::ValueType AtomicCounter::operator ++ (int) // postfix +{ + return __sync_fetch_and_add(&_counter, 1); +} + + +inline AtomicCounter::ValueType AtomicCounter::operator -- () // prefix +{ + return __sync_sub_and_fetch(&_counter, 1); +} + + +inline AtomicCounter::ValueType AtomicCounter::operator -- (int) // postfix +{ + return __sync_fetch_and_sub(&_counter, 1); +} + + +inline bool AtomicCounter::operator ! () const +{ + return _counter == 0; +} + + +#else +// +// Generic implementation based on FastMutex +// +inline AtomicCounter::operator AtomicCounter::ValueType () const +{ + ValueType result; + { + FastMutex::ScopedLock lock(_counter.mutex); + result = _counter.value; + } + return result; +} + + +inline AtomicCounter::ValueType AtomicCounter::value() const +{ + ValueType result; + { + FastMutex::ScopedLock lock(_counter.mutex); + result = _counter.value; + } + return result; +} + + +inline AtomicCounter::ValueType AtomicCounter::operator ++ () // prefix +{ + ValueType result; + { + FastMutex::ScopedLock lock(_counter.mutex); + result = ++_counter.value; + } + return result; +} + + +inline AtomicCounter::ValueType AtomicCounter::operator ++ (int) // postfix +{ + ValueType result; + { + FastMutex::ScopedLock lock(_counter.mutex); + result = _counter.value++; + } + return result; +} + + +inline AtomicCounter::ValueType AtomicCounter::operator -- () // prefix +{ + ValueType result; + { + FastMutex::ScopedLock lock(_counter.mutex); + result = --_counter.value; + } + return result; +} + + +inline AtomicCounter::ValueType AtomicCounter::operator -- (int) // postfix +{ + ValueType result; + { + FastMutex::ScopedLock lock(_counter.mutex); + result = _counter.value--; + } + return result; +} + + +inline bool AtomicCounter::operator ! () const +{ + bool result; + { + FastMutex::ScopedLock lock(_counter.mutex); + result = _counter.value == 0; + } + return result; +} + + +#endif // POCO_OS + + +} // namespace Poco + + +#endif // Foundation_AtomicCounter_INCLUDED |