Add atomics support

pull/174/head
Jeffrey Walton 2016-05-02 23:38:10 -04:00
parent 4d7cb70ea8
commit 8bb9197adc
4 changed files with 61 additions and 1 deletions

View File

@ -664,6 +664,19 @@ NAMESPACE_END
// C++11 or C++14 is available
#if defined(CRYPTOPP_CXX11)
// atomics: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.1/3.2; and Intel 13.0.
#if (CRYPTOPP_MSC_VERSION >= 1700)
# define CRYPTOPP_CXX11_ATOMICS 1
#elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)
# define CRYPTOPP_CXX11_ATOMICS 1
#elif defined(__clang__)
# if __has_feature(cxx_atomic)
# define CRYPTOPP_CXX11_ATOMICS 1
# endif
#elif (CRYPTOPP_GCC_VERSION >= 40400)
# define CRYPTOPP_CXX11_ATOMICS 1
#endif // atomics
// alignof/alignas: MS at VS2013 (19.00); GCC at 4.8; Clang at 3.3; and Intel 15.0.
#if (CRYPTOPP_MSC_VERSION >= 1900)
# define CRYPTOPP_CXX11_ALIGNAS 1

View File

@ -664,6 +664,19 @@ NAMESPACE_END
// C++11 or C++14 is available
#if defined(CRYPTOPP_CXX11)
// atomics: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.1/3.2; and Intel 13.0.
#if (CRYPTOPP_MSC_VERSION >= 1700)
# define CRYPTOPP_CXX11_ATOMICS 1
#elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)
# define CRYPTOPP_CXX11_ATOMICS 1
#elif defined(__clang__)
# if __has_feature(cxx_atomic)
# define CRYPTOPP_CXX11_ATOMICS 1
# endif
#elif (CRYPTOPP_GCC_VERSION >= 40400)
# define CRYPTOPP_CXX11_ATOMICS 1
#endif // atomics
// alignof/alignas: MS at VS2013 (19.00); GCC at 4.8; Clang at 3.3; and Intel 15.0.
#if (CRYPTOPP_MSC_VERSION >= 1900)
# define CRYPTOPP_CXX11_ALIGNAS 1

32
misc.h
View File

@ -218,7 +218,9 @@ struct NewObject
//! <tt>_ReadWriteBarrier()</tt> or <tt>__asm__("" ::: "memory")</tt>.
#define MEMORY_BARRIER ...
#else
#if (_MSC_VER >= 1400)
#if defined(CRYPTOPP_CXX11_ATOMICS)
# define MEMORY_BARRIER() std::atomic_thread_fence(std::memory_order_acq_rel)
#elif (_MSC_VER >= 1400)
# pragma intrinsic(_ReadWriteBarrier)
# define MEMORY_BARRIER() _ReadWriteBarrier()
#elif defined(__INTEL_COMPILER)
@ -254,6 +256,33 @@ private:
//! \brief Return a reference to the inner Singleton object
//! \details Ref() is used to create the object using the object factory. The
//! object is only created once with the limitations discussed in the class documentation.
#if defined(CRYPTOPP_CXX11_ATOMICS)
template <class T, class F, int instance>
const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
{
static volatile simple_ptr<T> s_pObject;
T *p = s_pObject.m_p;
std::atomic_thread_fence(std::memory_order_acquire);
if (p)
return *p;
T *newObject = m_objectFactory();
p = s_pObject.m_p;
std::atomic_thread_fence(std::memory_order_acquire);
if (p)
{
delete newObject;
return *p;
}
s_pObject.m_p = newObject;
std::atomic_thread_fence(std::memory_order_release);
return *newObject;
}
#else
template <class T, class F, int instance>
const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
{
@ -279,6 +308,7 @@ const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
return *newObject;
}
#endif
// ************** misc functions ***************

View File

@ -32,6 +32,10 @@ namespace std {
#include <iterator>
#endif
#if defined(CRYPTOPP_CXX11_ATOMICS)
#include <atomic>
#endif
#include <cstdlib>
#include <cstddef>
#include <cstring>