+class AtomicPointer
+{
+public:
+ /** Create a pointer.
+
+ @param initialValue An optional starting value (default is null).
+ */
+ explicit AtomicPointer (P* const initialValue = nullptr) noexcept
+:
+ m_value (initialValue)
+ {
+ }
+
+ /** Retrieve the pointer value */
+ inline P* get () const noexcept
+ {
+ return m_value.get ();
+ }
+
+ /** Obtain a pointer to P through type conversion.
+
+ The caller must synchronize access to P.
+
+ @return A pointer to P.
+ */
+ inline operator P* () const noexcept
+ {
+ return get ();
+ }
+
+ /** Dereference operator
+
+ The caller must synchronize access to P.
+
+ @return A reference to P.
+ */
+ inline P& operator* () const noexcept
+ {
+ return &get ();
+ }
+
+ /** Member selection
+
+ The caller must synchronize access to P.
+
+ @return A pointer to P.
+ */
+ inline P* operator-> () const noexcept
+ {
+ return get ();
+ }
+
+ inline void set (P* p)
+ {
+ m_value.set (p);
+ }
+
+ /** Atomically assign a new pointer
+
+ @param newValue The new value to assign.
+ */
+ inline void operator= (P* newValue) noexcept
+ {
+ set (newValue);
+ }
+
+ /** Atomically assign a new pointer and return the old value.
+
+ @param newValue The new value to assign.
+
+ @return The previous value.
+ */
+ inline P* exchange (P* newValue)
+ {
+ return m_value.exchange (newValue);
+ }
+
+ /** Conditionally perform an atomic assignment.
+
+ The current value is compared with oldValue and atomically
+ set to newValue if the comparison is equal.
+
+ The caller is responsible for handling the ABA problem.
+
+ @param newValue The new value to assign.
+
+ @param oldValue The matching old value.
+
+ @return true if the assignment was performed.
+ */
+ inline bool compareAndSet (P* newValue, P* oldValue)
+ {
+ return m_value.compareAndSetBool (newValue, oldValue);
+ }
+
+private:
+ Atomic m_value;
+};
+
+#endif
diff --git a/modules/beast_basics/memory/beast_AtomicState.h b/modules/beast_basics/memory/beast_AtomicState.h
new file mode 100644
index 00000000..3699f0d1
--- /dev/null
+++ b/modules/beast_basics/memory/beast_AtomicState.h
@@ -0,0 +1,114 @@
+/*============================================================================*/
+/*
+ VFLib: https://github.com/vinniefalco/VFLib
+
+ Copyright (C) 2008 by Vinnie Falco
+
+ This library contains portions of other open source products covered by
+ separate licenses. Please see the corresponding source files for specific
+ terms.
+
+ VFLib is provided under the terms of The MIT License (MIT):
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ IN THE SOFTWARE.
+*/
+/*============================================================================*/
+
+#ifndef BEAST_ATOMICSTATE_BEASTHEADER
+#define BEAST_ATOMICSTATE_BEASTHEADER
+
+/*============================================================================*/
+/**
+ A thread safe state variable.
+
+ This provides a simplified interface to an integer used to control atomic
+ state transitions. A state is distinguished by a single integer value.
+
+ @ingroup beast_core
+*/
+class AtomicState
+{
+public:
+ /** Create a new state with an optional starting value.
+
+ @param initialState The initial state.
+ */
+
+
+ explicit AtomicState (const int initialState = 0) noexcept
+:
+ m_value (initialState)
+ {
+ }
+
+ /** Retrieve the current state.
+
+ This converts the object to an integer reflecting the current state.
+
+ Note that other threads may change the value immediately after this
+ function returns. The caller is responsible for synchronizing.
+
+ @return The state at the time of the call.
+ */
+ inline operator int () const
+ {
+ return m_value.get ();
+ }
+
+ /** Attempt a state transition.
+
+ The current state is compared to `from`, and if the comparison is
+ successful the state becomes `to`. The entire operation is atomic.
+
+ @param from The current state, for comparison.
+
+ @param to The desired new state.
+
+ @return true if the state transition succeeded.
+ */
+ inline bool tryChangeState (const int from, const int to) noexcept
+ {
+ return m_value.compareAndSetBool (to, from);
+ }
+
+ /** Perform a state transition.
+
+ This attempts to change the state and generates a diagnostic on
+ failure. This routine can be used instead of tryChangeState()
+ when program logic requires that the state change must succeed.
+
+ @param from The required current state.
+
+ @param to The new state.
+ */
+ inline void changeState (const int from, const int to) noexcept
+ {
+#if BEAST_DEBUG
+ const bool success = tryChangeState (from, to);
+ bassert (success);
+#else
+ tryChangeState (from, to);
+#endif
+ }
+
+private:
+ Atomic m_value;
+};
+
+#endif
diff --git a/modules/beast_basics/memory/beast_CacheLine.h b/modules/beast_basics/memory/beast_CacheLine.h
new file mode 100644
index 00000000..096af217
--- /dev/null
+++ b/modules/beast_basics/memory/beast_CacheLine.h
@@ -0,0 +1,491 @@
+/*============================================================================*/
+/*
+ VFLib: https://github.com/vinniefalco/VFLib
+
+ Copyright (C) 2008 by Vinnie Falco
+
+ This library contains portions of other open source products covered by
+ separate licenses. Please see the corresponding source files for specific
+ terms.
+
+ VFLib is provided under the terms of The MIT License (MIT):
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ IN THE SOFTWARE.
+*/
+/*============================================================================*/
+
+#ifndef BEAST_CACHELINE_BEASTHEADER
+#define BEAST_CACHELINE_BEASTHEADER
+
+#include "beast_MemoryAlignment.h"
+
+// Allows turning off of all padding,
+// e.g. for memory-constrained systems or testing.
+//
+#define GLOBAL_PADDING_ENABLED 0
+
+namespace CacheLine
+{
+
+#if GLOBAL_PADDING_ENABLED
+
+// Pads an object so that it starts on a cache line boundary.
+//
+template
+class Aligned
+{
+public:
+ ~Aligned ()
+ {
+ ptr ()->~T ();
+ }
+
+ Aligned ()
+ {
+ new (ptr ()) T;
+ }
+
+ template
+ explicit Aligned (const T1& t1)
+ {
+ new (ptr ()) T (t1);
+ }
+
+ template
+ Aligned (const T1& t1, const T2& t2)
+ {
+ new (ptr ()) T (t1, t2);
+ }
+
+ template
+ Aligned (const T1& t1, const T2& t2, const T3& t3)
+ {
+ new (ptr ()) T (t1, t2, t3);
+ }
+
+ template
+ Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4)
+ {
+ new (ptr ()) T (t1, t2, t3, t4);
+ }
+
+ template
+ Aligned (const T1& t1, const T2& t2, const T3& t3,
+ const T4& t4, const T5& t5)
+ {
+ new (ptr ()) T (t1, t2, t3, t4, t5);
+ }
+
+ template
+ Aligned (const T1& t1, const T2& t2, const T3& t3,
+ const T4& t4, const T5& t5, const T6& t6)
+ {
+ new (ptr ()) T (t1, t2, t3, t4, t5, t6);
+ }
+
+ template < class T1, class T2, class T3, class T4,
+ class T5, class T6, class T7 >
+ Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
+ const T5& t5, const T6& t6, const T7& t7)
+ {
+ new (ptr ()) T (t1, t2, t3, t4, t5, t6, t7);
+ }
+
+ template < class T1, class T2, class T3, class T4,
+ class T5, class T6, class T7, class T8 >
+ Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
+ const T5& t5, const T6& t6, const T7& t7, const T8& t8)
+ {
+ new (ptr ()) T (t1, t2, t3, t4, t5, t6, t7, t8);
+ }
+
+ void operator= (T const& other)
+ {
+ *ptr () = other;
+ }
+
+ inline T& operator* () noexcept { return *ptr (); }
+ inline T* operator-> () noexcept { return ptr (); }
+ inline operator T& () noexcept { return *ptr (); }
+ inline operator T* () noexcept { return ptr (); }
+
+ inline const T& operator* () const noexcept
+ {
+ return *ptr ();
+ }
+ inline const T* operator-> () const noexcept
+ {
+ return ptr ();
+ }
+ inline operator const T& () const noexcept
+ {
+ return *ptr ();
+ }
+ inline operator const T* () const noexcept
+ {
+ return ptr ();
+ }
+
+private:
+ inline T* ptr () noexcept
+ {
+ return (T*) ((uintptr_t (m_storage) + Memory::cacheLineAlignMask)
+ & ~Memory::cacheLineAlignMask);
+ /*
+ return reinterpret_cast (Memory::pointerAdjustedForAlignment (
+ m_storage, Memory::cacheLineBytes));
+ */
+ }
+
+ char m_storage [ (sizeof (T) + Memory::cacheLineAlignMask)
+ & ~Memory::cacheLineAlignMask];
+};
+
+// Holds an object padded it to completely fill a CPU cache line.
+// The caller must ensure that this object starts at the beginning
+// of a cache line.
+//
+template
+class Padded
+{
+public:
+ Padded ()
+ { }
+
+ template
+ explicit Padded (const T1& t1)
+ : m_t (t1) { }
+
+ template
+ Padded (const T1& t1, const T2& t2)
+ : m_t (t1, t2) { }
+
+ template
+ Padded (const T1& t1, const T2& t2, const T3& t3)
+ : m_t (t1, t2, t3) { }
+
+ template
+ Padded (const T1& t1, const T2& t2, const T3& t3, const T4& t4)
+ : m_t (t1, t2, t3, t4) { }
+
+ template
+ Padded (const T1& t1, const T2& t2, const T3& t3,
+ const T4& t4, const T5& t5)
+ : m_t (t1, t2, t3, t4, t5) { }
+
+ template
+ Padded (const T1& t1, const T2& t2, const T3& t3,
+ const T4& t4, const T5& t5, const T6& t6)
+ : m_t (t1, t2, t3, t4, t5, t6) { }
+
+ template < class T1, class T2, class T3, class T4,
+ class T5, class T6, class T7 >
+ Padded (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
+ const T5& t5, const T6& t6, const T7& t7)
+ : m_t (t1, t2, t3, t4, t5, t6, t7) { }
+
+ template < class T1, class T2, class T3, class T4,
+ class T5, class T6, class T7, class T8 >
+ Padded (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
+ const T5& t5, const T6& t6, const T7& t7, const T8& t8)
+ : m_t (t1, t2, t3, t4, t5, t6, t7, t8) { }
+
+ void operator= (const T& other)
+ {
+ m_t = other;
+ }
+
+ T& operator* () noexcept { return m_t; }
+ T* operator-> () noexcept { return &m_t; }
+ operator T& () noexcept { return m_t; }
+ operator T* () noexcept { return &m_t; }
+
+ const T& operator* () const noexcept
+ {
+ return m_t;
+ }
+ const T* operator-> () const noexcept
+ {
+ return &m_t;
+ }
+ operator const T& () const noexcept
+ {
+ return m_t;
+ }
+ operator const T* () const noexcept
+ {
+ return &m_t;
+ }
+
+private:
+ T m_t;
+ char pad [Memory::cacheLineAlignBytes - sizeof (T)];
+};
+
+#else
+
+template
+class Aligned
+{
+public:
+ Aligned ()
+ { }
+
+ template
+ explicit Aligned (const T1& t1)
+ : m_t (t1) { }
+
+ template
+ Aligned (const T1& t1, const T2& t2)
+ : m_t (t1, t2) { }
+
+ template
+ Aligned (const T1& t1, const T2& t2, const T3& t3)
+ : m_t (t1, t2, t3) { }
+
+ template
+ Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4)
+ : m_t (t1, t2, t3, t4) { }
+
+ template
+ Aligned (const T1& t1, const T2& t2, const T3& t3,
+ const T4& t4, const T5& t5)
+ : m_t (t1, t2, t3, t4, t5) { }
+
+ template
+ Aligned (const T1& t1, const T2& t2, const T3& t3,
+ const T4& t4, const T5& t5, const T6& t6)
+ : m_t (t1, t2, t3, t4, t5, t6) { }
+
+ template < class T1, class T2, class T3, class T4,
+ class T5, class T6, class T7 >
+ Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
+ const T5& t5, const T6& t6, const T7& t7)
+ : m_t (t1, t2, t3, t4, t5, t6, t7) { }
+
+ template < class T1, class T2, class T3, class T4,
+ class T5, class T6, class T7, class T8 >
+ Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4,
+ const T5& t5, const T6& t6, const T7& t7, const T8& t8)
+ : m_t (t1, t2, t3, t4, t5, t6, t7, t8) { }
+
+ void operator= (const T& other)
+ {
+ m_t = other;
+ }
+
+ T& operator* () noexcept { return m_t; }
+ T* operator-> () noexcept { return &m_t; }
+ operator T& () noexcept { return m_t; }
+ operator T* () noexcept { return &m_t; }
+
+ const T& operator* () const noexcept
+ {
+ return m_t;
+ }
+ const T* operator-> () const noexcept
+ {
+ return &m_t;
+ }
+ operator const T& () const noexcept
+ {
+ return m_t;
+ }
+ operator const T* () const noexcept
+ {
+ return &m_t;
+ }
+
+private:
+ T m_t;
+};
+
+template
+class Padded
+{
+public:
+ Padded ()
+ { }
+
+ template
+ explicit Padded (const T1& t1)
+ : m_t (t1) { }
+
+ template