Add atomics support
parent
4d7cb70ea8
commit
8bb9197adc
13
config.h
13
config.h
|
|
@ -664,6 +664,19 @@ NAMESPACE_END
|
||||||
// C++11 or C++14 is available
|
// C++11 or C++14 is available
|
||||||
#if defined(CRYPTOPP_CXX11)
|
#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.
|
// alignof/alignas: MS at VS2013 (19.00); GCC at 4.8; Clang at 3.3; and Intel 15.0.
|
||||||
#if (CRYPTOPP_MSC_VERSION >= 1900)
|
#if (CRYPTOPP_MSC_VERSION >= 1900)
|
||||||
# define CRYPTOPP_CXX11_ALIGNAS 1
|
# define CRYPTOPP_CXX11_ALIGNAS 1
|
||||||
|
|
|
||||||
|
|
@ -664,6 +664,19 @@ NAMESPACE_END
|
||||||
// C++11 or C++14 is available
|
// C++11 or C++14 is available
|
||||||
#if defined(CRYPTOPP_CXX11)
|
#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.
|
// alignof/alignas: MS at VS2013 (19.00); GCC at 4.8; Clang at 3.3; and Intel 15.0.
|
||||||
#if (CRYPTOPP_MSC_VERSION >= 1900)
|
#if (CRYPTOPP_MSC_VERSION >= 1900)
|
||||||
# define CRYPTOPP_CXX11_ALIGNAS 1
|
# define CRYPTOPP_CXX11_ALIGNAS 1
|
||||||
|
|
|
||||||
32
misc.h
32
misc.h
|
|
@ -218,7 +218,9 @@ struct NewObject
|
||||||
//! <tt>_ReadWriteBarrier()</tt> or <tt>__asm__("" ::: "memory")</tt>.
|
//! <tt>_ReadWriteBarrier()</tt> or <tt>__asm__("" ::: "memory")</tt>.
|
||||||
#define MEMORY_BARRIER ...
|
#define MEMORY_BARRIER ...
|
||||||
#else
|
#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)
|
# pragma intrinsic(_ReadWriteBarrier)
|
||||||
# define MEMORY_BARRIER() _ReadWriteBarrier()
|
# define MEMORY_BARRIER() _ReadWriteBarrier()
|
||||||
#elif defined(__INTEL_COMPILER)
|
#elif defined(__INTEL_COMPILER)
|
||||||
|
|
@ -254,6 +256,33 @@ private:
|
||||||
//! \brief Return a reference to the inner Singleton object
|
//! \brief Return a reference to the inner Singleton object
|
||||||
//! \details Ref() is used to create the object using the object factory. The
|
//! \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.
|
//! 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>
|
template <class T, class F, int instance>
|
||||||
const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
|
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;
|
return *newObject;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// ************** misc functions ***************
|
// ************** misc functions ***************
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue