diff --git a/Builds/VisualStudio2012/BeastConfig.h b/Builds/VisualStudio2012/BeastConfig.h index 715c37a44b..0a19d0402d 100644 --- a/Builds/VisualStudio2012/BeastConfig.h +++ b/Builds/VisualStudio2012/BeastConfig.h @@ -120,8 +120,4 @@ //#define BEAST_BIND_USES_TR1 1 //#define BEAST_BIND_USES_BOOST 1 -#ifndef BEAST_USE_LEAKCHECKED -#define BEAST_USE_LEAKCHECKED 1 -#endif - #endif diff --git a/Builds/VisualStudio2012/beast.vcxproj b/Builds/VisualStudio2012/beast.vcxproj index 8e3f0c4b5f..a75601dae5 100644 --- a/Builds/VisualStudio2012/beast.vcxproj +++ b/Builds/VisualStudio2012/beast.vcxproj @@ -208,6 +208,7 @@ + @@ -778,6 +779,12 @@ true true + + true + true + true + true + true true diff --git a/Builds/VisualStudio2012/beast.vcxproj.filters b/Builds/VisualStudio2012/beast.vcxproj.filters index cdfd75ddf8..4224376f69 100644 --- a/Builds/VisualStudio2012/beast.vcxproj.filters +++ b/Builds/VisualStudio2012/beast.vcxproj.filters @@ -608,6 +608,9 @@ beast_core\maths + + beast_core\time + @@ -946,6 +949,9 @@ beast_core\native + + beast_core\time + diff --git a/TODO.txt b/TODO.txt index 188d0ec149..54ab94fd34 100644 --- a/TODO.txt +++ b/TODO.txt @@ -2,6 +2,8 @@ BEAST TODO -------------------------------------------------------------------------------- +- Make OwnedArray add routines return a pointer instead of reference + - Tidy up CacheLine, MemoryAlignment - Remove anything having to do with DLL builds like diff --git a/modules/beast_core/beast_core.h b/modules/beast_core/beast_core.h index 9ccd2c4be2..8ce82f6c26 100644 --- a/modules/beast_core/beast_core.h +++ b/modules/beast_core/beast_core.h @@ -81,10 +81,6 @@ #define BEAST_BOOST_IS_AVAILABLE 0 #endif -#ifndef BEAST_USE_LEAKCHECKED -#define BEAST_USE_LEAKCHECKED BEAST_CHECK_MEMORY_LEAKS -#endif - //------------------------------------------------------------------------------ // // This is a hack to fix boost's goofy placeholders @@ -208,6 +204,7 @@ namespace beast #include "containers/beast_LockFreeStack.h" #include "threads/beast_SpinDelay.h" #include "memory/beast_StaticObject.h" +#include "time/beast_PerformedAtExit.h" #include "diagnostic/beast_LeakChecked.h" #include "memory/beast_Memory.h" #include "memory/beast_ByteOrder.h" @@ -261,7 +258,6 @@ namespace beast #include "memory/beast_ReferenceCountedObject.h" #include "memory/beast_ScopedPointer.h" #include "threads/beast_SpinLock.h" -#include "time/beast_PerformedAtExit.h" #include "memory/beast_SharedSingleton.h" #include "memory/beast_WeakReference.h" #include "memory/beast_MemoryAlignment.h" diff --git a/modules/beast_core/diagnostic/beast_LeakChecked.cpp b/modules/beast_core/diagnostic/beast_LeakChecked.cpp index 7b68e983a3..dbff127934 100644 --- a/modules/beast_core/diagnostic/beast_LeakChecked.cpp +++ b/modules/beast_core/diagnostic/beast_LeakChecked.cpp @@ -17,7 +17,8 @@ */ //============================================================================== -#if BEAST_USE_LEAKCHECKED +namespace Implemented +{ class LeakCheckedBase::CounterBase::Singleton { @@ -27,16 +28,16 @@ public: m_list.push_front (counter); } - void detectAllLeaks () + void checkForLeaks () { for (;;) { - CounterBase* counter = m_list.pop_front (); + CounterBase* const counter = m_list.pop_front (); if (!counter) break; - counter->detectLeaks (); + counter->checkForLeaks (); } } @@ -48,6 +49,8 @@ public: } private: + friend class LeakCheckedBase; + LockFreeStack m_list; }; @@ -58,12 +61,7 @@ LeakCheckedBase::CounterBase::CounterBase () Singleton::getInstance ().push_back (this); } -void LeakCheckedBase::CounterBase::detectAllLeaks () -{ - Singleton::getInstance ().detectAllLeaks (); -} - -void LeakCheckedBase::CounterBase::detectLeaks () +void LeakCheckedBase::CounterBase::checkForLeaks () { // If there's a runtime error from this line, it means there's // an order of destruction problem between different translation units! @@ -91,9 +89,9 @@ void LeakCheckedBase::CounterBase::detectLeaks () //------------------------------------------------------------------------------ -void LeakCheckedBase::detectAllLeaks () +void LeakCheckedBase::checkForLeaks () { - CounterBase::detectAllLeaks (); + CounterBase::Singleton::getInstance ().checkForLeaks (); } -#endif +} diff --git a/modules/beast_core/diagnostic/beast_LeakChecked.h b/modules/beast_core/diagnostic/beast_LeakChecked.h index 36990fa94e..f25a649705 100644 --- a/modules/beast_core/diagnostic/beast_LeakChecked.h +++ b/modules/beast_core/diagnostic/beast_LeakChecked.h @@ -17,20 +17,14 @@ */ //============================================================================== -#ifndef BEAST_LEAKCHECKED_BEASTHEADER -#define BEAST_LEAKCHECKED_BEASTHEADER +#ifndef BEAST_LEAKCHECKED_H_INCLUDED +#define BEAST_LEAKCHECKED_H_INCLUDED -// -// Derived classes are automatically leak-checked on exit -// - -#if BEAST_USE_LEAKCHECKED +namespace Implemented +{ class BEAST_API LeakCheckedBase { -public: - static void detectAllLeaks (); - protected: class CounterBase : public LockFreeStack ::Node { @@ -51,18 +45,23 @@ protected: virtual char const* getClassName () const = 0; - static void detectAllLeaks (); - private: - void detectLeaks (); + void checkForLeaks (); virtual void checkPureVirtual () const = 0; - protected: + private: + friend class LeakCheckedBase; + class Singleton; Atomic m_count; }; + +private: + friend class PerformedAtExit::ExitHook; + + static void checkForLeaks (); }; //------------------------------------------------------------------------------ @@ -81,7 +80,7 @@ protected: getCounter ().increment (); } - LeakChecked (const LeakChecked&) noexcept + LeakChecked (LeakChecked const&) noexcept { getCounter ().increment (); } @@ -113,6 +112,8 @@ protected: } private: + // Singleton that maintains the count of this object + // class Counter : public CounterBase { public: @@ -139,6 +140,8 @@ private: return typeid (Object).name (); } + // Retrieve the singleton for this object + // static Counter& getCounter () noexcept { static Counter* volatile s_instance; @@ -156,14 +159,20 @@ private: } }; -#else +} + +//------------------------------------------------------------------------------ + +namespace Dummy +{ class BEAST_API LeakCheckedBase { private: friend class PerformedAtExit; - static void detectAllLeaks () { } +public: + static void checkForLeaks () { } }; template @@ -171,6 +180,18 @@ struct LeakChecked : LeakCheckedBase { }; +} + +//------------------------------------------------------------------------------ + +// Lift the corresponding implementation +// +#if BEAST_CHECK_MEMORY_LEAKS +using Implemented::LeakChecked; +using Implemented::LeakCheckedBase; +#else +using Dummy::LeakChecked; +using Dummy::LeakCheckedBase; #endif #endif diff --git a/modules/beast_core/memory/beast_CacheLine.h b/modules/beast_core/memory/beast_CacheLine.h index 44d06640bb..ef7b476bbd 100644 --- a/modules/beast_core/memory/beast_CacheLine.h +++ b/modules/beast_core/memory/beast_CacheLine.h @@ -23,7 +23,7 @@ // Allows turning off of all padding, // e.g. for memory-constrained systems or testing. // -#define GLOBAL_PADDING_ENABLED 0 +#define GLOBAL_PADDING_ENABLED 1 namespace CacheLine { @@ -32,77 +32,76 @@ namespace CacheLine // Pads an object so that it starts on a cache line boundary. // +/** Pad an object to start on a cache line boundary. + + Up to 8 constructor parameters are passed through. +*/ template class Aligned { public: - ~Aligned () - { - ptr ()->~T (); - } - Aligned () { new (ptr ()) T; } template - explicit Aligned (const T1& t1) + Aligned (T1 t1) { new (ptr ()) T (t1); } template - Aligned (const T1& t1, const T2& t2) + Aligned (T1 t1, T2 t2) { new (ptr ()) T (t1, t2); } template - Aligned (const T1& t1, const T2& t2, const T3& t3) + Aligned (T1 t1, T2 t2, T3 t3) { new (ptr ()) T (t1, t2, t3); } template - Aligned (const T1& t1, const T2& t2, const T3& t3, const T4& t4) + Aligned (T1 t1, T2 t2, T3 t3, 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) + Aligned (T1 t1, T2 t2, T3 t3, T4 t4, 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) + Aligned (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, 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) + template + Aligned (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, 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) + template + Aligned (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) { new (ptr ()) T (t1, t2, t3, t4, t5, t6, t7, t8); } - void operator= (T const& other) + ~Aligned () + { + ptr ()->~T (); + } + + T& operator= (T const& other) { *ptr () = other; + return *ptr (); } inline T& operator* () noexcept { return *ptr (); } @@ -110,22 +109,10 @@ public: 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 (); - } + inline const T& operator* () const noexcept { return *ptr (); } + inline const T* operator-> () const noexcept { return ptr (); } + inline operator T const& () const noexcept { return *ptr (); } + inline operator T const* () const noexcept { return ptr (); } private: inline T* ptr () noexcept @@ -138,85 +125,85 @@ private: */ } - char m_storage [ (sizeof (T) + Memory::cacheLineAlignMask) - & ~Memory::cacheLineAlignMask]; + 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. -// +/** End-pads an object to completely fill straddling CPU cache lines. + + 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) { } + explicit Padded (T1 t1) + : m_t (t1) + { + } template - Padded (const T1& t1, const T2& t2) - : m_t (t1, t2) { } + Padded (T1 t1, T2 t2) + : m_t (t1, t2) + { + } template - Padded (const T1& t1, const T2& t2, const T3& t3) - : m_t (t1, t2, t3) { } + Padded (T1 t1, T2 t2, 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) { } + Padded (T1 t1, T2 t2, T3 t3, 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) { } + Padded (T1 t1, T2 t2, T3 t3, T4 t4, 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) { } + Padded (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, 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 + Padded (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, 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) { } + template + Padded (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) + : m_t (t1, t2, t3, t4, t5, t6, t7, t8) + { + } - void operator= (const T& other) + T& operator= (T const& other) { m_t = other; + return m_t; } - T& operator* () noexcept { return m_t; } + T& operator* () noexcept { return m_t; } T* operator-> () noexcept { return &m_t; } - operator T& () noexcept { return m_t; } - operator T* () 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; - } + const T& operator* () const noexcept { return m_t; } + const T* operator-> () const noexcept { return &m_t; } + operator T const& () const noexcept { return m_t; } + operator T const* () const noexcept { return &m_t; } private: T m_t; diff --git a/modules/beast_core/time/beast_PerformedAtExit.cpp b/modules/beast_core/time/beast_PerformedAtExit.cpp index 4bcf1001be..7babb0d2dd 100644 --- a/modules/beast_core/time/beast_PerformedAtExit.cpp +++ b/modules/beast_core/time/beast_PerformedAtExit.cpp @@ -25,6 +25,8 @@ public: private: ~ExitHook () { + // Call all PerformedAtExit objects + // PerformedAtExit* object = s_list->pop_front (); while (object != nullptr) @@ -34,7 +36,9 @@ private: object = s_list->pop_front (); } - LeakCheckedBase::detectAllLeaks (); + // Now do the leak checking + // + LeakCheckedBase::checkForLeaks (); } public: diff --git a/modules/beast_core/time/beast_PerformedAtExit.h b/modules/beast_core/time/beast_PerformedAtExit.h index ce8801ecee..0c79d3646f 100644 --- a/modules/beast_core/time/beast_PerformedAtExit.h +++ b/modules/beast_core/time/beast_PerformedAtExit.h @@ -36,6 +36,9 @@ // class BEAST_API PerformedAtExit : public LockFreeStack ::Node { +public: + class ExitHook; + protected: PerformedAtExit (); virtual ~PerformedAtExit () { } @@ -44,9 +47,6 @@ protected: /** Called at program exit. */ virtual void performAtExit () = 0; - -private: - class ExitHook; }; #endif