From 759ffa51fb865adbebbfdb44273f9b83ec7cc8f3 Mon Sep 17 00:00:00 2001 From: khizmax Date: Sun, 15 Jan 2017 23:15:22 +0300 Subject: [PATCH] HP and DHP SMR totally refactored --- CMakeLists.txt | 7 +- cds/compiler/clang/defs.h | 9 + cds/compiler/gcc/defs.h | 8 + cds/compiler/icl/defs.h | 15 + cds/compiler/vc/defs.h | 9 + cds/details/throw_exception.h | 88 + cds/gc/details/dhp.h | 874 ---------- cds/gc/details/hp.h | 680 -------- cds/gc/details/hp_alloc.h | 373 ----- cds/gc/details/hp_common.h | 184 +++ cds/gc/details/hp_type.h | 53 - cds/gc/dhp.h | 4 +- cds/gc/dhp_smr.h | 1355 +++++++++++++++ cds/gc/hp.h | 8 +- cds/gc/hp_smr.h | 1461 +++++++++++++++++ cds/gc/impl/dhp_decl.h | 823 ---------- cds/gc/impl/dhp_impl.h | 115 -- cds/gc/impl/hp_decl.h | 883 ---------- cds/gc/impl/hp_impl.h | 150 -- cds/threading/details/_common.h | 100 +- cds/threading/details/cxx11_manager.h | 24 - cds/threading/details/gcc_manager.h | 24 - cds/threading/details/msvc_manager.h | 24 - cds/threading/details/pthread_manager.h | 22 - cds/threading/details/wintls_manager.h | 25 +- cds/threading/model.h | 26 - change.log | 16 + doxygen/cds.doxy | 3 +- projects/Win/vc14/cds.vcxproj | 29 +- projects/Win/vc14/cds.vcxproj.filters | 46 +- projects/Win/vc14/gtest-deque.vcxproj | 12 +- .../Win/vc14/gtest-ilist-iterable.vcxproj | 12 +- projects/Win/vc14/gtest-ilist-lazy.vcxproj | 12 +- projects/Win/vc14/gtest-ilist-michael.vcxproj | 12 +- projects/Win/vc14/gtest-iset-feldman.vcxproj | 12 +- .../vc14/gtest-iset-michael-iterable.vcxproj | 12 +- .../Win/vc14/gtest-iset-michael-lazy.vcxproj | 12 +- projects/Win/vc14/gtest-iset-michael.vcxproj | 12 +- projects/Win/vc14/gtest-iset-skip.vcxproj | 12 +- .../vc14/gtest-iset-split-iterable.vcxproj | 12 +- .../Win/vc14/gtest-iset-split-lazy.vcxproj | 12 +- .../Win/vc14/gtest-iset-split-michael.vcxproj | 12 +- projects/Win/vc14/gtest-list-iterable.vcxproj | 12 +- projects/Win/vc14/gtest-list-lazy.vcxproj | 12 +- projects/Win/vc14/gtest-list-michael.vcxproj | 12 +- projects/Win/vc14/gtest-map-feldman.vcxproj | 12 +- .../vc14/gtest-map-michael-iterable.vcxproj | 12 +- .../Win/vc14/gtest-map-michael-lazy.vcxproj | 12 +- projects/Win/vc14/gtest-map-michael.vcxproj | 12 +- projects/Win/vc14/gtest-map-skip.vcxproj | 12 +- .../Win/vc14/gtest-map-split-iterable.vcxproj | 12 +- .../Win/vc14/gtest-map-split-lazy.vcxproj | 12 +- .../Win/vc14/gtest-map-split-michael.vcxproj | 12 +- projects/Win/vc14/gtest-misc.vcxproj | 12 +- projects/Win/vc14/gtest-pqueue.vcxproj | 12 +- projects/Win/vc14/gtest-queue.vcxproj | 12 +- projects/Win/vc14/gtest-set-feldman.vcxproj | 12 +- .../vc14/gtest-set-michael-iterable.vcxproj | 12 +- .../Win/vc14/gtest-set-michael-lazy.vcxproj | 12 +- projects/Win/vc14/gtest-set-michael.vcxproj | 12 +- projects/Win/vc14/gtest-set-skip.vcxproj | 12 +- .../Win/vc14/gtest-set-split-iterable.vcxproj | 12 +- .../Win/vc14/gtest-set-split-lazy.vcxproj | 12 +- .../Win/vc14/gtest-set-split-michael.vcxproj | 12 +- projects/Win/vc14/gtest-stack.vcxproj | 12 +- projects/Win/vc14/gtest-tree-bronson.vcxproj | 12 +- projects/Win/vc14/gtest-tree-ellen.vcxproj | 12 +- projects/Win/vc14/stress-framework.vcxproj | 12 +- projects/Win/vc14/stress-freelist.vcxproj | 12 +- projects/Win/vc14/stress-map-delodd.vcxproj | 12 +- projects/Win/vc14/stress-map-find_int.vcxproj | 12 +- .../Win/vc14/stress-map-find_string.vcxproj | 12 +- .../Win/vc14/stress-map-insdel-func.vcxproj | 12 +- .../Win/vc14/stress-map-insdel-int.vcxproj | 12 +- .../vc14/stress-map-insdel-item-int.vcxproj | 12 +- .../Win/vc14/stress-map-insdel-string.vcxproj | 12 +- .../Win/vc14/stress-map-insdelfind.vcxproj | 12 +- .../Win/vc14/stress-map-insfind-int.vcxproj | 12 +- projects/Win/vc14/stress-pqueue.vcxproj | 12 +- projects/Win/vc14/stress-queue.vcxproj | 12 +- projects/Win/vc14/stress-set-delodd.vcxproj | 12 +- .../Win/vc14/stress-set-insdel_func.vcxproj | 12 +- .../Win/vc14/stress-set-insdel_string.vcxproj | 12 +- .../Win/vc14/stress-set-insdelfind.vcxproj | 12 +- .../Win/vc14/stress-set-iteration.vcxproj | 12 +- projects/Win/vc14/stress-stack.vcxproj | 12 +- src/dhp.cpp | 488 ++++++ src/dhp_gc.cpp | 289 ---- src/hp.cpp | 512 ++++++ src/hp_gc.cpp | 427 ----- src/init.cpp | 3 - src/thread_data.cpp | 99 ++ test/stress/data/test-debug.conf | 6 +- test/stress/data/test-express-x86.conf | 6 +- test/stress/data/test-express.conf | 8 +- test/stress/data/test.conf | 6 +- test/stress/main.cpp | 12 +- .../intrusive-list/intrusive_iterable_dhp.cpp | 4 +- .../intrusive-list/intrusive_lazy_dhp.cpp | 4 +- .../intrusive-list/intrusive_michael_dhp.cpp | 4 +- .../intrusive_feldman_hashset_dhp.cpp | 4 +- .../intrusive_michael_iterable_dhp.cpp | 4 +- .../intrusive_michael_lazy_dhp.cpp | 4 +- .../intrusive_michael_michael_dhp.cpp | 4 +- .../intrusive-set/intrusive_skiplist_dhp.cpp | 4 +- .../intrusive_split_iterable_dhp.cpp | 4 +- .../intrusive_split_lazy_dhp.cpp | 4 +- .../intrusive_split_michael_dhp.cpp | 4 +- test/unit/list/iterable_dhp.cpp | 4 +- test/unit/list/kv_iterable_dhp.cpp | 4 +- test/unit/list/kv_lazy_dhp.cpp | 4 +- test/unit/list/kv_michael_dhp.cpp | 4 +- test/unit/list/lazy_dhp.cpp | 4 +- test/unit/list/michael_dhp.cpp | 2 +- test/unit/map/feldman_hashmap_dhp.cpp | 5 +- test/unit/map/michael_iterable_dhp.cpp | 4 +- test/unit/map/michael_lazy_dhp.cpp | 4 +- test/unit/map/michael_michael_dhp.cpp | 4 +- test/unit/map/skiplist_dhp.cpp | 4 +- test/unit/map/split_iterable_dhp.cpp | 4 +- test/unit/map/split_lazy_dhp.cpp | 4 +- test/unit/map/split_michael_dhp.cpp | 5 +- test/unit/queue/basket_queue_dhp.cpp | 2 +- .../unit/queue/intrusive_basket_queue_dhp.cpp | 2 +- test/unit/queue/intrusive_moirqueue_dhp.cpp | 4 +- test/unit/queue/intrusive_msqueue_dhp.cpp | 4 +- test/unit/queue/intrusive_optqueue_dhp.cpp | 4 +- .../queue/intrusive_segmented_queue_dhp.cpp | 4 +- test/unit/queue/moirqueue_dhp.cpp | 4 +- test/unit/queue/msqueue_dhp.cpp | 4 +- test/unit/queue/optimistic_queue_dhp.cpp | 4 +- test/unit/queue/segmented_queue_dhp.cpp | 4 +- test/unit/set/feldman_hashset_dhp.cpp | 4 +- test/unit/set/michael_iterable_dhp.cpp | 4 +- test/unit/set/michael_lazy_dhp.cpp | 4 +- test/unit/set/michael_michael_dhp.cpp | 4 +- test/unit/set/skiplist_dhp.cpp | 4 +- test/unit/set/split_iterable_dhp.cpp | 4 +- test/unit/set/split_lazy_dhp.cpp | 4 +- test/unit/set/split_michael_dhp.cpp | 4 +- .../stack/intrusive_treiber_stack_dhp.cpp | 4 +- test/unit/stack/treiber_stack_dhp.cpp | 4 +- test/unit/tree/ellen_bintree_map_dhp.cpp | 4 +- test/unit/tree/ellen_bintree_set_dhp.cpp | 4 +- test/unit/tree/intrusive_ellenbintree_dhp.cpp | 4 +- 145 files changed, 4743 insertions(+), 5411 deletions(-) create mode 100644 cds/details/throw_exception.h delete mode 100644 cds/gc/details/dhp.h delete mode 100644 cds/gc/details/hp.h delete mode 100644 cds/gc/details/hp_alloc.h create mode 100644 cds/gc/details/hp_common.h delete mode 100644 cds/gc/details/hp_type.h create mode 100644 cds/gc/dhp_smr.h create mode 100644 cds/gc/hp_smr.h delete mode 100644 cds/gc/impl/dhp_decl.h delete mode 100644 cds/gc/impl/dhp_impl.h delete mode 100644 cds/gc/impl/hp_decl.h delete mode 100644 cds/gc/impl/hp_impl.h create mode 100644 src/dhp.cpp delete mode 100644 src/dhp_gc.cpp create mode 100644 src/hp.cpp delete mode 100644 src/hp_gc.cpp create mode 100644 src/thread_data.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4848054a..0843a2c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,11 +109,12 @@ include_directories(${PROJECT_SOURCE_DIR}) set(LIBRARIES_COMPONENT lib) set(HEADERS_COMPONENT devel) -set(SOURCES src/hp_gc.cpp - src/init.cpp - src/dhp_gc.cpp +set(SOURCES src/init.cpp + src/hp.cpp + src/dhp.cpp src/urcu_gp.cpp src/urcu_sh.cpp + src/thread_data.cpp src/topology_hpux.cpp src/topology_linux.cpp src/topology_osx.cpp diff --git a/cds/compiler/clang/defs.h b/cds/compiler/clang/defs.h index 3c43ef09..daec9c73 100644 --- a/cds/compiler/clang/defs.h +++ b/cds/compiler/clang/defs.h @@ -108,6 +108,8 @@ # define CDS_DEPRECATED( reason ) __attribute__((deprecated( reason ))) #endif +#define CDS_NORETURN __attribute__((__noreturn__)) + // ************************************************* // Features #if defined(__has_feature) && __has_feature(thread_sanitizer) @@ -127,6 +129,13 @@ #define cds_likely( expr ) __builtin_expect( !!( expr ), 1 ) #define cds_unlikely( expr ) __builtin_expect( !!( expr ), 0 ) +// Exceptions + +#if defined( __EXCEPTIONS ) && __EXCEPTIONS == 1 +# define CDS_EXCEPTION_ENABLED +#endif + + // double-width CAS support - only for libc++ #ifdef _LIBCPP_VERSION # if CDS_BUILD_BITS == 64 diff --git a/cds/compiler/gcc/defs.h b/cds/compiler/gcc/defs.h index 32b02c88..f7e3c403 100644 --- a/cds/compiler/gcc/defs.h +++ b/cds/compiler/gcc/defs.h @@ -97,11 +97,19 @@ # define CDS_DEPRECATED( reason ) __attribute__((deprecated( reason ))) #endif +#define CDS_NORETURN __attribute__((__noreturn__)) + // likely/unlikely #define cds_likely( expr ) __builtin_expect( !!( expr ), 1 ) #define cds_unlikely( expr ) __builtin_expect( !!( expr ), 0 ) +// Exceptions + +#if defined( __EXCEPTIONS ) && __EXCEPTIONS == 1 +# define CDS_EXCEPTION_ENABLED +#endif + // double-width CAS support // note: gcc-4.8 does not support double-word atomics // gcc-4.9: a lot of crashes when use DCAS diff --git a/cds/compiler/icl/defs.h b/cds/compiler/icl/defs.h index dde93b96..f0e0729d 100644 --- a/cds/compiler/icl/defs.h +++ b/cds/compiler/icl/defs.h @@ -133,10 +133,25 @@ // Attributes #if CDS_OS_INTERFACE == CDS_OSI_WINDOWS # define CDS_DEPRECATED( reason ) __declspec(deprecated( reason )) +# define CDS_NORETURN __declspec(noreturn) #else # define CDS_DEPRECATED( reason ) __attribute__((deprecated( reason ))) +# define CDS_NORETURN __attribute__((__noreturn__)) #endif +// Exceptions + +#if CDS_OS_INTERFACE == CDS_OSI_WINDOWS +# if defined( _CPPUNWIND ) +# define CDS_EXCEPTION_ENABLED +# endif +#else +# if defined( __EXCEPTIONS ) && __EXCEPTIONS == 1 +# define CDS_EXCEPTION_ENABLED +# endif +#endif + + #include //@endcond diff --git a/cds/compiler/vc/defs.h b/cds/compiler/vc/defs.h index d3425dd5..f665acfb 100644 --- a/cds/compiler/vc/defs.h +++ b/cds/compiler/vc/defs.h @@ -159,6 +159,15 @@ # define CDS_DEPRECATED( reason ) __declspec(deprecated( reason )) #endif +#define CDS_NORETURN __declspec(noreturn) + +// Exceptions + +#if defined( _CPPUNWIND ) +# define CDS_EXCEPTION_ENABLED +#endif + + // double-width CAS support //#define CDS_DCAS_SUPPORT diff --git a/cds/details/throw_exception.h b/cds/details/throw_exception.h new file mode 100644 index 00000000..cd708df8 --- /dev/null +++ b/cds/details/throw_exception.h @@ -0,0 +1,88 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CDSLIB_DETAILS_THROW_EXCEPTION_H +#define CDSLIB_DETAILS_THROW_EXCEPTION_H + +#include +#if !defined( CDS_EXCEPTION_ENABLED ) && !defined( CDS_USER_DEFINED_THROW_HANDLER ) +# include +#endif + +namespace cds { + +#if !defined( CDS_USER_DEFINED_THROW_EXCEPTION ) +#if defined( CDS_EXCEPTION_ENABLED ) + /// Function to throw an exception + /** + If you compile your code with exception enabled, \p %throw_exception() function + throws the \p exception. + + If exception is disabled, \p %throw_exception() prints an exception message to + standard output and call \p abort(). + + You may supply your own \p %cds::throw_exception() function; + for that you should specify \p -DCDS_USER_DEFINED_THROW_EXCEPTION + in compiler command line. + + @note \p %throw_exception() never returns. If the user-defined \p %throw_exception() returns, + the behavior is undefined. + */ + template + CDS_NORETURN static inline void throw_exception( + E&& exception, ///< Exception to throw + char const* file, ///< Source filename + int line ///< File line + ) + { + CDS_UNUSED( file ); + CDS_UNUSED( line ); + + throw exception; + } +#else + template + CDS_NORETURN static inline void throw_exception( E&& exception, char const* file, int line ) + { + printf( "file %s, line %d: %s\n", file, line, exception.what() ); + abort(); + } +#endif +//#else + // User-provided cds::throw_exception() +#endif + +#define CDS_THROW_EXCEPTION( exception ) ::cds::throw_exception( exception, __FILE__, __LINE__ ) + +} // namespace cds + + +#endif // #ifndef CDSLIB_DETAILS_THROW_EXCEPTION_H + diff --git a/cds/gc/details/dhp.h b/cds/gc/details/dhp.h deleted file mode 100644 index da9113d1..00000000 --- a/cds/gc/details/dhp.h +++ /dev/null @@ -1,874 +0,0 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef CDSLIB_GC_DETAILS_DHP_H -#define CDSLIB_GC_DETAILS_DHP_H - -#include // unique_lock -#include -#include -#include -#include -#include -#include - -#if CDS_COMPILER == CDS_COMPILER_MSVC -# pragma warning(push) -# pragma warning(disable:4251) // C4251: 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' -#endif - -//@cond -namespace cds { namespace gc { - - /// Dynamic Hazard Pointer reclamation schema - /** - The cds::gc::dhp namespace and its members are internal representation of the GC and should not be used directly. - Use cds::gc::DHP class in your code. - - Dynamic Hazard Pointer (DHP) garbage collector is a singleton. The main user-level part of DHP schema is - GC class and its nested classes. Before use any DHP-related class you must initialize DHP garbage collector - by contructing cds::gc::DHP object in beginning of your main(). - See cds::gc::DHP class for explanation. - - \par Implementation issues - The global list of free guards (\p cds::gc::dhp::details::guard_allocator) is protected by a spin-lock (i.e. serialized). - It seems that this solution should not introduce significant performance bottleneck, because each thread has its own set - of guards allocated from the global list of free guards and the access to the global list is occurred only when - all thread's guard is busy. In this case the thread allocates a next block of guards from the global list. - Guards allocated for the thread is push back to the global list only when the thread terminates. - */ - namespace dhp { - - // Forward declarations - class Guard; - template class GuardArray; - class ThreadGC; - class GarbageCollector; - - /// Retired pointer type - typedef cds::gc::details::retired_ptr retired_ptr; - - using cds::gc::details::free_retired_ptr_func; - - /// Details of Dynamic Hazard Pointer algorithm - namespace details { - - // Forward declaration - class liberate_set; - - /// Retired pointer buffer node - struct retired_ptr_node { - retired_ptr m_ptr ; ///< retired pointer - atomics::atomic m_pNext ; ///< next retired pointer in buffer - atomics::atomic m_pNextFree ; ///< next item in free list of \p retired_ptr_node - }; - - /// Internal guard representation - struct guard_data { - typedef void * guarded_ptr; ///< type of value guarded - - atomics::atomic pPost; ///< pointer guarded - atomics::atomic pGlobalNext; ///< next item of global list of allocated guards - atomics::atomic pNextFree; ///< pointer to the next item in global or thread-local free-list - - guard_data * pThreadNext; ///< next item of thread's local list of guards - - guard_data() CDS_NOEXCEPT - : pPost( nullptr ) - , pGlobalNext( nullptr ) - , pNextFree( nullptr ) - , pThreadNext( nullptr ) - {} - - void init() CDS_NOEXCEPT - { - pPost.store( nullptr, atomics::memory_order_relaxed ); - } - - /// Checks if the guard is free, that is, it does not contain any pointer guarded - bool isFree() const CDS_NOEXCEPT - { - return pPost.load( atomics::memory_order_acquire ) == nullptr; - } - - guarded_ptr get( atomics::memory_order order = atomics::memory_order_acquire ) - { - return pPost.load( order ); - } - - void set( guarded_ptr p, atomics::memory_order order = atomics::memory_order_release ) - { - pPost.store( p, order ); - } - }; - - /// Guard allocator - template - class guard_allocator - { - cds::details::Allocator m_GuardAllocator; ///< guard allocator - - atomics::atomic m_GuardList; ///< Head of allocated guard list (linked by guard_data::pGlobalNext field) - atomics::atomic m_FreeGuardList; ///< Head of free guard list (linked by guard_data::pNextFree field) - cds::sync::spin m_freeListLock; ///< Access to m_FreeGuardList - - /* - Unfortunately, access to the list of free guard is lock-based. - Lock-free manipulations with guard free-list are ABA-prone. - TODO: working with m_FreeGuardList in lock-free manner. - */ - - private: - /// Allocates new guard from the heap. The function uses aligned allocator - guard_data * allocNew() - { - //TODO: the allocator should make block allocation - - details::guard_data * pGuard = m_GuardAllocator.New(); - - // Link guard to the list - // m_GuardList is an accumulating list and it cannot support concurrent deletion, - // so, ABA problem is impossible for it - details::guard_data * pHead = m_GuardList.load( atomics::memory_order_acquire ); - do { - pGuard->pGlobalNext.store( pHead, atomics::memory_order_relaxed ); - // pHead is changed by compare_exchange_weak - } while ( !m_GuardList.compare_exchange_weak( pHead, pGuard, atomics::memory_order_acq_rel, atomics::memory_order_acquire )); - - pGuard->init(); - return pGuard; - } - - public: - // Default ctor - guard_allocator() CDS_NOEXCEPT - : m_GuardList( nullptr ) - , m_FreeGuardList( nullptr ) - {} - - // Destructor - ~guard_allocator() - { - guard_data * pNext; - for ( guard_data * pData = m_GuardList.load( atomics::memory_order_relaxed ); pData != nullptr; pData = pNext ) { - pNext = pData->pGlobalNext.load( atomics::memory_order_relaxed ); - m_GuardAllocator.Delete( pData ); - } - } - - /// Allocates a guard from free list or from heap if free list is empty - guard_data* alloc() - { - // Try to pop a guard from free-list - details::guard_data * pGuard; - - { - std::unique_lock al( m_freeListLock ); - pGuard = m_FreeGuardList.load(atomics::memory_order_relaxed); - if ( pGuard ) - m_FreeGuardList.store( pGuard->pNextFree.load(atomics::memory_order_relaxed), atomics::memory_order_relaxed ); - } - if ( !pGuard ) - return allocNew(); - - pGuard->init(); - return pGuard; - } - - /// Frees guard \p pGuard - /** - The function places the guard \p pGuard into free-list - */ - void free( guard_data* pGuard ) CDS_NOEXCEPT - { - pGuard->pPost.store( nullptr, atomics::memory_order_relaxed ); - - std::unique_lock al( m_freeListLock ); - pGuard->pNextFree.store( m_FreeGuardList.load(atomics::memory_order_relaxed), atomics::memory_order_relaxed ); - m_FreeGuardList.store( pGuard, atomics::memory_order_relaxed ); - } - - /// Allocates list of guard - /** - The list returned is linked by guard's \p pThreadNext and \p pNextFree fields. - - cds::gc::dhp::ThreadGC supporting method - */ - guard_data * allocList( size_t nCount ) - { - assert( nCount != 0 ); - - guard_data * pHead; - guard_data * pLast; - - pHead = - pLast = alloc(); - - // The guard list allocated is private for the thread, - // so, we can use relaxed memory order - while ( --nCount ) { - guard_data * p = alloc(); - pLast->pNextFree.store( pLast->pThreadNext = p, atomics::memory_order_relaxed ); - pLast = p; - } - - pLast->pNextFree.store( pLast->pThreadNext = nullptr, atomics::memory_order_relaxed ); - - return pHead; - } - - /// Frees list of guards - /** - The list \p pList is linked by guard's \p pThreadNext field. - - cds::gc::dhp::ThreadGC supporting method - */ - void freeList( guard_data * pList ) CDS_NOEXCEPT - { - assert( pList != nullptr ); - - guard_data * pLast = pList; - while ( pLast->pThreadNext ) { - pLast->pPost.store( nullptr, atomics::memory_order_relaxed ); - guard_data * p; - pLast->pNextFree.store( p = pLast->pThreadNext, atomics::memory_order_relaxed ); - pLast = p; - } - - std::unique_lock al( m_freeListLock ); - pLast->pNextFree.store( m_FreeGuardList.load(atomics::memory_order_relaxed), atomics::memory_order_relaxed ); - m_FreeGuardList.store( pList, atomics::memory_order_relaxed ); - } - - /// Returns the list's head of guards allocated - guard_data * begin() CDS_NOEXCEPT - { - return m_GuardList.load(atomics::memory_order_acquire); - } - }; - - /// Retired pointer buffer - /** - The buffer of retired nodes ready for liberating. - When size of buffer exceeds a threshold the GC calls \p scan() procedure to free - retired nodes. - */ - class retired_ptr_buffer - { - atomics::atomic m_pHead ; ///< head of buffer - atomics::atomic m_nItemCount; ///< buffer's item count - - public: - retired_ptr_buffer() CDS_NOEXCEPT - : m_pHead( nullptr ) - , m_nItemCount(0) - {} - - ~retired_ptr_buffer() CDS_NOEXCEPT - { - assert( m_pHead.load( atomics::memory_order_relaxed ) == nullptr ); - } - - /// Pushes new node into the buffer. Returns current buffer size - size_t push( retired_ptr_node& node ) CDS_NOEXCEPT - { - retired_ptr_node * pHead = m_pHead.load(atomics::memory_order_acquire); - do { - node.m_pNext.store( pHead, atomics::memory_order_relaxed ); - // pHead is changed by compare_exchange_weak - } while ( !m_pHead.compare_exchange_weak( pHead, &node, atomics::memory_order_release, atomics::memory_order_acquire )); - - return m_nItemCount.fetch_add( 1, atomics::memory_order_relaxed ) + 1; - } - - /// Pushes [pFirst, pLast] list linked by pNext field. - size_t push_list( retired_ptr_node* pFirst, retired_ptr_node* pLast, size_t nSize ) - { - assert( pFirst ); - assert( pLast ); - - retired_ptr_node * pHead = m_pHead.load( atomics::memory_order_acquire ); - do { - pLast->m_pNext.store( pHead, atomics::memory_order_relaxed ); - // pHead is changed by compare_exchange_weak - } while ( !m_pHead.compare_exchange_weak( pHead, pFirst, atomics::memory_order_release, atomics::memory_order_acquire )); - - return m_nItemCount.fetch_add( nSize, atomics::memory_order_relaxed ) + 1; - } - - /// Result of \ref dhp_gc_privatize "privatize" function. - /** - The \p privatize function returns retired node list as \p first and the size of that list as \p second. - */ - typedef std::pair privatize_result; - - /// Gets current list of retired pointer and clears the list - /**@anchor dhp_gc_privatize - */ - privatize_result privatize() CDS_NOEXCEPT - { - privatize_result res; - - // Item counter is needed only as a threshold for \p scan() function - // So, we may clear the item counter without synchronization with m_pHead - res.second = m_nItemCount.exchange( 0, atomics::memory_order_relaxed ); - res.first = m_pHead.exchange( nullptr, atomics::memory_order_acq_rel ); - return res; - } - - /// Returns current size of buffer (approximate) - size_t size() const CDS_NOEXCEPT - { - return m_nItemCount.load(atomics::memory_order_relaxed); - } - }; - - /// Pool of retired pointers - /** - The class acts as an allocator of retired node. - Retired pointers are linked in the lock-free list. - */ - template - class retired_ptr_pool { - /// Pool item - typedef retired_ptr_node item; - - /// Count of items in block - static const size_t m_nItemPerBlock = 1024 / sizeof(item) - 1; - - /// Pool block - struct block { - atomics::atomic pNext; ///< next block - item items[m_nItemPerBlock]; ///< item array - }; - - atomics::atomic m_pBlockListHead; ///< head of of allocated block list - - // To solve ABA problem we use epoch-based approach - unsigned int const m_nEpochBitmask; ///< Epoch bitmask (log2( m_nEpochCount)) - atomics::atomic m_nCurEpoch; ///< Current epoch - atomics::atomic* m_pEpochFree; ///< List of free item per epoch - atomics::atomic m_pGlobalFreeHead; ///< Head of unallocated item list - - typedef cds::details::Allocator< block, Alloc > block_allocator; - typedef cds::details::Allocator< atomics::atomic, Alloc > epoch_array_alloc; - - private: - void allocNewBlock() - { - // allocate new block - block * pNew = block_allocator().New(); - - // link items within the block - item * pLastItem = pNew->items + m_nItemPerBlock - 1; - for ( item * pItem = pNew->items; pItem != pLastItem; ++pItem ) { - pItem->m_pNextFree.store( pItem + 1, atomics::memory_order_release ); - CDS_STRICT_DO( pItem->m_pNext.store( nullptr, atomics::memory_order_relaxed )); - } - - // links new block to the block list - { - block * pHead = m_pBlockListHead.load(atomics::memory_order_relaxed); - do { - pNew->pNext.store( pHead, atomics::memory_order_relaxed ); - // pHead is changed by compare_exchange_weak - } while ( !m_pBlockListHead.compare_exchange_weak( pHead, pNew, atomics::memory_order_release, atomics::memory_order_acquire )); - } - - // links block's items to the free list - { - item * pHead = m_pGlobalFreeHead.load(atomics::memory_order_relaxed); - do { - pLastItem->m_pNextFree.store( pHead, atomics::memory_order_release ); - // pHead is changed by compare_exchange_weak - } while ( !m_pGlobalFreeHead.compare_exchange_weak( pHead, pNew->items, atomics::memory_order_release, atomics::memory_order_acquire )); - } - } - - unsigned int current_epoch() const CDS_NOEXCEPT - { - return m_nCurEpoch.load(atomics::memory_order_acquire) & m_nEpochBitmask; - } - - unsigned int next_epoch() const CDS_NOEXCEPT - { - return (m_nCurEpoch.load(atomics::memory_order_acquire) - 1) & m_nEpochBitmask; - } - - public: - retired_ptr_pool( unsigned int nEpochCount = 8 ) - : m_pBlockListHead( nullptr ) - , m_nEpochBitmask( static_cast(beans::ceil2(nEpochCount)) - 1 ) - , m_nCurEpoch(0) - , m_pEpochFree( epoch_array_alloc().NewArray( m_nEpochBitmask + 1)) - , m_pGlobalFreeHead( nullptr ) - { - - - for (unsigned int i = 0; i <= m_nEpochBitmask; ++i ) - m_pEpochFree[i].store( nullptr, atomics::memory_order_relaxed ); - - allocNewBlock(); - } - - ~retired_ptr_pool() - { - block_allocator a; - block * p; - for ( block * pBlock = m_pBlockListHead.load(atomics::memory_order_relaxed); pBlock; pBlock = p ) { - p = pBlock->pNext.load( atomics::memory_order_relaxed ); - a.Delete( pBlock ); - } - - epoch_array_alloc().Delete( m_pEpochFree, m_nEpochBitmask + 1 ); - } - - /// Increments current epoch - void inc_epoch() CDS_NOEXCEPT - { - m_nCurEpoch.fetch_add( 1, atomics::memory_order_acq_rel ); - } - - /// Allocates the new retired pointer - retired_ptr_node& alloc() - { - unsigned int nEpoch; - item * pItem; - for (;;) { - pItem = m_pEpochFree[ nEpoch = current_epoch() ].load(atomics::memory_order_acquire); - if ( !pItem ) - goto retry; - if ( m_pEpochFree[nEpoch].compare_exchange_weak( pItem, - pItem->m_pNextFree.load(atomics::memory_order_acquire), - atomics::memory_order_acquire, atomics::memory_order_relaxed )) - { - goto success; - } - } - - // Epoch free list is empty - // Alloc from global free list - retry: - pItem = m_pGlobalFreeHead.load( atomics::memory_order_relaxed ); - do { - if ( !pItem ) { - allocNewBlock(); - goto retry; - } - // pItem is changed by compare_exchange_weak - } while ( !m_pGlobalFreeHead.compare_exchange_weak( pItem, - pItem->m_pNextFree.load(atomics::memory_order_acquire), - atomics::memory_order_acquire, atomics::memory_order_acquire )); - - success: - CDS_STRICT_DO( pItem->m_pNextFree.store( nullptr, atomics::memory_order_relaxed )); - return *pItem; - } - - /// Allocates and initializes new retired pointer - retired_ptr_node& alloc( const retired_ptr& p ) - { - retired_ptr_node& node = alloc(); - node.m_ptr = p; - return node; - } - - /// Places the list [pHead, pTail] of retired pointers to pool (frees retired pointers) - /** - The list is linked on the m_pNextFree field - */ - void free_range( retired_ptr_node * pHead, retired_ptr_node * pTail ) CDS_NOEXCEPT - { - assert( pHead != nullptr ); - assert( pTail != nullptr ); - - unsigned int nEpoch; - item * pCurHead; - do { - pCurHead = m_pEpochFree[nEpoch = next_epoch()].load(atomics::memory_order_acquire); - pTail->m_pNextFree.store( pCurHead, atomics::memory_order_release ); - } while ( !m_pEpochFree[nEpoch].compare_exchange_weak( pCurHead, pHead, atomics::memory_order_release, atomics::memory_order_relaxed )); - } - }; - } // namespace details - - /// Memory manager (Garbage collector) - class CDS_EXPORT_API GarbageCollector - { - private: - friend class ThreadGC; - - /// Internal GC statistics - struct internal_stat - { - atomics::atomic m_nGuardCount ; ///< Total guard count - atomics::atomic m_nFreeGuardCount ; ///< Count of free guard - - internal_stat() - : m_nGuardCount(0) - , m_nFreeGuardCount(0) - {} - }; - - public: - /// Exception "No GarbageCollector object is created" - class not_initialized : public std::runtime_error - { - public: - //@cond - not_initialized() - : std::runtime_error( "Global DHP GarbageCollector is not initialized" ) - {} - //@endcond - }; - - /// Internal GC statistics - struct InternalState - { - size_t m_nGuardCount ; ///< Total guard count - size_t m_nFreeGuardCount ; ///< Count of free guard - - //@cond - InternalState() - : m_nGuardCount(0) - , m_nFreeGuardCount(0) - {} - - InternalState& operator =( internal_stat const& s ) - { - m_nGuardCount = s.m_nGuardCount.load(atomics::memory_order_relaxed); - m_nFreeGuardCount = s.m_nFreeGuardCount.load(atomics::memory_order_relaxed); - - return *this; - } - //@endcond - }; - - private: - static GarbageCollector * m_pManager ; ///< GC global instance - - atomics::atomic m_nLiberateThreshold; ///< Max size of retired pointer buffer to call \p scan() - const size_t m_nInitialThreadGuardCount; ///< Initial count of guards allocated for ThreadGC - - details::guard_allocator<> m_GuardPool ; ///< Guard pool - details::retired_ptr_pool<> m_RetiredAllocator ; ///< Pool of free retired pointers - details::retired_ptr_buffer m_RetiredBuffer ; ///< Retired pointer buffer for liberating - - internal_stat m_stat ; ///< Internal statistics - bool m_bStatEnabled ; ///< Internal Statistics enabled - - public: - /// Initializes DHP memory manager singleton - /** - This member function creates and initializes DHP global object. - The function should be called before using CDS data structure based on cds::gc::DHP GC. Usually, - this member function is called in the \p main() function. See cds::gc::dhp for example. - After calling of this function you may use CDS data structures based on cds::gc::DHP. - - \par Parameters - - \p nLiberateThreshold - \p scan() threshold. When count of retired pointers reaches this value, - the \ref dhp_gc_liberate "scan()" member function would be called for freeing retired pointers. - If \p nLiberateThreshold <= 1, \p scan() would called after each \ref dhp_gc_retirePtr "retirePtr" call. - - \p nInitialThreadGuardCount - initial count of guard allocated for ThreadGC. When a thread - is initialized the GC allocates local guard pool for the thread from common guard pool. - By perforce the local thread's guard pool is grown automatically from common pool. - When the thread terminated its guard pool is backed to common GC's pool. - - \p nEpochCount: internally, DHP memory manager uses epoch-based schema to solve - ABA problem for internal data. \p nEpochCount specifies the epoch count, - i.e. the count of simultaneously working threads that remove the elements - of DHP-based concurrent data structure. Default value is 16. - */ - static void CDS_STDCALL Construct( - size_t nLiberateThreshold = 1024 - , size_t nInitialThreadGuardCount = 8 - , size_t nEpochCount = 16 - ); - - /// Destroys DHP memory manager - /** - The member function destroys DHP global object. After calling of this function you may \b NOT - use CDS data structures based on cds::gc::DHP. Usually, the \p Destruct function is called - at the end of your \p main(). See cds::gc::dhp for example. - */ - static void CDS_STDCALL Destruct(); - - /// Returns pointer to GarbageCollector instance - /** - If DHP GC is not initialized, \p not_initialized exception is thrown - */ - static GarbageCollector& instance() - { - if ( m_pManager == nullptr ) - throw not_initialized(); - return *m_pManager; - } - - /// Checks if global GC object is constructed and may be used - static bool isUsed() CDS_NOEXCEPT - { - return m_pManager != nullptr; - } - - public: - //@{ - /// Internal interface - - /// Allocates a guard - details::guard_data * allocGuard() - { - return m_GuardPool.alloc(); - } - - /// Frees guard \p g for reusing in future - void freeGuard(details::guard_data * pGuard ) - { - m_GuardPool.free( pGuard ); - } - - /// Allocates guard list for a thread. - details::guard_data* allocGuardList( size_t nCount ) - { - return m_GuardPool.allocList( nCount ); - } - - /// Frees thread's guard list pointed by \p pList - void freeGuardList( details::guard_data * pList ) - { - m_GuardPool.freeList( pList ); - } - - /// Places retired pointer \p and its deleter \p pFunc into thread's array of retired pointer for deferred reclamation - /**@anchor dhp_gc_retirePtr - */ - template - void retirePtr( T * p, void (* pFunc)(T *)) - { - retirePtr( retired_ptr( reinterpret_cast( p ), reinterpret_cast( pFunc ))); - } - - /// Places retired pointer \p into thread's array of retired pointer for deferred reclamation - void retirePtr( retired_ptr const& p ) - { - if ( m_RetiredBuffer.push( m_RetiredAllocator.alloc(p)) >= m_nLiberateThreshold.load(atomics::memory_order_relaxed)) - scan(); - } - - protected: - /// Liberate function - /** @anchor dhp_gc_liberate - The main function of Dynamic Hazard Pointer algorithm. It tries to free retired pointers if they are not - trapped by any guard. - */ - void scan(); - //@} - - public: - /// Get internal statistics - InternalState& getInternalState(InternalState& stat) const - { - return stat = m_stat; - } - - /// Checks if internal statistics enabled - bool isStatisticsEnabled() const - { - return m_bStatEnabled; - } - - /// Enables/disables internal statistics - bool enableStatistics( bool bEnable ) - { - bool bEnabled = m_bStatEnabled; - m_bStatEnabled = bEnable; - return bEnabled; - } - - private: - GarbageCollector( size_t nLiberateThreshold, size_t nInitialThreadGuardCount, size_t nEpochCount ); - ~GarbageCollector(); - }; - - /// Thread GC - /** - To use Dynamic Hazard Pointer reclamation schema each thread object must be linked with the object of ThreadGC class - that interacts with GarbageCollector global object. The linkage is performed by calling \ref cds_threading "cds::threading::Manager::attachThread()" - on the start of each thread that uses DHP GC. Before terminating the thread linked to DHP GC it is necessary to call - \ref cds_threading "cds::threading::Manager::detachThread()". - - The ThreadGC object maintains two list: - \li Thread guard list: the list of thread-local guards (linked by \p pThreadNext field) - \li Free guard list: the list of thread-local free guards (linked by \p pNextFree field) - Free guard list is a subset of thread guard list. - */ - class ThreadGC - { - GarbageCollector& m_gc; ///< reference to GC singleton - details::guard_data * m_pList; ///< Local list of guards owned by the thread - details::guard_data * m_pFree; ///< The list of free guard from m_pList - - public: - /// Default constructor - ThreadGC() - : m_gc( GarbageCollector::instance()) - , m_pList( nullptr ) - , m_pFree( nullptr ) - {} - - /// The object is not copy-constructible - ThreadGC( ThreadGC const& ) = delete; - - /// Dtor calls fini() - ~ThreadGC() - { - fini(); - } - - /// Initialization. Repeat call is available - void init() - { - if ( !m_pList ) { - m_pList = - m_pFree = m_gc.allocGuardList( m_gc.m_nInitialThreadGuardCount ); - } - } - - /// Finalization. Repeat call is available - void fini() - { - if ( m_pList ) { - m_gc.freeGuardList( m_pList ); - m_pList = - m_pFree = nullptr; - } - } - - public: - /// Allocates new guard - dhp::details::guard_data* allocGuard() - { - assert( m_pList != nullptr ); - - dhp::details::guard_data* ret; - if ( cds_likely( m_pFree )) { - ret = m_pFree; - m_pFree = m_pFree->pNextFree.load( atomics::memory_order_relaxed ); - } - else { - ret = m_gc.allocGuard(); - ret->pThreadNext = m_pList; - m_pList = ret; - } - return ret; - } - - /// Frees guard \p g - void freeGuard( dhp::details::guard_data* g ) - { - assert( m_pList != nullptr ); - if ( cds_likely( g )) { - g->pPost.store( nullptr, atomics::memory_order_relaxed ); - g->pNextFree.store( m_pFree, atomics::memory_order_relaxed ); - m_pFree = g; - } - } - - /// Guard array - template - using guard_array = dhp::details::guard_data* [Count]; - - /// Initializes guard array \p arr - template - void allocGuard( guard_array& arr ) - { - assert( m_pList != nullptr ); - size_t nCount = 0; - - while ( m_pFree && nCount < Count ) { - arr[nCount] = m_pFree; - m_pFree = m_pFree->pNextFree.load(atomics::memory_order_relaxed); - ++nCount; - } - - while ( nCount < Count ) { - dhp::details::guard_data*& g = arr[nCount]; - g = m_gc.allocGuard(); - g->pThreadNext = m_pList; - m_pList = g; - ++nCount; - } - } - - /// Frees guard array \p arr - template - void freeGuard( guard_array& arr ) - { - assert( m_pList != nullptr ); - - details::guard_data* first = nullptr; - details::guard_data* last; - for ( size_t i = 0; i < Count; ++i ) { - details::guard_data* guard = arr[i]; - if ( cds_likely( guard )) { - guard->pPost.store( nullptr, atomics::memory_order_relaxed ); - if ( first ) - last->pNextFree.store( guard, atomics::memory_order_relaxed ); - else - first = guard; - last = guard; - } - } - if ( first ) { - last->pNextFree.store( m_pFree, atomics::memory_order_relaxed ); - m_pFree = first; - } - } - - /// Places retired pointer \p and its deleter \p pFunc into list of retired pointer for deferred reclamation - template - void retirePtr( T * p, void (* pFunc)(T *)) - { - m_gc.retirePtr( p, pFunc ); - } - - /// Run retiring cycle - void scan() - { - m_gc.scan(); - } - }; - } // namespace dhp -}} // namespace cds::gc -//@endcond - -#if CDS_COMPILER == CDS_COMPILER_MSVC -# pragma warning(pop) -#endif - -#endif // #ifndef CDSLIB_GC_DETAILS_DHP_H diff --git a/cds/gc/details/hp.h b/cds/gc/details/hp.h deleted file mode 100644 index 21e83f79..00000000 --- a/cds/gc/details/hp.h +++ /dev/null @@ -1,680 +0,0 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef CDSLIB_GC_DETAILS_HP_H -#define CDSLIB_GC_DETAILS_HP_H - -#include -#include -#include -#include - -#include -#include - -#if CDS_COMPILER == CDS_COMPILER_MSVC -# pragma warning(push) - // warning C4251: 'cds::gc::hp::GarbageCollector::m_pListHead' : class 'cds::cxx11_atomic::atomic' - // needs to have dll-interface to be used by clients of class 'cds::gc::hp::GarbageCollector' -# pragma warning(disable: 4251) -#endif - -/* - Editions: - 2007.12.24 khizmax Add statistics and CDS_GATHER_HAZARDPTR_STAT macro - 2008.03.06 khizmax Refactoring: implementation of HazardPtrMgr is moved to hazardptr.cpp - 2008.03.08 khizmax Remove HazardPtrMgr singleton. Now you must initialize/destroy HazardPtrMgr calling - HazardPtrMgr::Construct / HazardPtrMgr::Destruct before use (usually in main() function). - 2008.12.06 khizmax Refactoring. Changes class name, namespace hierarchy, all helper defs have been moved to details namespace - 2010.01.27 khizmax Introducing memory order constraint -*/ - -//@cond -namespace cds { - /// Different safe memory reclamation schemas (garbage collectors) - /** @ingroup cds_garbage_collector - - This namespace specifies different safe memory reclamation (SMR) algorithms. - See \ref cds_garbage_collector "Garbage collectors" - */ - namespace gc { - - /// Michael's Hazard Pointers reclamation schema - /** - \par Sources: - - [2002] Maged M.Michael "Safe memory reclamation for dynamic lock-freeobjects using atomic reads and writes" - - [2003] Maged M.Michael "Hazard Pointers: Safe memory reclamation for lock-free objects" - - [2004] Andrei Alexandrescy, Maged Michael "Lock-free Data Structures with Hazard Pointers" - - The \p cds::gc::hp namespace and its members are internal representation of Hazard Pointer GC and should not be used directly. - Use \p cds::gc::HP class in your code. - - Hazard Pointer garbage collector is a singleton. The main user-level part of Hazard Pointer schema is - GC class and its nested classes. Before use any HP-related class you must initialize HP garbage collector - by contructing \p cds::gc::HP object in beginning of your \p main(). - See \p cds::gc::HP class for explanation. - */ - namespace hp { - - // forwards - class GarbageCollector; - class ThreadGC; - - namespace details { - - /// Retired pointer - typedef cds::gc::details::retired_ptr retired_ptr; - - /// Array of retired pointers - /** - The vector of retired pointer ready to delete. - - The Hazard Pointer schema is build on thread-static arrays. For each HP-enabled thread the HP manager allocates - array of retired pointers. The array belongs to the thread: owner thread writes to the array, other threads - just read it. - */ - class retired_vector { - /// Underlying vector implementation - typedef cds::details::bounded_array retired_vector_impl; - - retired_vector_impl m_arr ; ///< the array of retired pointers - size_t m_nSize ; ///< Current size of \p m_arr - - public: - /// Iterator - typedef retired_vector_impl::iterator iterator; - - /// Constructor - explicit retired_vector( const cds::gc::hp::GarbageCollector& HzpMgr ); // inline - ~retired_vector() - {} - - /// Vector capacity. - /** - The capacity is constant for any thread. It is defined by cds::gc::hp::GarbageCollector. - */ - size_t capacity() const CDS_NOEXCEPT - { - return m_arr.capacity(); - } - - /// Current vector size (count of retired pointers in the vector) - size_t size() const CDS_NOEXCEPT - { - return m_nSize; - } - - /// Set vector size. Uses internally - void size( size_t nSize ) - { - assert( nSize <= capacity()); - m_nSize = nSize; - } - - /// Pushes retired pointer to the vector - void push( retired_ptr const& p ) - { - assert( m_nSize < capacity()); - m_arr[ m_nSize ] = p; - ++m_nSize; - } - - /// Checks if the vector is full (size() == capacity()) - bool isFull() const CDS_NOEXCEPT - { - return m_nSize >= capacity(); - } - - /// Begin iterator - iterator begin() CDS_NOEXCEPT - { - return m_arr.begin(); - } - - /// End iterator - iterator end() CDS_NOEXCEPT - { - return m_arr.begin() + m_nSize; - } - - /// Clears the vector. After clearing, size() == 0 - void clear() CDS_NOEXCEPT - { - m_nSize = 0; - } - }; - - /// Hazard pointer record of the thread - /** - The structure of type "single writer - multiple reader": only the owner thread may write to this structure - other threads have read-only access. - */ - struct hp_record { - hp_allocator<> m_hzp; ///< array of hazard pointers. Implicit \ref CDS_DEFAULT_ALLOCATOR dependency - retired_vector m_arrRetired ; ///< Retired pointer array - - char padding[cds::c_nCacheLineSize]; - atomics::atomic m_nSync; ///< dummy var to introduce synchronizes-with relationship between threads - char padding2[cds::c_nCacheLineSize]; - - /// Ctor - explicit hp_record( const cds::gc::hp::GarbageCollector& HzpMgr ); // inline - ~hp_record() - {} - - /// Clears all hazard pointers - void clear() - { - m_hzp.clear(); - } - - void sync() - { - m_nSync.fetch_add( 1, atomics::memory_order_acq_rel ); - } - }; - } // namespace details - - /// GarbageCollector::Scan phase strategy - /** - See GarbageCollector::Scan for explanation - */ - enum scan_type { - classic, ///< classic scan as described in Michael's works (see GarbageCollector::classic_scan) - inplace ///< inplace scan without allocation (see GarbageCollector::inplace_scan) - }; - - /// Hazard Pointer singleton - /** - Safe memory reclamation schema by Michael "Hazard Pointers" - - \par Sources: - \li [2002] Maged M.Michael "Safe memory reclamation for dynamic lock-freeobjects using atomic reads and writes" - \li [2003] Maged M.Michael "Hazard Pointers: Safe memory reclamation for lock-free objects" - \li [2004] Andrei Alexandrescy, Maged Michael "Lock-free Data Structures with Hazard Pointers" - - */ - class CDS_EXPORT_API GarbageCollector - { - public: - typedef cds::atomicity::event_counter event_counter ; ///< event counter type - - /// Internal GC statistics - struct InternalState { - size_t nHPCount ; ///< HP count per thread (const) - size_t nMaxThreadCount ; ///< Max thread count (const) - size_t nMaxRetiredPtrCount ; ///< Max retired pointer count per thread (const) - size_t nHPRecSize ; ///< Size of HP record, bytes (const) - - size_t nHPRecAllocated ; ///< Count of HP record allocations - size_t nHPRecUsed ; ///< Count of HP record used - size_t nTotalRetiredPtrCount ; ///< Current total count of retired pointers - size_t nRetiredPtrInFreeHPRecs ; ///< Count of retired pointer in free (unused) HP records - - event_counter::value_type evcAllocHPRec ; ///< Count of \p hp_record allocations - event_counter::value_type evcRetireHPRec ; ///< Count of \p hp_record retire events - event_counter::value_type evcAllocNewHPRec; ///< Count of new \p hp_record allocations from heap - event_counter::value_type evcDeleteHPRec ; ///< Count of \p hp_record deletions - - event_counter::value_type evcScanCall ; ///< Count of Scan calling - event_counter::value_type evcHelpScanCall ; ///< Count of HelpScan calling - event_counter::value_type evcScanFromHelpScan;///< Count of Scan calls from HelpScan - - event_counter::value_type evcDeletedNode ; ///< Count of deleting of retired objects - event_counter::value_type evcDeferredNode ; ///< Count of objects that cannot be deleted in Scan phase because of a hazard_pointer guards it - }; - - /// No GarbageCollector object is created - class not_initialized : public std::runtime_error - { - public: - not_initialized() - : std::runtime_error( "Global Hazard Pointer GarbageCollector is not initialized" ) - {} - }; - - /// Not enough Hazard Pointer - class too_many_hazard_ptr : public std::length_error - { - public: - too_many_hazard_ptr() - : std::length_error( "Not enough Hazard Pointer" ) - {} - }; - - private: - /// Internal GC statistics - struct Statistics { - event_counter m_AllocHPRec ; ///< Count of \p hp_record allocations - event_counter m_RetireHPRec ; ///< Count of \p hp_record retire events - event_counter m_AllocNewHPRec ; ///< Count of new \p hp_record allocations from heap - event_counter m_DeleteHPRec ; ///< Count of \p hp_record deletions - - event_counter m_ScanCallCount ; ///< Count of Scan calling - event_counter m_HelpScanCallCount ; ///< Count of HelpScan calling - event_counter m_CallScanFromHelpScan ; ///< Count of Scan calls from HelpScan - - event_counter m_DeletedNode ; ///< Count of retired objects deleting - event_counter m_DeferredNode ; ///< Count of objects that cannot be deleted in Scan phase because of a hazard_pointer guards it - }; - - /// Internal list of cds::gc::hp::details::hp_record - struct hplist_node : public details::hp_record - { - atomics::atomic m_pNextNode; ///< next hazard ptr record in list - atomics::atomic m_idOwner; ///< Owner thread id; 0 - the record is free (not owned) - atomics::atomic m_bFree; ///< true if record is free (not owned) - - explicit hplist_node( const GarbageCollector& HzpMgr ) - : hp_record( HzpMgr ), - m_pNextNode( nullptr ), - m_idOwner( OS::c_NullThreadId ), - m_bFree( true ) - {} - - hplist_node( const GarbageCollector& HzpMgr, OS::ThreadId owner ) - : hp_record( HzpMgr ), - m_pNextNode( nullptr ), - m_idOwner( owner ), - m_bFree( false ) - {} - - ~hplist_node() - { - assert( m_idOwner.load( atomics::memory_order_relaxed ) == OS::c_NullThreadId ); - assert( m_bFree.load(atomics::memory_order_relaxed)); - } - }; - - atomics::atomic m_pListHead ; ///< Head of GC list - - static GarbageCollector * m_pHZPManager ; ///< GC instance pointer - - Statistics m_Stat ; ///< Internal statistics - bool m_bStatEnabled ; ///< true - statistics enabled - - const size_t m_nHazardPointerCount ; ///< max count of thread's hazard pointer - const size_t m_nMaxThreadCount ; ///< max count of thread - const size_t m_nMaxRetiredPtrCount ; ///< max count of retired ptr per thread - scan_type m_nScanType ; ///< scan type (see \ref scan_type enum) - - - private: - /// Ctor - GarbageCollector( - size_t nHazardPtrCount = 0, ///< Hazard pointer count per thread - size_t nMaxThreadCount = 0, ///< Max count of thread - size_t nMaxRetiredPtrCount = 0, ///< Capacity of the array of retired objects - scan_type nScanType = inplace ///< Scan type (see \ref scan_type enum) - ); - - /// Dtor - ~GarbageCollector(); - - /// Allocate new HP record - hplist_node * NewHPRec( OS::ThreadId owner ); - - /// Permanently deletes HPrecord \p pNode - /** - Caveat: for performance reason this function is defined as inline and cannot be called directly - */ - void DeleteHPRec( hplist_node * pNode ); - - void detachAllThread(); - - public: - /// Creates GarbageCollector singleton - /** - GC is the singleton. If GC instance is not exist then the function creates the instance. - Otherwise it does nothing. - - The Michael's HP reclamation schema depends of three parameters: - - \p nHazardPtrCount - HP pointer count per thread. Usually it is small number (2-4) depending from - the data structure algorithms. By default, if \p nHazardPtrCount = 0, - the function uses maximum of HP count for CDS library. - - \p nMaxThreadCount - max count of thread with using HP GC in your application. Default is 100. - - \p nMaxRetiredPtrCount - capacity of array of retired pointers for each thread. Must be greater than - \p nHazardPtrCount * \p nMaxThreadCount. - Default is 2 * \p nHazardPtrCount * \p nMaxThreadCount. - */ - static void CDS_STDCALL Construct( - size_t nHazardPtrCount = 0, ///< Hazard pointer count per thread - size_t nMaxThreadCount = 0, ///< Max count of simultaneous working thread in your application - size_t nMaxRetiredPtrCount = 0, ///< Capacity of the array of retired objects for the thread - scan_type nScanType = inplace ///< Scan type (see \ref scan_type enum) - ); - - /// Destroys global instance of GarbageCollector - /** - The parameter \p bDetachAll should be used carefully: if its value is \p true, - then the destroying GC automatically detaches all attached threads. This feature - can be useful when you have no control over the thread termination, for example, - when \p libcds is injected into existing external thread. - */ - static void CDS_STDCALL Destruct( - bool bDetachAll = false ///< Detach all threads - ); - - /// Returns pointer to GarbageCollector instance - static GarbageCollector& instance() - { - if ( !m_pHZPManager ) - throw not_initialized(); - return *m_pHZPManager; - } - - /// Checks if global GC object is constructed and may be used - static bool isUsed() CDS_NOEXCEPT - { - return m_pHZPManager != nullptr; - } - - /// Returns max Hazard Pointer count defined in construction time - size_t getHazardPointerCount() const CDS_NOEXCEPT - { - return m_nHazardPointerCount; - } - - /// Returns max thread count defined in construction time - size_t getMaxThreadCount() const CDS_NOEXCEPT - { - return m_nMaxThreadCount; - } - - /// Returns max size of retired objects array. It is defined in construction time - size_t getMaxRetiredPtrCount() const CDS_NOEXCEPT - { - return m_nMaxRetiredPtrCount; - } - - // Internal statistics - - /// Get internal statistics - InternalState& getInternalState(InternalState& stat) const; - - /// Checks if internal statistics enabled - bool isStatisticsEnabled() const { return m_bStatEnabled; } - - /// Enables/disables internal statistics - bool enableStatistics( bool bEnable ) - { - bool bEnabled = m_bStatEnabled; - m_bStatEnabled = bEnable; - return bEnabled; - } - - /// Checks that required hazard pointer count \p nRequiredCount is less or equal then max hazard pointer count - /** - If \p nRequiredCount > getHazardPointerCount() then the exception \p too_many_hazard_ptr is thrown - */ - static void checkHPCount( unsigned int nRequiredCount ) - { - if ( instance().getHazardPointerCount() < nRequiredCount ) - throw too_many_hazard_ptr(); - } - - /// Get current scan strategy - scan_type getScanType() const - { - return m_nScanType; - } - - /// Set current scan strategy - /** @anchor hzp_gc_setScanType - Scan strategy changing is allowed on the fly. - */ - void setScanType( - scan_type nScanType ///< new scan strategy - ) - { - m_nScanType = nScanType; - } - - public: // Internals for threads - - /// Allocates Hazard Pointer GC record. For internal use only - details::hp_record* alloc_hp_record(); - - /// Free HP record. For internal use only - void free_hp_record( details::hp_record* pRec ); - - /// The main garbage collecting function - /** - This function is called internally by ThreadGC object when upper bound of thread's list of reclaimed pointers - is reached. - - There are the following scan algorithm: - - \ref hzp_gc_classic_scan "classic_scan" allocates memory for internal use - - \ref hzp_gc_inplace_scan "inplace_scan" does not allocate any memory - - Use \ref hzp_gc_setScanType "setScanType" member function to setup appropriate scan algorithm. - */ - void Scan( details::hp_record * pRec ) - { - switch ( m_nScanType ) { - case inplace: - inplace_scan( pRec ); - break; - default: - assert(false) ; // Forgotten something?.. - case classic: - classic_scan( pRec ); - break; - } - } - - /// Helper scan routine - /** - The function guarantees that every node that is eligible for reuse is eventually freed, barring - thread failures. To do so, after executing Scan, a thread executes a HelpScan, - where it checks every HP record. If an HP record is inactive, the thread moves all "lost" reclaimed pointers - to thread's list of reclaimed pointers. - - The function is called internally by Scan. - */ - void HelpScan( details::hp_record * pThis ); - - protected: - /// Classic scan algorithm - /** @anchor hzp_gc_classic_scan - Classical scan algorithm as described in Michael's paper. - - A scan includes four stages. The first stage involves scanning the array HP for non-null values. - Whenever a non-null value is encountered, it is inserted in a local list of currently protected pointer. - Only stage 1 accesses shared variables. The following stages operate only on private variables. - - The second stage of a scan involves sorting local list of protected pointers to allow - binary search in the third stage. - - The third stage of a scan involves checking each reclaimed node - against the pointers in local list of protected pointers. If the binary search yields - no match, the node is freed. Otherwise, it cannot be deleted now and must kept in thread's list - of reclaimed pointers. - - The forth stage prepares new thread's private list of reclaimed pointers - that could not be freed during the current scan, where they remain until the next scan. - - This algorithm allocates memory for internal HP array. - - This function is called internally by ThreadGC object when upper bound of thread's list of reclaimed pointers - is reached. - */ - void classic_scan( details::hp_record * pRec ); - - /// In-place scan algorithm - /** @anchor hzp_gc_inplace_scan - Unlike the \ref hzp_gc_classic_scan "classic_scan" algorithm, \p inplace_scan does not allocate any memory. - All operations are performed in-place. - */ - void inplace_scan( details::hp_record * pRec ); - }; - - /// Thread's hazard pointer manager - /** - To use Hazard Pointer reclamation schema each thread object must be linked with the object of ThreadGC class - that interacts with GarbageCollector global object. The linkage is performed by calling \ref cds_threading "cds::threading::Manager::attachThread()" - on the start of each thread that uses HP GC. Before terminating the thread linked to HP GC it is necessary to call - \ref cds_threading "cds::threading::Manager::detachThread()". - */ - class ThreadGC - { - GarbageCollector& m_HzpManager; ///< Hazard Pointer GC singleton - details::hp_record* m_pHzpRec; ///< Pointer to thread's HZP record - - public: - /// Default constructor - ThreadGC() - : m_HzpManager( GarbageCollector::instance()), - m_pHzpRec( nullptr ) - {} - - /// The object is not copy-constructible - ThreadGC( ThreadGC const& ) = delete; - - ~ThreadGC() - { - fini(); - } - - /// Checks if thread GC is initialized - bool isInitialized() const { return m_pHzpRec != nullptr; } - - /// Initialization. Repeat call is available - void init() - { - if ( !m_pHzpRec ) - m_pHzpRec = m_HzpManager.alloc_hp_record(); - } - - /// Finalization. Repeat call is available - void fini() - { - if ( m_pHzpRec ) { - details::hp_record* pRec = m_pHzpRec; - m_pHzpRec = nullptr; - m_HzpManager.free_hp_record( pRec ); - } - } - - /// Initializes HP guard \p guard - details::hp_guard* allocGuard() - { - assert( m_pHzpRec ); - return m_pHzpRec->m_hzp.alloc(); - } - - /// Frees HP guard \p guard - void freeGuard( details::hp_guard* guard ) - { - assert( m_pHzpRec ); - m_pHzpRec->m_hzp.free( guard ); - } - - /// Initializes HP guard array \p arr - template - size_t allocGuard( details::hp_array& arr ) - { - assert( m_pHzpRec ); - return m_pHzpRec->m_hzp.alloc( arr ); - } - - /// Frees HP guard array \p arr - template - void freeGuard( details::hp_array& arr ) - { - assert( m_pHzpRec ); - m_pHzpRec->m_hzp.free( arr ); - } - - /// Places retired pointer \p and its deleter \p pFunc into thread's array of retired pointer for deferred reclamation - template - void retirePtr( T * p, void (* pFunc)(T *)) - { - retirePtr( details::retired_ptr( reinterpret_cast( p ), reinterpret_cast( pFunc ))); - } - - /// Places retired pointer \p into thread's array of retired pointer for deferred reclamation - void retirePtr( details::retired_ptr const& p ) - { - m_pHzpRec->m_arrRetired.push( p ); - - if ( m_pHzpRec->m_arrRetired.isFull()) { - // Max of retired pointer count is reached. Do scan - scan(); - } - } - - /// Run retiring scan cycle - void scan() - { - m_HzpManager.Scan( m_pHzpRec ); - m_HzpManager.HelpScan( m_pHzpRec ); - } - - void sync() - { - assert( m_pHzpRec != nullptr ); - m_pHzpRec->sync(); - } - }; - - } // namespace hp -}} // namespace cds::gc -//@endcond - -//@cond -// Inlines -namespace cds { - namespace gc { namespace hp { namespace details { - - inline retired_vector::retired_vector( const cds::gc::hp::GarbageCollector& HzpMgr ) - : m_arr( HzpMgr.getMaxRetiredPtrCount()), - m_nSize(0) - {} - - inline hp_record::hp_record( const cds::gc::hp::GarbageCollector& HzpMgr ) - : m_hzp( HzpMgr.getHazardPointerCount()) - , m_arrRetired( HzpMgr ) - , m_nSync( 0 ) - {} - - }}} // namespace gc::hp::details -} // namespace cds -//@endcond - - -#if CDS_COMPILER == CDS_COMPILER_MSVC -# pragma warning(pop) -#endif - -#endif // #ifndef CDSLIB_GC_DETAILS_HP_H diff --git a/cds/gc/details/hp_alloc.h b/cds/gc/details/hp_alloc.h deleted file mode 100644 index 978a342f..00000000 --- a/cds/gc/details/hp_alloc.h +++ /dev/null @@ -1,373 +0,0 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef CDSLIB_GC_DETAILS_HP_ALLOC_H -#define CDSLIB_GC_DETAILS_HP_ALLOC_H - -#include -#include -#include -#include // memset - -//@cond -namespace cds { - namespace gc { namespace hp { - // forwards - class GarbageCollector; - class ThreadGC; - - /// Hazard Pointer schema implementation details - namespace details { - - /// Hazard pointer guard - /** - It is unsafe to use this class directly. - Instead, the \p hp::guard class should be used. - */ - class hp_guard : protected atomics::atomic < hazard_pointer > - { - template friend class hp_allocator; - - public: - typedef hazard_pointer hazard_ptr;///< Hazard pointer type - - private: - typedef atomics::atomic atomic_hazard_ptr; - - atomic_hazard_ptr m_hp; - hp_guard* m_next; // next free guard - - public: - hp_guard() CDS_NOEXCEPT - : m_hp( nullptr ) - , m_next( nullptr ) - {} - - ~hp_guard() CDS_NOEXCEPT - {} - - /// Sets HP value. Guards pointer \p p from reclamation. - /** - Storing has release semantics. - */ - template - T * operator =(T * p) CDS_NOEXCEPT - { - // We use atomic store with explicit memory order because other threads may read this hazard pointer concurrently - set( p ); - return p; - } - - std::nullptr_t operator=(std::nullptr_t) CDS_NOEXCEPT - { - clear(); - return nullptr; - } - - /// Returns current value of hazard pointer - /** - Loading has acquire semantics - */ - hazard_ptr get( atomics::memory_order order = atomics::memory_order_acquire ) const CDS_NOEXCEPT - { - return m_hp.load( order ); - } - - template - void set( T * p, atomics::memory_order order = atomics::memory_order_release ) CDS_NOEXCEPT - { - m_hp.store( reinterpret_cast(p), order ); - } - - /// Clears HP - /** - Clearing has relaxed semantics. - */ - void clear( atomics::memory_order order = atomics::memory_order_release ) CDS_NOEXCEPT - { - // memory order is not necessary here - m_hp.store( nullptr, order ); - } - }; - - /// Array of hazard pointers. - /** - Array of hazard-pointer. Placing a pointer into this array guards the pointer against reclamation. - Template parameter \p Count defines the size of hazard pointer array. \p Count parameter should not exceed - GarbageCollector::getHazardPointerCount(). - - It is unsafe to use this class directly. Instead, the \p hp::array should be used. - - While creating the object of \p hp_array class an array of size \p Count of hazard pointers is reserved by - the HP Manager of current thread. The object's destructor cleans all of reserved hazard pointer and - returns reserved HP to the HP pool of ThreadGC. - - Usually, it is not necessary to create an object of this class. The object of class ThreadGC contains - the \p hp_array object and implements interface for HP setting and freeing. - - Template parameter: - \li Count - capacity of array - */ - template - class hp_array - { - template friend class hp_allocator; - - public: - typedef hazard_pointer hazard_ptr; ///< Hazard pointer type - static CDS_CONSTEXPR const size_t c_nCapacity = Count ; ///< Capacity of the array - - public: - /// Constructs uninitialized array. - hp_array() CDS_NOEXCEPT - { - memset( m_arr, 0, sizeof( m_arr )); - } - - /// Destructs object - ~hp_array() CDS_NOEXCEPT - {} - - /// Returns max count of hazard pointer for this array - CDS_CONSTEXPR size_t capacity() const - { - return c_nCapacity; - } - - /// Set hazard pointer \p nIndex. 0 <= \p nIndex < \p Count - void set( size_t nIndex, hazard_ptr hptr ) CDS_NOEXCEPT - { - assert( nIndex < capacity()); - assert( m_arr[nIndex] != nullptr ); - - *m_arr[nIndex] = hptr; - } - - /// Returns pointer to hazard pointer of index \p nIndex (0 <= \p nIndex < \p Count) - hp_guard* operator []( size_t nIndex ) CDS_NOEXCEPT - { - assert( nIndex < capacity()); - return m_arr[nIndex]; - } - - /// Returns pointer to hazard pointer of index \p nIndex (0 <= \p nIndex < \p Count) [const version] - hp_guard* operator []( size_t nIndex ) const CDS_NOEXCEPT - { - assert( nIndex < capacity()); - return m_arr[nIndex]; - } - - /// Clears (sets to \p nullptr) hazard pointer \p nIndex - void clear( size_t nIndex ) CDS_NOEXCEPT - { - assert( nIndex < capacity()); - assert( m_arr[nIndex] != nullptr ); - - m_arr[ nIndex ]->clear(); - } - - hp_guard* release( size_t nIndex ) CDS_NOEXCEPT - { - assert( nIndex < capacity()); - - hp_guard* p = m_arr[ nIndex ]; - m_arr[ nIndex ] = nullptr; - return p; - } - - - private: - hp_guard* m_arr[c_nCapacity]; ///< Hazard pointer array of size = \p Count - }; - - /// Allocator of hazard pointers for the thread - /** - The hazard pointer array is the free-list of unused hazard pointer for the thread. - The array is managed as a stack. - The max size (capacity) of array is defined at ctor time and cannot be changed during object's lifetime - - Each allocator object is thread-private. - - Template parameters: - \li Allocator - memory allocator class, default is \ref CDS_DEFAULT_ALLOCATOR - - This helper class should not be used directly. - */ - template - class hp_allocator - { - public: - typedef hazard_pointer hazard_ptr; ///< type of hazard pointer - typedef Allocator allocator_type; ///< allocator type - - private: - typedef cds::details::Allocator< hp_guard, allocator_type > allocator_impl; - - hp_guard* m_arrHazardPtr; ///< Array of hazard pointers - hp_guard* m_FreeListHead; ///< List of free hp guards - size_t const m_nCapacity; ///< Array capacity - - public: - /// Default ctor - explicit hp_allocator( - size_t nCapacity ///< max count of hazard pointer per thread - ) - : m_arrHazardPtr( alloc_array( nCapacity )) - , m_FreeListHead( m_arrHazardPtr ) - , m_nCapacity( nCapacity ) - { - build_free_list(); - } - - /// Dtor - ~hp_allocator() - { - allocator_impl().Delete( m_arrHazardPtr, capacity()); - } - - /// Get capacity of array - size_t capacity() const CDS_NOEXCEPT - { - return m_nCapacity; - } - - /// Get size of array. The size is equal to the capacity of array - size_t size() const CDS_NOEXCEPT - { - return capacity(); - } - - /// Checks if all items are allocated - bool full() const CDS_NOEXCEPT - { - return m_FreeListHead == nullptr; - } - - /// Allocates hazard pointer - hp_guard* alloc() - { - assert( !full()); - - hp_guard* p = m_FreeListHead; - m_FreeListHead = m_FreeListHead->m_next; - return p; - } - - /// Frees previously allocated hazard pointer - void free( hp_guard* hp ) CDS_NOEXCEPT - { - if ( hp ) { - hp->clear(); - hp->m_next = m_FreeListHead; - m_FreeListHead = hp; - } - } - - /// Allocates hazard pointers array - /** - Allocates \p Count hazard pointers from array \p m_arrHazardPtr - Initializes \p arr with hazard pointers. - - @return actual size of allocated array. - */ - template - size_t alloc( hp_array& arr ) - { - size_t i; - hp_guard* p = m_FreeListHead; - for ( i = 0; i < Count && p; ++i ) { - arr.m_arr[i] = p; - p = p->m_next; - } - size_t ret = i; - for ( ; i < Count; ++i ) - arr.m_arr[i] = nullptr; - m_FreeListHead = p; - return ret; - } - - /// Frees hazard pointer array - /** - Frees the array of hazard pointers allocated by previous call \p this->alloc. - */ - template - void free( hp_array const& arr ) CDS_NOEXCEPT - { - hp_guard* pList = m_FreeListHead; - for ( size_t i = 0; i < Count; ++i ) { - hp_guard* p = arr[i]; - if ( p ) { - p->clear(); - p->m_next = pList; - pList = p; - } - } - m_FreeListHead = pList; - } - - /// Makes all HP free - void clear() CDS_NOEXCEPT - { - for ( size_t i = 0; i < capacity(); ++i ) - m_arrHazardPtr[i].clear(); - } - - /// Returns i-th hazard pointer - hp_guard& operator []( size_t i ) CDS_NOEXCEPT - { - assert( i < capacity()); - return m_arrHazardPtr[i]; - } - - private: - hp_guard* alloc_array( size_t nCapacity ) - { - return allocator_impl().NewArray( nCapacity ); - } - - void build_free_list() - { - hp_guard* first = m_arrHazardPtr; - hp_guard* last = m_arrHazardPtr + capacity(); - hp_guard* prev = first; - for ( ++first; first < last; ++first ) { - prev->m_next = first; - prev = first; - } - prev->m_next = nullptr; - m_FreeListHead = m_arrHazardPtr; - } - }; - - }}} // namespace gc::hp::details -} // namespace cds -//@endcond - -#endif // #ifndef CDSLIB_GC_DETAILS_HP_ALLOC_H diff --git a/cds/gc/details/hp_common.h b/cds/gc/details/hp_common.h new file mode 100644 index 00000000..bfdccefa --- /dev/null +++ b/cds/gc/details/hp_common.h @@ -0,0 +1,184 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CDSLIB_GC_DETAILS_HP_COMMON_H +#define CDSLIB_GC_DETAILS_HP_COMMON_H + +#include +#include + +#ifdef CDS_ENABLE_HPSTAT +# define CDS_HPSTAT( expr ) expr +#else +# define CDS_HPSTAT( expr ) +#endif + +//@cond +namespace cds { namespace gc { namespace hp { namespace common { + + /// Hazard pointer type + typedef void* hazard_ptr; + + /// Retired pointer + using cds::gc::details::retired_ptr; + using cds::gc::make_retired_ptr; + + /// Hazard pointer guard + class guard + { + public: + guard() noexcept + : hp_( nullptr ) + , next_( nullptr ) + {} + + template + T* operator=( T* ptr ) noexcept + { + set( ptr ); + return ptr; + } + + std::nullptr_t operator=( std::nullptr_t ) noexcept + { + clear(); + return nullptr; + } + + hazard_ptr get() const noexcept + { + return hp_.load( atomics::memory_order_acquire ); + } + + hazard_ptr get( atomics::memory_order order ) const noexcept + { + return hp_.load( order ); + } + + template + T* get_as() const noexcept + { + return reinterpret_cast( get() ); + } + + template + void set( T* ptr ) noexcept + { + hp_.store( reinterpret_cast( ptr ), atomics::memory_order_release ); + } + + void clear( atomics::memory_order order ) noexcept + { + hp_.store( nullptr, order ); + } + + void clear() noexcept + { + clear( atomics::memory_order_release ); + } + + private: + atomics::atomic hp_; + + public: + guard* next_; // free guard list + }; + + /// Array of guards + template + class guard_array + { + public: + static size_t const c_nCapacity = Capacity; + + public: + guard_array() + : arr_{ nullptr } + {} + + constexpr size_t capacity() const + { + return c_nCapacity; + } + + guard* operator[]( size_t idx ) const noexcept + { + assert( idx < capacity() ); + return arr_[idx]; + } + + template + void set( size_t idx, T* ptr ) noexcept + { + assert( idx < capacity()); + assert( arr_[idx] != nullptr ); + + arr_[idx]->set( ptr ); + } + + void clear( size_t idx ) noexcept + { + assert( idx < capacity() ); + assert( arr_[idx] != nullptr ); + + arr_[idx]->clear(); + } + + guard* release( size_t idx ) noexcept + { + assert( idx < capacity() ); + + guard* g = arr_[idx]; + arr_[idx] = nullptr; + return g; + } + + void reset( size_t idx, guard* g ) noexcept + { + assert( idx < capacity() ); + assert( arr_[idx] == nullptr ); + + arr_[idx] = g; + } + + private: + guard* arr_[c_nCapacity]; + }; + + + /// Retired pointer disposer + typedef void ( *disposer_func )( void* ); + +}}}} // namespace cds::gc::hp::common +//@endcond + +#endif // #ifndef CDSLIB_GC_DETAILS_HP_COMMON_H + + diff --git a/cds/gc/details/hp_type.h b/cds/gc/details/hp_type.h deleted file mode 100644 index 03da8adf..00000000 --- a/cds/gc/details/hp_type.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef CDSLIB_GC_DETAILS_HP_TYPE_H -#define CDSLIB_GC_DETAILS_HP_TYPE_H - -#include // free_retired_ptr_func - -//@cond -namespace cds { - namespace gc { - namespace hp { - - /// Hazard pointer - typedef void * hazard_pointer; - - /// Pointer to function to free (destruct and deallocate) retired pointer of specific type - typedef cds::gc::details::free_retired_ptr_func free_retired_ptr_func; - } - } -} -//@endcond - -#endif // #ifndef CDSLIB_GC_DETAILS_HP_TYPE_H - - diff --git a/cds/gc/dhp.h b/cds/gc/dhp.h index d29a4b8b..02a6d911 100644 --- a/cds/gc/dhp.h +++ b/cds/gc/dhp.h @@ -31,8 +31,8 @@ #ifndef CDSLIB_GC_DHP_H #define CDSLIB_GC_DHP_H -#include -#include +#include #include +#include #endif // #ifndef CDSLIB_GC_DHP_H diff --git a/cds/gc/dhp_smr.h b/cds/gc/dhp_smr.h new file mode 100644 index 00000000..92d9b53d --- /dev/null +++ b/cds/gc/dhp_smr.h @@ -0,0 +1,1355 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CDSLIB_GC_DHP_SMR_H +#define CDSLIB_GC_DHP_SMR_H + +#include +#include +#include +#include +#include +#include +#include + +namespace cds { namespace gc { + namespace dhp { + using namespace cds::gc::hp::common; + + /// Exception "Dynamic Hazard Pointer SMR is not initialized" + class not_initialized: public std::runtime_error + { + public: + not_initialized() + : std::runtime_error( "Global DHP SMR object is not initialized" ) + {} + }; + + struct guard_block: public cds::intrusive::FreeListImpl::node + { + guard_block* next_; // next block in the thread list + + guard_block() + : next_( nullptr ) + {} + + guard* first() + { + return reinterpret_cast( this + 1 ); + } + }; + + /// \p guard_block allocator (global object) + class hp_allocator + { + friend class smr; + public: + static hp_allocator& instance(); + + CDS_EXPORT_API guard_block* alloc(); + void free( guard_block* block ) + { + free_list_.put( block ); + } + + private: + hp_allocator() + {} + CDS_EXPORT_API ~hp_allocator(); + + private: + cds::intrusive::FreeListImpl free_list_; ///< list of free \p guard_block + }; + + /// Per-thread hazard pointer storage + class thread_hp_storage + { + friend class smr; + public: + thread_hp_storage( guard* arr, size_t nSize ) CDS_NOEXCEPT + : free_head_( arr ) + , extended_list_( nullptr ) + , array_( arr ) + , initial_capacity_( nSize ) + {} + + thread_hp_storage() = delete; + thread_hp_storage( thread_hp_storage const& ) = delete; + thread_hp_storage( thread_hp_storage&& ) = delete; + + ~thread_hp_storage() + { + clear(); + } + + guard* alloc() + { + if ( cds_unlikely( free_head_ == nullptr )) { + extend(); + assert( free_head_ != nullptr ); + } + + guard* g = free_head_; + free_head_ = g->next_; + return g; + } + + void free( guard* g ) CDS_NOEXCEPT + { + if ( g ) { + g->clear(); + g->next_ = free_head_; + free_head_ = g; + } + } + + template< size_t Capacity> + size_t alloc( guard_array& arr ) + { + for ( size_t i = 0; i < Capacity; ++i ) { + if ( cds_unlikely( free_head_ == nullptr )) + extend(); + arr.reset( i, free_head_ ); + free_head_ = free_head_->next_; + } + return Capacity; + } + + template + void free( guard_array& arr ) CDS_NOEXCEPT + { + guard* gList = free_head_; + for ( size_t i = 0; i < Capacity; ++i ) { + guard* g = arr[i]; + if ( g ) { + g->clear(); + g->next_ = gList; + gList = g; + } + } + free_head_ = gList; + } + + void clear() + { + // clear array_ + for ( guard* cur = array_, *last = array_ + initial_capacity_; cur < last; ++cur ) + cur->clear(); + + // free all extended blocks + hp_allocator& alloc = hp_allocator::instance(); + for ( guard_block* p = extended_list_; p; ) { + guard_block* next = p->next_; + alloc.free( p ); + p = next; + } + + extended_list_ = nullptr; + } + + void init() + { + assert( extended_list_ == nullptr ); + + guard* p = array_; + for ( guard* pEnd = p + initial_capacity_ - 1; p != pEnd; ++p ) + p->next_ = p + 1; + p->next_ = nullptr; + free_head_ = array_; + } + + private: + void extend() + { + assert( free_head_ == nullptr ); + + guard_block* block = hp_allocator::instance().alloc(); + block->next_ = extended_list_; + extended_list_ = block; + free_head_ = block->first(); + } + + private: + guard* free_head_; ///< Head of free guard list + guard_block* extended_list_; ///< Head of extended guard blocks allocated for the thread + guard* const array_; ///< initial HP array + size_t const initial_capacity_; ///< Capacity of \p array_ + }; + + struct retired_block: public cds::intrusive::FreeListImpl::node + { + retired_block* next_; ///< Next block in thread-private retired array + + static size_t const c_capacity = 256; + + retired_block() + : next_( nullptr ) + {} + + retired_ptr* first() + { + return reinterpret_cast( this + 1 ); + } + + retired_ptr* last() + { + return first() + c_capacity; + } + }; + + class retired_allocator + { + friend class smr; + public: + static retired_allocator& instance(); + + CDS_EXPORT_API retired_block* alloc(); + void free( retired_block* block ) + { + block->next_ = nullptr; + free_list_.put( block ); + } + + private: + retired_allocator() + {} + CDS_EXPORT_API ~retired_allocator(); + + private: + cds::intrusive::FreeListImpl free_list_; ///< list of free \p guard_block + }; + + /// Per-thread retired array + class retired_array + { + friend class smr; + public: + retired_array() CDS_NOEXCEPT + : current_block_( nullptr ) + , current_cell_( nullptr ) + , list_head_( nullptr ) + , list_tail_( nullptr ) + , block_count_(0) + {} + + retired_array( retired_array const& ) = delete; + retired_array( retired_array&& ) = delete; + + ~retired_array() + { + assert( empty()); + fini(); + } + + bool push( retired_ptr const& p ) CDS_NOEXCEPT + { + assert( current_block_ != nullptr ); + assert( current_block_->first() <= current_cell_ ); + assert( current_cell_ < current_block_->last() ); + //assert( &p != current_cell_ ); + + *current_cell_ = p; + if ( ++current_cell_ == current_block_->last() ) { + // goto next block if exists + if ( current_block_->next_ ) { + current_block_ = current_block_->next_; + current_cell_ = current_block_->first(); + return true; + } + + // no free block + // smr::scan() extend retired_array if needed + return false; + } + + return true; + } + + bool safe_push( retired_ptr* p ) CDS_NOEXCEPT + { + bool ret = push( *p ); + assert( ret ); + return ret; + } + + private: // called by smr + void init() + { + if ( list_head_ == nullptr ) { + retired_block* block = retired_allocator::instance().alloc(); + assert( block->next_ == nullptr ); + + current_block_ = + list_head_ = + list_tail_ = block; + current_cell_ = block->first(); + + block_count_ = 1; + } + } + + void fini() + { + retired_allocator& alloc = retired_allocator::instance(); + for ( retired_block* p = list_head_; p; ) { + retired_block* next = p->next_; + alloc.free( p ); + p = next; + } + + current_block_ = + list_head_ = + list_tail_ = nullptr; + current_cell_ = nullptr; + + block_count_ = 0; + } + + void extend() + { + assert( list_head_ != nullptr ); + assert( current_block_ == list_tail_ ); + assert( current_cell_ == current_block_->last() ); + + retired_block* block = retired_allocator::instance().alloc(); + assert( block->next_ == nullptr ); + + list_tail_ = list_tail_->next_ = block; + current_cell_ = block->first(); + ++block_count_; + } + + bool empty() const + { + return current_block_ == nullptr + || ( current_block_ == list_head_ && current_cell_ == current_block_->first()); + } + + private: + retired_block* current_block_; + retired_ptr* current_cell_; // in current_block_ + + retired_block* list_head_; + retired_block* list_tail_; + size_t block_count_; + }; + + /// Per-thread data + struct thread_data { + thread_hp_storage hazards_; ///< Hazard pointers private to the thread + retired_array retired_; ///< Retired data private to the thread + + char pad1_[cds::c_nCacheLineSize]; + atomics::atomic sync_; ///< dummy var to introduce synchronizes-with relationship between threads + char pad2_[cds::c_nCacheLineSize]; + + thread_data( guard* guards, size_t guard_count ) + : hazards_( guards, guard_count ) + , sync_( 0 ) + {} + + thread_data() = delete; + thread_data( thread_data const& ) = delete; + thread_data( thread_data&& ) = delete; + + void sync() + { + sync_.fetch_add( 1, atomics::memory_order_acq_rel ); + } + }; + + // Hazard Pointer SMR (Safe Memory Reclamation) + class smr + { + struct thread_record; + + public: + /// Returns the instance of Hazard Pointer \ref smr + static smr& instance() + { +# ifdef CDS_DISABLE_SMR_EXCEPTION + assert( instance_ != nullptr ); +# else + if ( !instance_ ) + CDS_THROW_EXCEPTION( not_initialized() ); +# endif + return *instance_; + } + + /// Creates Dynamic Hazard Pointer SMR singleton + /** + Dynamic Hazard Pointer SMR is a singleton. If DHP instance is not initialized then the function creates the instance. + Otherwise it does nothing. + + The Michael's HP reclamation schema depends of three parameters: + - \p nHazardPtrCount - HP pointer count per thread. Usually it is small number (2-4) depending from + the data structure algorithms. By default, if \p nHazardPtrCount = 0, + the function uses maximum of HP count for CDS library + - \p nMaxThreadCount - max count of thread with using HP GC in your application. Default is 100. + - \p nMaxRetiredPtrCount - capacity of array of retired pointers for each thread. Must be greater than + nHazardPtrCount * nMaxThreadCount + Default is 2 * nHazardPtrCount * nMaxThreadCount + */ + static CDS_EXPORT_API void construct( + size_t nInitialHazardPtrCount = 16 ///< Initial number of hazard pointer per thread + ); + + //@cond + // for back-copatibility + static void Construct( + size_t nInitialHazardPtrCount = 16 ///< Initial number of hazard pointer per thread + ) + { + construct( nInitialHazardPtrCount ); + } + //@endcond + + /// Destroys global instance of \ref smr + /** + The parameter \p bDetachAll should be used carefully: if its value is \p true, + then the object destroyed automatically detaches all attached threads. This feature + can be useful when you have no control over the thread termination, for example, + when \p libcds is injected into existing external thread. + */ + static CDS_EXPORT_API void destruct( + bool bDetachAll = false ///< Detach all threads + ); + + //@cond + // for back-copatibility + static void Destruct( + bool bDetachAll = false ///< Detach all threads + ) + { + destruct( bDetachAll ); + } + //@endcond + + /// Checks if global SMR object is constructed and may be used + static bool isUsed() CDS_NOEXCEPT + { + return instance_ != nullptr; + } + + /// Set memory management functions + /** + @note This function may be called BEFORE creating an instance + of Dynamic Hazard Pointer SMR + + SMR object allocates some memory for thread-specific data and for + creating SMR object. + By default, a standard \p new and \p delete operators are used for this. + */ + static CDS_EXPORT_API void set_memory_allocator( + void* ( *alloc_func )( size_t size ), + void( *free_func )( void * p ) + ); + + /// Returns thread-local data for the current thread + static CDS_EXPORT_API thread_data* tls(); + + static CDS_EXPORT_API void attach_thread(); + static CDS_EXPORT_API void detach_thread(); + + public: // for internal use only + /// The main garbage collecting function + CDS_EXPORT_API void scan( thread_data* pRec ); + + /// Helper scan routine + /** + The function guarantees that every node that is eligible for reuse is eventually freed, barring + thread failures. To do so, after executing \p scan(), a thread executes a \p %help_scan(), + where it checks every HP record. If an HP record is inactive, the thread moves all "lost" reclaimed pointers + to thread's list of reclaimed pointers. + + The function is called internally by \p scan(). + */ + CDS_EXPORT_API void help_scan( thread_data* pThis ); + + hp_allocator& get_hp_allocator() + { + return hp_allocator_; + } + + retired_allocator& get_retired_allocator() + { + return retired_allocator_; + } + + private: + CDS_EXPORT_API smr( + size_t nInitialHazardPtrCount + ); + + CDS_EXPORT_API ~smr(); + + CDS_EXPORT_API void detach_all_thread(); + + private: + //@cond + CDS_EXPORT_API thread_record* create_thread_data(); + CDS_EXPORT_API void destroy_thread_data( thread_record* pRec ); + + /// Allocates Hazard Pointer SMR thread private data + CDS_EXPORT_API thread_record* alloc_thread_data(); + + /// Free HP SMR thread-private data + CDS_EXPORT_API void free_thread_data( thread_record* pRec ); + //@endcond + + private: + static CDS_EXPORT_API smr* instance_; + + atomics::atomic< thread_record*> thread_list_; ///< Head of thread list + size_t const initial_hazard_count_; ///< initial number of hazard pointers per thread + hp_allocator hp_allocator_; + retired_allocator retired_allocator_; + + // temporaries + std::atomic last_plist_size_; ///< HP array size in last scan() call + }; + + // for backward compatibility + typedef smr GarbageCollector; + + + // inlines + inline hp_allocator& hp_allocator::instance() + { + return smr::instance().get_hp_allocator(); + } + + inline retired_allocator& retired_allocator::instance() + { + return smr::instance().get_retired_allocator(); + } + + } // namespace dhp + + + /// Dynamic Hazard Pointer garbage collector + /** @ingroup cds_garbage_collector + @headerfile cds/gc/dhp.h + + Implementation of Dynamic Hazard Pointer garbage collector. + + Sources: + - [2002] Maged M.Michael "Safe memory reclamation for dynamic lock-freeobjects using atomic reads and writes" + - [2003] Maged M.Michael "Hazard Pointers: Safe memory reclamation for lock-free objects" + - [2004] Andrei Alexandrescy, Maged Michael "Lock-free Data Structures with Hazard Pointers" + + Dynamic Hazard Pointers SMR (safe memory reclamation) provides an unbounded number of hazard pointer per thread + despite of classic Hazard Pointer SMR in which the count of the hazard pointef per thread is limited. + + See \ref cds_how_to_use "How to use" section for details how to apply garbage collector. + */ + class DHP + { + public: + /// Native guarded pointer type + typedef void* guarded_pointer; + + /// Atomic reference + template using atomic_ref = atomics::atomic; + + /// Atomic type + /** + @headerfile cds/gc/dhp.h + */ + template using atomic_type = atomics::atomic; + + /// Atomic marked pointer + template using atomic_marked_ptr = atomics::atomic; + + + /// Dynamic Hazard Pointer guard + /** + A guard is a hazard pointer. + Additionally, the \p %Guard class manages allocation and deallocation of the hazard pointer + + \p %Guard object is movable but not copyable. + + The guard object can be in two states: + - unlinked - the guard is not linked with any internal hazard pointer. + In this state no operation except \p link() and move assignment is supported. + - linked (default) - the guard allocates an internal hazard pointer and fully operable. + + Due to performance reason the implementation does not check state of the guard in runtime. + + @warning Move assignment can transfer the guard in unlinked state, use with care. + */ + class Guard + { + public: + /// Default ctor allocates a guard (hazard pointer) from thread-private storage + Guard() CDS_NOEXCEPT + : guard_( dhp::smr::tls()->hazards_.alloc() ) + {} + + /// Initilalizes an unlinked guard i.e. the guard contains no hazard pointer. Used for move semantics support + explicit Guard( std::nullptr_t ) CDS_NOEXCEPT + : guard_( nullptr ) + {} + + /// Move ctor - \p src guard becomes unlinked (transfer internal guard ownership) + Guard( Guard&& src ) CDS_NOEXCEPT + : guard_( src.guard_ ) + { + src.guard_ = nullptr; + } + + /// Move assignment: the internal guards are swapped between \p src and \p this + /** + @warning \p src will become in unlinked state if \p this was unlinked on entry. + */ + Guard& operator=( Guard&& src ) CDS_NOEXCEPT + { + std::swap( guard_, src.guard_ ); + return *this; + } + + /// Copy ctor is prohibited - the guard is not copyable + Guard( Guard const& ) = delete; + + /// Copy assignment is prohibited + Guard& operator=( Guard const& ) = delete; + + /// Frees the internal hazard pointer if the guard is in linked state + ~Guard() + { + unlink(); + } + + /// Checks if the guard object linked with any internal hazard pointer + bool is_linked() const + { + return guard_ != nullptr; + } + + /// Links the guard with internal hazard pointer if the guard is in unlinked state + void link() + { + if ( !guard_ ) + guard_ = dhp::smr::tls()->hazards_.alloc(); + } + + /// Unlinks the guard from internal hazard pointer; the guard becomes in unlinked state + void unlink() + { + if ( guard_ ) { + dhp::smr::tls()->hazards_.free( guard_ ); + guard_ = nullptr; + } + } + + /// Protects a pointer of type atomic + /** + Return the value of \p toGuard + + The function tries to load \p toGuard and to store it + to the HP slot repeatedly until the guard's value equals \p toGuard + */ + template + T protect( atomics::atomic const& toGuard ) + { + assert( guard_ != nullptr ); + + T pCur = toGuard.load(atomics::memory_order_acquire); + T pRet; + do { + pRet = assign( pCur ); + pCur = toGuard.load(atomics::memory_order_acquire); + } while ( pRet != pCur ); + return pCur; + } + + /// Protects a converted pointer of type atomic + /** + Return the value of \p toGuard + + The function tries to load \p toGuard and to store result of \p f functor + to the HP slot repeatedly until the guard's value equals \p toGuard. + + The function is useful for intrusive containers when \p toGuard is a node pointer + that should be converted to a pointer to the value type before guarding. + The parameter \p f of type Func is a functor that makes this conversion: + \code + struct functor { + value_type * operator()( T * p ); + }; + \endcode + Really, the result of f( toGuard.load()) is assigned to the hazard pointer. + */ + template + T protect( atomics::atomic const& toGuard, Func f ) + { + assert( guard_ != nullptr ); + + T pCur = toGuard.load(atomics::memory_order_acquire); + T pRet; + do { + pRet = pCur; + assign( f( pCur )); + pCur = toGuard.load(atomics::memory_order_acquire); + } while ( pRet != pCur ); + return pCur; + } + + /// Store \p p to the guard + /** + The function is just an assignment, no loop is performed. + Can be used for a pointer that cannot be changed concurrently + or for already guarded pointer. + */ + template + T* assign( T* p ) + { + assert( guard_ != nullptr ); + + guard_->set( p ); + dhp::smr::tls()->sync(); + return p; + } + + //@cond + std::nullptr_t assign( std::nullptr_t ) + { + assert( guard_ != nullptr ); + + clear(); + return nullptr; + } + //@endcond + + /// Store marked pointer \p p to the guard + /** + The function is just an assignment of p.ptr(), no loop is performed. + Can be used for a marked pointer that cannot be changed concurrently + or for already guarded pointer. + */ + template + T* assign( cds::details::marked_ptr p ) + { + return assign( p.ptr()); + } + + /// Copy from \p src guard to \p this guard + void copy( Guard const& src ) + { + assign( src.get_native()); + } + + /// Clears value of the guard + void clear() + { + assert( guard_ != nullptr ); + + guard_->clear(); + } + + /// Gets the value currently protected (relaxed read) + template + T * get() const + { + assert( guard_ != nullptr ); + return guard_->get_as(); + } + + /// Gets native guarded pointer stored + void* get_native() const + { + assert( guard_ != nullptr ); + return guard_->get(); + } + + //@cond + dhp::guard* release() + { + dhp::guard* g = guard_; + guard_ = nullptr; + return g; + } + + dhp::guard*& guard_ref() + { + return guard_; + } + //@endcond + + private: + //@cond + dhp::guard* guard_; + //@endcond + }; + + /// Array of Dynamic Hazard Pointer guards + /** + The class is intended for allocating an array of hazard pointer guards. + Template parameter \p Count defines the size of the array. + + A \p %GuardArray object is not copy- and move-constructible + and not copy- and move-assignable. + */ + template + class GuardArray + { + public: + /// Rebind array for other size \p OtherCount + template + struct rebind { + typedef GuardArray other ; ///< rebinding result + }; + + /// Array capacity + static CDS_CONSTEXPR const size_t c_nCapacity = Count; + + public: + /// Default ctor allocates \p Count hazard pointers + GuardArray() + { + dhp::smr::tls()->hazards_.alloc( guards_ ); + } + + /// Move ctor is prohibited + GuardArray( GuardArray&& ) = delete; + + /// Move assignment is prohibited + GuardArray& operator=( GuardArray&& ) = delete; + + /// Copy ctor is prohibited + GuardArray( GuardArray const& ) = delete; + + /// Copy assignment is prohibited + GuardArray& operator=( GuardArray const& ) = delete; + + /// Frees allocated hazard pointers + ~GuardArray() + { + dhp::smr::tls()->hazards_.free( guards_ ); + } + + /// Protects a pointer of type \p atomic + /** + Return the value of \p toGuard + + The function tries to load \p toGuard and to store it + to the slot \p nIndex repeatedly until the guard's value equals \p toGuard + */ + template + T protect( size_t nIndex, atomics::atomic const& toGuard ) + { + assert( nIndex < capacity() ); + + T pRet; + do { + pRet = assign( nIndex, toGuard.load(atomics::memory_order_acquire)); + } while ( pRet != toGuard.load(atomics::memory_order_relaxed)); + + return pRet; + } + + /// Protects a pointer of type \p atomic + /** + Return the value of \p toGuard + + The function tries to load \p toGuard and to store it + to the slot \p nIndex repeatedly until the guard's value equals \p toGuard + + The function is useful for intrusive containers when \p toGuard is a node pointer + that should be converted to a pointer to the value type before guarding. + The parameter \p f of type Func is a functor to make that conversion: + \code + struct functor { + value_type * operator()( T * p ); + }; + \endcode + Actually, the result of f( toGuard.load()) is assigned to the hazard pointer. + */ + template + T protect( size_t nIndex, atomics::atomic const& toGuard, Func f ) + { + assert( nIndex < capacity() ); + + T pRet; + do { + assign( nIndex, f( pRet = toGuard.load(atomics::memory_order_acquire))); + } while ( pRet != toGuard.load(atomics::memory_order_relaxed)); + + return pRet; + } + + /// Store \p p to the slot \p nIndex + /** + The function is just an assignment, no loop is performed. + */ + template + T * assign( size_t nIndex, T * p ) + { + assert( nIndex < capacity() ); + + guards_.set( nIndex, p ); + dhp::smr::tls()->sync(); + return p; + } + + /// Store marked pointer \p p to the guard + /** + The function is just an assignment of p.ptr(), no loop is performed. + Can be used for a marked pointer that cannot be changed concurrently + or for already guarded pointer. + */ + template + T * assign( size_t nIndex, cds::details::marked_ptr p ) + { + return assign( nIndex, p.ptr()); + } + + /// Copy guarded value from \p src guard to slot at index \p nIndex + void copy( size_t nIndex, Guard const& src ) + { + assign( nIndex, src.get_native()); + } + + /// Copy guarded value from slot \p nSrcIndex to slot at index \p nDestIndex + void copy( size_t nDestIndex, size_t nSrcIndex ) + { + assign( nDestIndex, get_native( nSrcIndex )); + } + + /// Clear value of the slot \p nIndex + void clear( size_t nIndex ) + { + guards_.clear( nIndex ); + } + + /// Get current value of slot \p nIndex + template + T * get( size_t nIndex ) const + { + assert( nIndex < capacity() ); + return guards_[nIndex]->template get_as(); + } + + /// Get native guarded pointer stored + guarded_pointer get_native( size_t nIndex ) const + { + assert( nIndex < capacity() ); + return guards_[nIndex]->get(); + } + + //@cond + dhp::guard* release( size_t nIndex ) CDS_NOEXCEPT + { + return guards_.release( nIndex ); + } + //@endcond + + /// Capacity of the guard array + static CDS_CONSTEXPR size_t capacity() + { + return Count; + } + + private: + //@cond + dhp::guard_array guards_; + //@endcond + }; + + /// Guarded pointer + /** + A guarded pointer is a pair of a pointer and GC's guard. + Usually, it is used for returning a pointer to the item from an lock-free container. + The guard prevents the pointer to be early disposed (freed) by GC. + After destructing \p %guarded_ptr object the pointer can be disposed (freed) automatically at any time. + + Template arguments: + - \p GuardedType - a type which the guard stores + - \p ValueType - a value type + - \p Cast - a functor for converting GuardedType* to ValueType*. Default is \p void (no casting). + + For intrusive containers, \p GuardedType is the same as \p ValueType and no casting is needed. + In such case the \p %guarded_ptr is: + @code + typedef cds::gc::DHP::guarded_ptr< foo > intrusive_guarded_ptr; + @endcode + + For standard (non-intrusive) containers \p GuardedType is not the same as \p ValueType and casting is needed. + For example: + @code + struct foo { + int const key; + std::string value; + }; + + struct value_accessor { + std::string* operator()( foo* pFoo ) const + { + return &(pFoo->value); + } + }; + + // Guarded ptr + typedef cds::gc::DHP::guarded_ptr< Foo, std::string, value_accessor > nonintrusive_guarded_ptr; + @endcode + + You don't need use this class directly. + All set/map container classes from \p libcds declare the typedef for \p %guarded_ptr with appropriate casting functor. + */ + template + class guarded_ptr + { + //@cond + struct trivial_cast { + ValueType * operator()( GuardedType * p ) const + { + return p; + } + }; + + template friend class guarded_ptr; + //@endcond + + public: + typedef GuardedType guarded_type; ///< Guarded type + typedef ValueType value_type; ///< Value type + + /// Functor for casting \p guarded_type to \p value_type + typedef typename std::conditional< std::is_same::value, trivial_cast, Cast >::type value_cast; + + public: + /// Creates empty guarded pointer + guarded_ptr() CDS_NOEXCEPT + : guard_( nullptr ) + {} + + //@cond + explicit guarded_ptr( dhp::guard* g ) CDS_NOEXCEPT + : guard_( g ) + {} + + /// Initializes guarded pointer with \p p + explicit guarded_ptr( guarded_type * p ) CDS_NOEXCEPT + : guard_( nullptr ) + { + reset( p ); + } + explicit guarded_ptr( std::nullptr_t ) CDS_NOEXCEPT + : guard_( nullptr ) + {} + //@endcond + + /// Move ctor + guarded_ptr( guarded_ptr&& gp ) CDS_NOEXCEPT + : guard_( gp.guard_ ) + { + gp.guard_ = nullptr; + } + + /// Move ctor + template + guarded_ptr( guarded_ptr&& gp ) CDS_NOEXCEPT + : guard_( gp.guard_ ) + { + gp.guard_ = nullptr; + } + + /// Ctor from \p Guard + explicit guarded_ptr( Guard&& g ) CDS_NOEXCEPT + : guard_( g.release()) + {} + + /// The guarded pointer is not copy-constructible + guarded_ptr( guarded_ptr const& gp ) = delete; + + /// Clears the guarded pointer + /** + \ref release is called if guarded pointer is not \ref empty + */ + ~guarded_ptr() CDS_NOEXCEPT + { + release(); + } + + /// Move-assignment operator + guarded_ptr& operator=( guarded_ptr&& gp ) CDS_NOEXCEPT + { + std::swap( guard_, gp.guard_ ); + return *this; + } + + /// Move-assignment from \p Guard + guarded_ptr& operator=( Guard&& g ) CDS_NOEXCEPT + { + std::swap( guard_, g.guard_ref()); + return *this; + } + + /// The guarded pointer is not copy-assignable + guarded_ptr& operator=(guarded_ptr const& gp) = delete; + + /// Returns a pointer to guarded value + value_type * operator ->() const CDS_NOEXCEPT + { + assert( !empty()); + return value_cast()( guard_->get_as() ); + } + + /// Returns a reference to guarded value + value_type& operator *() CDS_NOEXCEPT + { + assert( !empty()); + return *value_cast()( guard_->get_as() ); + } + + /// Returns const reference to guarded value + value_type const& operator *() const CDS_NOEXCEPT + { + assert( !empty()); + return *value_cast()(reinterpret_cast(guard_->get())); + } + + /// Checks if the guarded pointer is \p nullptr + bool empty() const CDS_NOEXCEPT + { + return guard_ == nullptr || guard_->get( atomics::memory_order_relaxed ) == nullptr; + } + + /// \p bool operator returns !empty() + explicit operator bool() const CDS_NOEXCEPT + { + return !empty(); + } + + /// Clears guarded pointer + /** + If the guarded pointer has been released, the pointer can be disposed (freed) at any time. + Dereferncing the guarded pointer after \p release() is dangerous. + */ + void release() CDS_NOEXCEPT + { + free_guard(); + } + + //@cond + // For internal use only!!! + void reset(guarded_type * p) CDS_NOEXCEPT + { + alloc_guard(); + assert( guard_ ); + guard_->set( p ); + } + + //@endcond + + private: + //@cond + void alloc_guard() + { + if ( !guard_ ) + guard_ = dhp::smr::tls()->hazards_.alloc(); + } + + void free_guard() + { + if ( guard_ ) { + dhp::smr::tls()->hazards_.free( guard_ ); + guard_ = nullptr; + } + } + //@endcond + + private: + //@cond + dhp::guard* guard_; + //@endcond + }; + + public: + /// Initializes %DHP memory manager singleton + /** + Constructor creates and initializes %DHP global object. + %DHP object should be created before using CDS data structure based on \p %cds::gc::DHP. Usually, + it is created in the beginning of \p main() function. + After creating of global object you may use CDS data structures based on \p %cds::gc::DHP. + + \p nInitialThreadGuardCount - initial count of guard allocated for each thread. + When a thread is initialized the GC allocates local guard pool for the thread from a common guard pool. + By perforce the local thread's guard pool is grown automatically from common pool. + When the thread terminated its guard pool is backed to common GC's pool. + */ + DHP( + size_t nInitialHazardPtrCount = 16 ///< Initial number of hazard pointer per thread + ) + { + dhp::smr::construct( nInitialHazardPtrCount ); + } + + /// Destroys %DHP memory manager + /** + The destructor destroys %DHP global object. After calling of this function you may \b NOT + use CDS data structures based on \p %cds::gc::DHP. + Usually, %DHP object is destroyed at the end of your \p main(). + */ + ~DHP() + { + dhp::GarbageCollector::destruct( true ); + } + + /// Checks if count of hazard pointer is no less than \p nCountNeeded + /** + The function always returns \p true since the guard count is unlimited for + \p %gc::DHP garbage collector. + */ + static CDS_CONSTEXPR bool check_available_guards( +#ifdef CDS_DOXYGEN_INVOKED + size_t nCountNeeded, +#else + size_t +#endif + ) + { + return true; + } + + /// Set memory management functions + /** + @note This function may be called BEFORE creating an instance + of Dynamic Hazard Pointer SMR + + SMR object allocates some memory for thread-specific data and for + creating SMR object. + By default, a standard \p new and \p delete operators are used for this. + */ + static void set_memory_allocator( + void* ( *alloc_func )( size_t size ), ///< \p malloc() function + void( *free_func )( void * p ) ///< \p free() function + ) + { + dhp::smr::set_memory_allocator( alloc_func, free_func ); + } + + /// Retire pointer \p p with function \p pFunc + /** + The function places pointer \p p to array of pointers ready for removing. + (so called retired pointer array). The pointer can be safely removed when no hazard pointer points to it. + \p func is a disposer: when \p p can be safely removed, \p func is called. + */ + template + static void retire( T * p, void (* func)(T *)) + { + dhp::thread_data* rec = dhp::smr::tls(); + if ( !rec->retired_.push( dhp::retired_ptr( p, func ) ) ) + dhp::smr::instance().scan( rec ); + } + + /// Retire pointer \p p with functor of type \p Disposer + /** + The function places pointer \p p to array of pointers ready for removing. + (so called retired pointer array). The pointer can be safely removed when no hazard pointer points to it. + + Deleting the pointer is an invocation of some object of type \p Disposer; the interface of \p Disposer is: + \code + template + struct disposer { + void operator()( T * p ) ; // disposing operator + }; + \endcode + Since the functor call can happen at any time after \p retire() call, additional restrictions are imposed to \p Disposer type: + - it should be stateless functor + - it should be default-constructible + - the result of functor call with argument \p p should not depend on where the functor will be called. + + \par Examples: + Operator \p delete functor: + \code + template + struct disposer { + void operator ()( T * p ) { + delete p; + } + }; + + // How to call HP::retire method + int * p = new int; + + // ... use p in lock-free manner + + cds::gc::DHP::retire( p ) ; // place p to retired pointer array of DHP SMR + \endcode + + Functor based on \p std::allocator : + \code + template > + struct disposer { + template + void operator()( T * p ) { + typedef typename Alloc::templare rebind::other alloc_t; + alloc_t a; + a.destroy( p ); + a.deallocate( p, 1 ); + } + }; + \endcode + */ + template + static void retire( T * p ) + { + if ( !dhp::smr::tls()->retired_.push( dhp::retired_ptr( p, cds::details::static_functor::call ))) + scan(); + } + + /// Checks if Dynamic Hazard Pointer GC is constructed and may be used + static bool isUsed() + { + return dhp::smr::isUsed(); + } + + /// Forced GC cycle call for current thread + /** + Usually, this function should not be called directly. + */ + static void scan() + { + dhp::smr::instance().scan( dhp::smr::tls() ); + } + + /// Synonym for \p scan() + static void force_dispose() + { + scan(); + } + }; + +}} // namespace cds::gc + +#endif // #ifndef CDSLIB_GC_DHP_SMR_H + + diff --git a/cds/gc/hp.h b/cds/gc/hp.h index 61ec83af..e42fedb6 100644 --- a/cds/gc/hp.h +++ b/cds/gc/hp.h @@ -31,12 +31,12 @@ #ifndef CDSLIB_GC_HP_H #define CDSLIB_GC_HP_H -#include -#include +#include #include +#include /** - @page cds_garbage_collectors_comparison GC comparison + @page cds_garbage_collectors_comparison SMR (Safe Memory Reclamation schema) comparison @ingroup cds_garbage_collector @@ -47,7 +47,7 @@ - + diff --git a/cds/gc/hp_smr.h b/cds/gc/hp_smr.h new file mode 100644 index 00000000..9d7aa488 --- /dev/null +++ b/cds/gc/hp_smr.h @@ -0,0 +1,1461 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CDSLIB_GC_HP_SMR_H +#define CDSLIB_GC_HP_SMR_H + +#include +#include +#include +#include +#include +#include + +namespace cds { namespace gc { + namespace hp { + using namespace cds::gc::hp::common; + + /// Exception "Not enough Hazard Pointer" + class not_enought_hazard_ptr: public std::length_error + { + public: + //@cond + not_enought_hazard_ptr() + : std::length_error( "Not enough Hazard Pointer" ) + {} + //@endcond + }; + + /// Exception "Hazard Pointer SMR is not initialized" + class not_initialized: public std::runtime_error + { + public: + not_initialized() + : std::runtime_error( "Global Hazard Pointer SMR object is not initialized" ) + {} + }; + + /// Per-thread hazard pointer storage + class thread_hp_storage { + public: + thread_hp_storage( guard* arr, size_t nSize ) CDS_NOEXCEPT + : free_head_( arr ) + , array_( arr ) + , capacity_( nSize ) +# ifdef CDS_ENABLE_HPSTAT + , alloc_guard_count_(0) + , free_guard_count_(0) +# endif + { + for ( guard* pEnd = arr + nSize - 1; arr < pEnd; ++arr ) + arr->next_ = arr + 1; + arr->next_ = nullptr; + } + + thread_hp_storage() = delete; + thread_hp_storage( thread_hp_storage const& ) = delete; + thread_hp_storage( thread_hp_storage&& ) = delete; + + size_t capacity() const CDS_NOEXCEPT + { + return capacity_; + } + + bool full() const CDS_NOEXCEPT + { + return free_head_ == nullptr; + } + + guard* alloc() + { +# ifdef CDS_DISABLE_SMR_EXCEPTION + assert( !full()); +# else + if ( full() ) + CDS_THROW_EXCEPTION( not_enought_hazard_ptr()); +# endif + guard* g = free_head_; + free_head_ = g->next_; + CDS_HPSTAT( ++alloc_guard_count_ ); + return g; + } + + void free( guard* g ) CDS_NOEXCEPT + { + assert( g >= array_ && g < array_ + capacity() ); + + if ( g ) { + g->clear(); + g->next_ = free_head_; + free_head_ = g; + CDS_HPSTAT( ++free_guard_count_ ); + } + } + + template< size_t Capacity> + size_t alloc( guard_array& arr ) + { + size_t i; + guard* g = free_head_; + for ( i = 0; i < Capacity && g; ++i ) { + arr.reset( i, g ); + g = g->next_; + } + +# ifdef CDS_DISABLE_SMR_EXCEPTION + assert( i == Capacity ); +# else + if ( i != Capacity ) + CDS_THROW_EXCEPTION( not_enought_hazard_ptr()); +# endif + free_head_ = g; + CDS_HPSTAT( alloc_guard_count_ += Capacity ); + return i; + } + + template + void free( guard_array& arr ) CDS_NOEXCEPT + { + guard* gList = free_head_; + for ( size_t i = 0; i < Capacity; ++i ) { + guard* g = arr[i]; + if ( g ) { + g->clear(); + g->next_ = gList; + gList = g; + CDS_HPSTAT( ++free_guard_count_ ); + } + } + free_head_ = gList; + } + + void clear() + { + for ( guard* cur = array_, *last = array_ + capacity(); cur < last; ++cur ) + cur->clear(); + } + + guard& operator[]( size_t idx ) + { + assert( idx < capacity() ); + + return array_[idx]; + } + + static size_t calc_array_size( size_t capacity ) + { + return sizeof( guard ) * capacity; + } + + private: + guard* free_head_; ///< Head of free guard list + guard* const array_; ///< HP array + size_t const capacity_; ///< HP array capacity +# ifdef CDS_ENABLE_HPSTAT + public: + size_t alloc_guard_count_; + size_t free_guard_count_; +# endif + }; + + /// Per-thread retired array + class retired_array + { + public: + retired_array( retired_ptr* arr, size_t capacity ) CDS_NOEXCEPT + : current_( arr ) + , last_( arr + capacity ) + , retired_( arr ) +# ifdef CDS_ENABLE_HPSTAT + , retire_call_count_(0) +# endif + {} + + retired_array() = delete; + retired_array( retired_array const& ) = delete; + retired_array( retired_array&& ) = delete; + + size_t capacity() const CDS_NOEXCEPT + { + return last_ - retired_; + } + + size_t size() const CDS_NOEXCEPT + { + return current_ - retired_; + } + + bool push( retired_ptr&& p ) CDS_NOEXCEPT + { + *current_ = p; + CDS_HPSTAT( ++retire_call_count_ ); + return ++current_ < last_; + } + + retired_ptr* first() const CDS_NOEXCEPT + { + return retired_; + } + + retired_ptr* last() const CDS_NOEXCEPT + { + return current_; + } + + void reset( size_t nSize ) CDS_NOEXCEPT + { + current_ = first() + nSize; + } + + bool full() const CDS_NOEXCEPT + { + return current_ == last_; + } + + static size_t calc_array_size( size_t capacity ) + { + return sizeof( retired_ptr ) * capacity; + } + + private: + retired_ptr* current_; + retired_ptr* const last_; + retired_ptr* const retired_; +# ifdef CDS_ENABLE_HPSTAT + public: + size_t retire_call_count_; +# endif + + }; + + /// Internal statistics + struct stat { + size_t guard_allocated; ///< Count of allocated HP guards + size_t guard_freed; ///< Count of freed HP guards + size_t retired_count; ///< Count of retired pointers + size_t free_count; ///< Count of free pointers + size_t scan_count; ///< Count of \p scan() call + size_t help_scan_count; ///< Count of \p help_scan() call + + size_t thread_rec_count; ///< Count of thread records + + stat() + { + clear(); + } + + void clear() + { + guard_allocated = + guard_freed = + retired_count = + free_count = + scan_count = + help_scan_count = + thread_rec_count = 0; + } + }; + + /// Per-thread data + struct thread_data { + thread_hp_storage hazards_; ///< Hazard pointers private to the thread + retired_array retired_; ///< Retired data private to the thread + + stat stat_; ///< Internal statistics for the thread + + char pad1_[cds::c_nCacheLineSize]; + atomics::atomic sync_; ///< dummy var to introduce synchronizes-with relationship between threads + char pad2_[cds::c_nCacheLineSize]; + + thread_data( guard* guards, size_t guard_count, retired_ptr* retired_arr, size_t retired_capacity ) + : hazards_( guards, guard_count ) + , retired_( retired_arr, retired_capacity ) + , sync_(0) + {} + + thread_data() = delete; + thread_data( thread_data const& ) = delete; + thread_data( thread_data&& ) = delete; + + void sync() + { + sync_.fetch_add( 1, atomics::memory_order_acq_rel ); + } + }; + + /// smr::scan() strategy + enum scan_type { + classic, ///< classic scan as described in Michael's works (see smr::classic_scan() ) + inplace ///< inplace scan without allocation (see smr::inplace_scan() ) + }; + + // Hazard Pointer SMR (Safe Memory Reclamation) + class smr + { + struct thread_record; + + public: + /// Returns the instance of Hazard Pointer \ref smr + static smr& instance() + { +# ifdef CDS_DISABLE_SMR_EXCEPTION + assert( instance_ != nullptr ); +# else + if ( !instance_ ) + CDS_THROW_EXCEPTION( not_initialized()); +# endif + return *instance_; + } + + /// Creates Hazard Pointer SMR singleton + /** + Hazard Pointer SMR is a singleton. If HP instance is not initialized then the function creates the instance. + Otherwise it does nothing. + + The Michael's HP reclamation schema depends of three parameters: + - \p nHazardPtrCount - HP pointer count per thread. Usually it is small number (2-4) depending from + the data structure algorithms. By default, if \p nHazardPtrCount = 0, + the function uses maximum of HP count for CDS library + - \p nMaxThreadCount - max count of thread with using HP GC in your application. Default is 100. + - \p nMaxRetiredPtrCount - capacity of array of retired pointers for each thread. Must be greater than + nHazardPtrCount * nMaxThreadCount + Default is 2 * nHazardPtrCount * nMaxThreadCount + */ + static CDS_EXPORT_API void construct( + size_t nHazardPtrCount = 0, ///< Hazard pointer count per thread + size_t nMaxThreadCount = 0, ///< Max count of simultaneous working thread in your application + size_t nMaxRetiredPtrCount = 0, ///< Capacity of the array of retired objects for the thread + scan_type nScanType = inplace ///< Scan type (see \ref scan_type enum) + ); + + //@cond + // for back-copatibility + static void Construct( + size_t nHazardPtrCount = 0, ///< Hazard pointer count per thread + size_t nMaxThreadCount = 0, ///< Max count of simultaneous working thread in your application + size_t nMaxRetiredPtrCount = 0, ///< Capacity of the array of retired objects for the thread + scan_type nScanType = inplace ///< Scan type (see \ref scan_type enum) + ) + { + construct( nHazardPtrCount, nMaxThreadCount, nMaxRetiredPtrCount, nScanType ); + } + + //@endcond + + /// Destroys global instance of \ref smr + /** + The parameter \p bDetachAll should be used carefully: if its value is \p true, + then the object destroyed automatically detaches all attached threads. This feature + can be useful when you have no control over the thread termination, for example, + when \p libcds is injected into existing external thread. + */ + static CDS_EXPORT_API void destruct( + bool bDetachAll = false ///< Detach all threads + ); + + //@cond + // for back-copatibility + static void Destruct( + bool bDetachAll = false ///< Detach all threads + ) + { + destruct( bDetachAll ); + } + //@endcond + + /// Checks if global SMR object is constructed and may be used + static bool isUsed() CDS_NOEXCEPT + { + return instance_ != nullptr; + } + + /// Set memory management functions + /** + @note This function may be called BEFORE creating an instance + of Hazard Pointer SMR + + SMR object allocates some memory for thread-specific data and for + creating SMR object. + By default, a standard \p new and \p delete operators are used for this. + */ + static CDS_EXPORT_API void set_memory_allocator( + void* ( *alloc_func )( size_t size ), + void (*free_func )( void * p ) + ); + + /// Returns max Hazard Pointer count per thread + size_t get_hazard_ptr_count() const CDS_NOEXCEPT + { + return hazard_ptr_count_; + } + + /// Returns max thread count + size_t get_max_thread_count() const CDS_NOEXCEPT + { + return max_thread_count_; + } + + /// Returns max size of retired objects array + size_t get_max_retired_ptr_count() const CDS_NOEXCEPT + { + return max_retired_ptr_count_; + } + + /// Get current scan strategy + scan_type get_scan_type() const + { + return scan_type_; + } + + /// Checks that required hazard pointer count \p nRequiredCount is less or equal then max hazard pointer count + /** + If nRequiredCount > get_hazard_ptr_count() then the exception \p not_enought_hazard_ptr is thrown + */ + static void check_hazard_ptr_count( size_t nRequiredCount ) + { + if ( instance().get_hazard_ptr_count() < nRequiredCount ) { +# ifdef CDS_DISABLE_SMR_EXCEPTION + assert( false ); // not enough hazard ptr +# else + CDS_THROW_EXCEPTION( not_enought_hazard_ptr() ); +# endif + } + } + + /// Returns thread-local data for the current thread + static CDS_EXPORT_API thread_data* tls(); + + static CDS_EXPORT_API void attach_thread(); + static CDS_EXPORT_API void detach_thread(); + + /// Get internal statistics + void statistics( stat& st ); + + public: // for internal use only + /// The main garbage collecting function + /** + This function is called internally when upper bound of thread's list of reclaimed pointers + is reached. + + There are the following scan algorithm: + - \ref hzp_gc_classic_scan "classic_scan" allocates memory for internal use + - \ref hzp_gc_inplace_scan "inplace_scan" does not allocate any memory + + Use \p set_scan_type() member function to setup appropriate scan algorithm. + */ + void scan( thread_data* pRec ) + { + ( this->*scan_func_ )( pRec ); + } + + /// Helper scan routine + /** + The function guarantees that every node that is eligible for reuse is eventually freed, barring + thread failures. To do so, after executing \p scan(), a thread executes a \p %help_scan(), + where it checks every HP record. If an HP record is inactive, the thread moves all "lost" reclaimed pointers + to thread's list of reclaimed pointers. + + The function is called internally by \p scan(). + */ + CDS_EXPORT_API void help_scan( thread_data* pThis ); + + private: + CDS_EXPORT_API smr( + size_t nHazardPtrCount, ///< Hazard pointer count per thread + size_t nMaxThreadCount, ///< Max count of simultaneous working thread in your application + size_t nMaxRetiredPtrCount, ///< Capacity of the array of retired objects for the thread + scan_type nScanType ///< Scan type (see \ref scan_type enum) + ); + + CDS_EXPORT_API ~smr(); + + CDS_EXPORT_API void detach_all_thread(); + + /// Classic scan algorithm + /** @anchor hzp_gc_classic_scan + Classical scan algorithm as described in Michael's paper. + + A scan includes four stages. The first stage involves scanning the array HP for non-null values. + Whenever a non-null value is encountered, it is inserted in a local list of currently protected pointer. + Only stage 1 accesses shared variables. The following stages operate only on private variables. + + The second stage of a scan involves sorting local list of protected pointers to allow + binary search in the third stage. + + The third stage of a scan involves checking each reclaimed node + against the pointers in local list of protected pointers. If the binary search yields + no match, the node is freed. Otherwise, it cannot be deleted now and must kept in thread's list + of reclaimed pointers. + + The forth stage prepares new thread's private list of reclaimed pointers + that could not be freed during the current scan, where they remain until the next scan. + + This algorithm allocates memory for internal HP array. + + This function is called internally by ThreadGC object when upper bound of thread's list of reclaimed pointers + is reached. + */ + CDS_EXPORT_API void classic_scan( thread_data* pRec ); + + /// In-place scan algorithm + /** @anchor hzp_gc_inplace_scan + Unlike the \p classic_scan() algorithm, \p %inplace_scan() does not allocate any memory. + All operations are performed in-place. + */ + CDS_EXPORT_API void inplace_scan( thread_data* pRec ); + + private: + //@cond + CDS_EXPORT_API thread_record* create_thread_data(); + CDS_EXPORT_API void destroy_thread_data( thread_record* pRec ); + + /// Allocates Hazard Pointer SMR thread private data + CDS_EXPORT_API thread_record* alloc_thread_data(); + + /// Free HP SMR thread-private data + CDS_EXPORT_API void free_thread_data( thread_record* pRec ); + + //@endcond + + private: + static CDS_EXPORT_API smr* instance_; + + atomics::atomic< thread_record*> thread_list_; ///< Head of thread list + + size_t const hazard_ptr_count_; ///< max count of thread's hazard pointer + size_t const max_thread_count_; ///< max count of thread + size_t const max_retired_ptr_count_; ///< max count of retired ptr per thread + scan_type const scan_type_; ///< scan type (see \ref scan_type enum) + void ( smr::*scan_func_ )( thread_data* pRec ); + }; + + // for backward compatibility + typedef smr GarbageCollector; + + } // namespace hp + + + /// @defgroup cds_garbage_collector Garbage collectors + + /// Hazard Pointer SMR (Safe Memory Reclamation) + /** @ingroup cds_garbage_collector + + Implementation of classic Hazard Pointer garbage collector. + + Sources: + - [2002] Maged M.Michael "Safe memory reclamation for dynamic lock-freeobjects using atomic reads and writes" + - [2003] Maged M.Michael "Hazard Pointers: Safe memory reclamation for lock-free objects" + - [2004] Andrei Alexandrescy, Maged Michael "Lock-free Data Structures with Hazard Pointers" + + Hazard Pointer garbage collector is a singleton. The main user-level part of Hazard Pointer schema is + \p %cds::gc::HP class and its nested classes. Before use any HP-related class you must initialize HP + by contructing \p %cds::gc::HP object in beginning of your \p main(). + See \ref cds_how_to_use "How to use" section for details how to apply SMR schema. + */ + class HP + { + public: + /// Native guarded pointer type + typedef hp::hazard_ptr guarded_pointer; + + /// Atomic reference + template using atomic_ref = atomics::atomic; + + /// Atomic marked pointer + template using atomic_marked_ptr = atomics::atomic; + + /// Atomic type + template using atomic_type = atomics::atomic; + + /// Exception "Not enough Hazard Pointer" + typedef hp::not_enought_hazard_ptr not_enought_hazard_ptr_exception; + + /// Internal statistics + typedef hp::stat stat; + + /// Hazard Pointer guard + /** + A guard is a hazard pointer. + Additionally, the \p %Guard class manages allocation and deallocation of the hazard pointer. + + \p %Guard object is movable but not copyable. + + The guard object can be in two states: + - unlinked - the guard is not linked with any internal hazard pointer. + In this state no operation except \p link() and move assignment is supported. + - linked (default) - the guard allocates an internal hazard pointer and completely operable. + + Due to performance reason the implementation does not check state of the guard in runtime. + + @warning Move assignment transfers the guard in unlinked state, use with care. + */ + class Guard + { + public: + /// Default ctor allocates a guard (hazard pointer) from thread-private storage + /** + @warning Can throw \p too_many_hazard_ptr_exception if internal hazard pointer objects are exhausted. + */ + Guard() + : guard_( hp::smr::tls()->hazards_.alloc() ) + {} + + /// Initilalizes an unlinked guard i.e. the guard contains no hazard pointer. Used for move semantics support + explicit Guard( std::nullptr_t ) CDS_NOEXCEPT + : guard_( nullptr ) + {} + + /// Move ctor - \p src guard becomes unlinked (transfer internal guard ownership) + Guard( Guard&& src ) CDS_NOEXCEPT + : guard_( src.guard_ ) + { + src.guard_ = nullptr; + } + + /// Move assignment: the internal guards are swapped between \p src and \p this + /** + @warning \p src will become in unlinked state if \p this was unlinked on entry. + */ + Guard& operator=( Guard&& src ) CDS_NOEXCEPT + { + std::swap( guard_, src.guard_ ); + return *this; + } + + /// Copy ctor is prohibited - the guard is not copyable + Guard( Guard const& ) = delete; + + /// Copy assignment is prohibited + Guard& operator=( Guard const& ) = delete; + + /// Frees the internal hazard pointer if the guard is in linked state + ~Guard() + { + unlink(); + } + + /// Checks if the guard object linked with any internal hazard pointer + bool is_linked() const + { + return guard_ != nullptr; + } + + /// Links the guard with internal hazard pointer if the guard is in unlinked state + /** + @warning Can throw \p not_enought_hazard_ptr_exception if internal hazard pointer array is exhausted. + */ + void link() + { + if ( !guard_ ) + guard_ = hp::smr::tls()->hazards_.alloc(); + } + + /// Unlinks the guard from internal hazard pointer; the guard becomes in unlinked state + void unlink() + { + if ( guard_ ) { + hp::smr::tls()->hazards_.free( guard_ ); + guard_ = nullptr; + } + } + + /// Protects a pointer of type \p atomic + /** + Return the value of \p toGuard + + The function tries to load \p toGuard and to store it + to the HP slot repeatedly until the guard's value equals \p toGuard + + @warning The guad object should be in linked state, otherwise the result is undefined + */ + template + T protect( atomics::atomic const& toGuard ) + { + assert( guard_ != nullptr ); + + T pCur = toGuard.load(atomics::memory_order_acquire); + T pRet; + do { + pRet = assign( pCur ); + pCur = toGuard.load(atomics::memory_order_acquire); + } while ( pRet != pCur ); + return pCur; + } + + /// Protects a converted pointer of type \p atomic + /** + Return the value of \p toGuard + + The function tries to load \p toGuard and to store result of \p f functor + to the HP slot repeatedly until the guard's value equals \p toGuard. + + The function is useful for intrusive containers when \p toGuard is a node pointer + that should be converted to a pointer to the value before protecting. + The parameter \p f of type Func is a functor that makes this conversion: + \code + struct functor { + value_type * operator()( T * p ); + }; + \endcode + Actually, the result of f( toGuard.load()) is assigned to the hazard pointer. + + @warning The guad object should be in linked state, otherwise the result is undefined + */ + template + T protect( atomics::atomic const& toGuard, Func f ) + { + assert( guard_ != nullptr ); + + T pCur = toGuard.load(atomics::memory_order_acquire); + T pRet; + do { + pRet = pCur; + assign( f( pCur )); + pCur = toGuard.load(atomics::memory_order_acquire); + } while ( pRet != pCur ); + return pCur; + } + + /// Store \p p to the guard + /** + The function equals to a simple assignment the value \p p to guard, no loop is performed. + Can be used for a pointer that cannot be changed concurrently or if the pointer is already + guarded by another guard. + + @warning The guad object should be in linked state, otherwise the result is undefined + */ + template + T * assign( T* p ) + { + assert( guard_ != nullptr ); + + guard_->set( p ); + hp::smr::tls()->sync(); + return p; + } + + //@cond + std::nullptr_t assign( std::nullptr_t ) + { + assert( guard_ != nullptr ); + + guard_->clear(); + return nullptr; + } + //@endcond + + /// Copy a value guarded from \p src guard to \p this guard (valid only in linked state) + void copy( Guard const& src ) + { + assign( src.get_native()); + } + + /// Store marked pointer \p p to the guard + /** + The function equals to a simple assignment of p.ptr(), no loop is performed. + Can be used for a marked pointer that cannot be changed concurrently or if the marked pointer + is already guarded by another guard. + + @warning The guard object should be in linked state, otherwise the result is undefined + */ + template + T * assign( cds::details::marked_ptr p ) + { + return assign( p.ptr()); + } + + /// Clear value of the guard (valid only in linked state) + void clear() + { + assign( nullptr ); + } + + /// Get the value currently protected (valid only in linked state) + template + T * get() const + { + assert( guard_ != nullptr ); + return guard_->get_as(); + } + + /// Get native hazard pointer stored (valid only in linked state) + guarded_pointer get_native() const + { + assert( guard_ != nullptr ); + return guard_->get(); + } + + //@cond + hp::guard* release() + { + hp::guard* g = guard_; + guard_ = nullptr; + return g; + } + + hp::guard*& guard_ref() + { + return guard_; + } + //@endcond + + private: + //@cond + hp::guard* guard_; + //@endcond + }; + + /// Array of Hazard Pointer guards + /** + The class is intended for allocating an array of hazard pointer guards. + Template parameter \p Count defines the size of the array. + */ + template + class GuardArray + { + public: + /// Rebind array for other size \p Count2 + template + struct rebind { + typedef GuardArray other; ///< rebinding result + }; + + /// Array capacity + static CDS_CONSTEXPR const size_t c_nCapacity = Count; + + public: + /// Default ctor allocates \p Count hazard pointers + GuardArray() + { + hp::smr::tls()->hazards_.alloc( guards_ ); + } + + /// Move ctor is prohibited + GuardArray( GuardArray&& ) = delete; + + /// Move assignment is prohibited + GuardArray& operator=( GuardArray&& ) = delete; + + /// Copy ctor is prohibited + GuardArray( GuardArray const& ) = delete; + + /// Copy assignment is prohibited + GuardArray& operator=( GuardArray const& ) = delete; + + /// Frees allocated hazard pointers + ~GuardArray() + { + hp::smr::tls()->hazards_.free( guards_ ); + } + + /// Protects a pointer of type \p atomic + /** + Return the value of \p toGuard + + The function tries to load \p toGuard and to store it + to the slot \p nIndex repeatedly until the guard's value equals \p toGuard + */ + template + T protect( size_t nIndex, atomics::atomic const& toGuard ) + { + assert( nIndex < capacity()); + + T pRet; + do { + pRet = assign( nIndex, toGuard.load(atomics::memory_order_acquire)); + } while ( pRet != toGuard.load(atomics::memory_order_acquire)); + + return pRet; + } + + /// Protects a pointer of type \p atomic + /** + Return the value of \p toGuard + + The function tries to load \p toGuard and to store it + to the slot \p nIndex repeatedly until the guard's value equals \p toGuard + + The function is useful for intrusive containers when \p toGuard is a node pointer + that should be converted to a pointer to the value type before guarding. + The parameter \p f of type Func is a functor that makes this conversion: + \code + struct functor { + value_type * operator()( T * p ); + }; + \endcode + Really, the result of f( toGuard.load()) is assigned to the hazard pointer. + */ + template + T protect( size_t nIndex, atomics::atomic const& toGuard, Func f ) + { + assert( nIndex < capacity()); + + T pRet; + do { + assign( nIndex, f( pRet = toGuard.load(atomics::memory_order_acquire))); + } while ( pRet != toGuard.load(atomics::memory_order_acquire)); + + return pRet; + } + + /// Store \p to the slot \p nIndex + /** + The function equals to a simple assignment, no loop is performed. + */ + template + T * assign( size_t nIndex, T * p ) + { + assert( nIndex < capacity() ); + + guards_.set( nIndex, p ); + hp::smr::tls()->sync(); + return p; + } + + /// Store marked pointer \p p to the guard + /** + The function equals to a simple assignment of p.ptr(), no loop is performed. + Can be used for a marked pointer that cannot be changed concurrently. + */ + template + T * assign( size_t nIndex, cds::details::marked_ptr p ) + { + return assign( nIndex, p.ptr()); + } + + /// Copy guarded value from \p src guard to slot at index \p nIndex + void copy( size_t nIndex, Guard const& src ) + { + assign( nIndex, src.get_native()); + } + + /// Copy guarded value from slot \p nSrcIndex to the slot \p nDestIndex + void copy( size_t nDestIndex, size_t nSrcIndex ) + { + assign( nDestIndex, get_native( nSrcIndex )); + } + + /// Clear value of the slot \p nIndex + void clear( size_t nIndex ) + { + guards_.clear( nIndex ); + } + + /// Get current value of slot \p nIndex + template + T * get( size_t nIndex ) const + { + assert( nIndex < capacity() ); + return guards_[nIndex]->template get_as(); + } + + /// Get native hazard pointer stored + guarded_pointer get_native( size_t nIndex ) const + { + assert( nIndex < capacity()); + return guards_[nIndex]->get(); + } + + //@cond + hp::guard* release( size_t nIndex ) CDS_NOEXCEPT + { + return guards_.release( nIndex ); + } + //@endcond + + /// Capacity of the guard array + static CDS_CONSTEXPR size_t capacity() + { + return c_nCapacity; + } + + private: + //@cond + hp::guard_array guards_; + //@endcond + }; + + /// Guarded pointer + /** + A guarded pointer is a pair of a pointer and GC's guard. + Usually, it is used for returning a pointer to an element of a lock-free container. + The guard prevents the pointer to be early disposed (freed) by SMR. + After destructing \p %guarded_ptr object the pointer can be disposed (freed) automatically at any time. + + Template arguments: + - \p GuardedType - a type which the guard stores + - \p ValueType - a value type + - \p Cast - a functor for converting GuardedType* to ValueType*. Default is \p void (no casting). + + For intrusive containers, \p GuardedType is the same as \p ValueType and no casting is needed. + In such case the \p %guarded_ptr is: + @code + typedef cds::gc::HP::guarded_ptr< foo > intrusive_guarded_ptr; + @endcode + + For standard (non-intrusive) containers \p GuardedType is not the same as \p ValueType and casting is needed. + For example: + @code + struct foo { + int const key; + std::string value; + }; + + struct value_accessor { + std::string* operator()( foo* pFoo ) const + { + return &(pFoo->value); + } + }; + + // Guarded ptr + typedef cds::gc::HP::guarded_ptr< Foo, std::string, value_accessor > nonintrusive_guarded_ptr; + @endcode + + You don't need use this class directly. + All set/map container classes from \p libcds declare the typedef for \p %guarded_ptr with appropriate casting functor. + */ + template + class guarded_ptr + { + //@cond + struct trivial_cast { + ValueType * operator()( GuardedType * p ) const + { + return p; + } + }; + + template friend class guarded_ptr; + //@endcond + + public: + typedef GuardedType guarded_type; ///< Guarded type + typedef ValueType value_type; ///< Value type + + /// Functor for casting \p guarded_type to \p value_type + typedef typename std::conditional< std::is_same::value, trivial_cast, Cast >::type value_cast; + + public: + /// Creates empty guarded pointer + guarded_ptr() CDS_NOEXCEPT + : guard_(nullptr) + {} + + //@cond + explicit guarded_ptr( hp::guard* g ) CDS_NOEXCEPT + : guard_( g ) + {} + + /// Initializes guarded pointer with \p p + explicit guarded_ptr( guarded_type* p ) CDS_NOEXCEPT + : guard_( nullptr ) + { + reset(p); + } + explicit guarded_ptr( std::nullptr_t ) CDS_NOEXCEPT + : guard_( nullptr ) + {} + //@endcond + + /// Move ctor + guarded_ptr( guarded_ptr&& gp ) CDS_NOEXCEPT + : guard_( gp.guard_ ) + { + gp.guard_ = nullptr; + } + + /// Move ctor + template + guarded_ptr( guarded_ptr&& gp ) CDS_NOEXCEPT + : guard_( gp.guard_ ) + { + gp.guard_ = nullptr; + } + + /// Ctor from \p Guard + explicit guarded_ptr( Guard&& g ) CDS_NOEXCEPT + : guard_( g.release()) + {} + + /// The guarded pointer is not copy-constructible + guarded_ptr( guarded_ptr const& gp ) = delete; + + /// Clears the guarded pointer + /** + \ref release() is called if guarded pointer is not \ref empty() + */ + ~guarded_ptr() CDS_NOEXCEPT + { + release(); + } + + /// Move-assignment operator + guarded_ptr& operator=( guarded_ptr&& gp ) CDS_NOEXCEPT + { + std::swap( guard_, gp.guard_ ); + return *this; + } + + /// Move-assignment from \p Guard + guarded_ptr& operator=( Guard&& g ) CDS_NOEXCEPT + { + std::swap( guard_, g.guard_ref()); + return *this; + } + + /// The guarded pointer is not copy-assignable + guarded_ptr& operator=(guarded_ptr const& gp) = delete; + + /// Returns a pointer to guarded value + value_type * operator ->() const CDS_NOEXCEPT + { + assert( !empty()); + return value_cast()( guard_->get_as()); + } + + /// Returns a reference to guarded value + value_type& operator *() CDS_NOEXCEPT + { + assert( !empty()); + return *value_cast()( guard_->get_as()); + } + + /// Returns const reference to guarded value + value_type const& operator *() const CDS_NOEXCEPT + { + assert( !empty()); + return *value_cast()( guard_->get_as()); + } + + /// Checks if the guarded pointer is \p nullptr + bool empty() const CDS_NOEXCEPT + { + return !guard_ || guard_->get( atomics::memory_order_relaxed ) == nullptr; + } + + /// \p bool operator returns !empty() + explicit operator bool() const CDS_NOEXCEPT + { + return !empty(); + } + + /// Clears guarded pointer + /** + If the guarded pointer has been released, the pointer can be disposed (freed) at any time. + Dereferncing the guarded pointer after \p release() is dangerous. + */ + void release() CDS_NOEXCEPT + { + free_guard(); + } + + //@cond + // For internal use only!!! + void reset(guarded_type * p) CDS_NOEXCEPT + { + alloc_guard(); + assert( guard_ ); + guard_->set(p); + } + //@endcond + + private: + //@cond + void alloc_guard() + { + if ( !guard_ ) + guard_ = hp::smr::tls()->hazards_.alloc(); + } + + void free_guard() + { + if ( guard_ ) { + hp::smr::tls()->hazards_.free( guard_ ); + guard_ = nullptr; + } + } + //@endcond + + private: + //@cond + hp::guard* guard_; + //@endcond + }; + + public: + /// \p scan() type + enum class scan_type { + classic = hp::classic, ///< classic scan as described in Michael's papers + inplace = hp::inplace ///< inplace scan without allocation + }; + + /// Initializes %HP singleton + /** + The constructor initializes Hazard Pointer SMR singleton with passed parameters. + If the instance does not yet exist then the function creates the instance. + Otherwise it does nothing. + + The Michael's %HP reclamation schema depends of three parameters: + - \p nHazardPtrCount - hazard pointer count per thread. Usually it is small number (up to 10) depending from + the data structure algorithms. If \p nHazardPtrCount = 0, the defaul value 8 is used + - \p nMaxThreadCount - max count of thread with using Hazard Pointer GC in your application. Default is 100. + - \p nMaxRetiredPtrCount - capacity of array of retired pointers for each thread. Must be greater than + nHazardPtrCount * nMaxThreadCount . Default is 2 * nHazardPtrCount * nMaxThreadCount . + */ + HP( + size_t nHazardPtrCount = 0, ///< Hazard pointer count per thread + size_t nMaxThreadCount = 0, ///< Max count of simultaneous working thread in your application + size_t nMaxRetiredPtrCount = 0, ///< Capacity of the array of retired objects for the thread + scan_type nScanType = scan_type::inplace ///< Scan type (see \p scan_type enum) + ) + { + hp::smr::construct( + nHazardPtrCount, + nMaxThreadCount, + nMaxRetiredPtrCount, + static_cast(nScanType) + ); + } + + /// Terminates GC singleton + /** + The destructor destroys %HP global object. After calling of this function you may \b NOT + use CDS data structures based on \p %cds::gc::HP. + Usually, %HP object is destroyed at the end of your \p main(). + */ + ~HP() + { + hp::smr::destruct( true ); + } + + /// Checks that required hazard pointer count \p nCountNeeded is less or equal then max hazard pointer count + /** + If nRequiredCount > get_hazard_ptr_count() then the exception \p not_enought_hazard_ptr is thrown + */ + static void check_available_guards( size_t nCountNeeded ) + { + hp::smr::check_hazard_ptr_count( nCountNeeded ); + } + + /// Set memory management functions + /** + @note This function may be called BEFORE creating an instance + of Hazard Pointer SMR + + SMR object allocates some memory for thread-specific data and for + creating SMR object. + By default, a standard \p new and \p delete operators are used for this. + */ + static void set_memory_allocator( + void* ( *alloc_func )( size_t size ), ///< \p malloc() function + void( *free_func )( void * p ) ///< \p free() function + ) + { + hp::smr::set_memory_allocator( alloc_func, free_func ); + } + + /// Returns max Hazard Pointer count + static size_t max_hazard_count() + { + return hp::smr::instance().get_hazard_ptr_count(); + } + + /// Returns max count of thread + static size_t max_thread_count() + { + return hp::smr::instance().get_max_thread_count(); + } + + /// Returns capacity of retired pointer array + static size_t retired_array_capacity() + { + return hp::smr::instance().get_max_retired_ptr_count(); + } + + /// Retire pointer \p p with function \p func + /** + The function places pointer \p p to array of pointers ready for removing. + (so called retired pointer array). The pointer can be safely removed when no hazard pointer points to it. + \p func is a disposer: when \p p can be safely removed, \p func is called. + */ + template + static void retire( T * p, void( *func )( T * )) + { + hp::thread_data* rec = hp::smr::tls(); + if ( !rec->retired_.push( hp::retired_ptr( p, func ))) + hp::smr::instance().scan( rec ); + } + + /// Retire pointer \p p with functor of type \p Disposer + /** + The function places pointer \p p to array of pointers ready for removing. + (so called retired pointer array). The pointer can be safely removed when no hazard pointer points to it. + + Deleting the pointer is an invocation of some object of type \p Disposer; the interface of \p Disposer is: + \code + template + struct disposer { + void operator()( T * p ) ; // disposing operator + }; + \endcode + Since the functor call can happen at any time after \p retire() call, additional restrictions are imposed to \p Disposer type: + - it should be stateless functor + - it should be default-constructible + - the result of functor call with argument \p p should not depend on where the functor will be called. + + \par Examples: + Operator \p delete functor: + \code + template + struct disposer { + void operator ()( T * p ) { + delete p; + } + }; + + // How to call HP::retire method + int * p = new int; + + // ... use p in lock-free manner + + cds::gc::HP::retire( p ) ; // place p to retired pointer array of HP GC + \endcode + + Functor based on \p std::allocator : + \code + template > + struct disposer { + template + void operator()( T * p ) { + typedef typename Alloc::templare rebind::other alloc_t; + alloc_t a; + a.destroy( p ); + a.deallocate( p, 1 ); + } + }; + \endcode + */ + template + static void retire( T * p ) + { + if ( !hp::smr::tls()->retired_.push( hp::retired_ptr( p, cds::details::static_functor::call ))) + scan(); + } + + /// Get current scan strategy + static scan_type getScanType() + { + return static_cast( hp::smr::instance().get_scan_type()); + } + + /// Checks if Hazard Pointer GC is constructed and may be used + static bool isUsed() + { + return hp::smr::isUsed(); + } + + /// Forces SMR call for current thread + /** + Usually, this function should not be called directly. + */ + static void scan() + { + hp::smr::instance().scan( hp::smr::tls()); + } + + /// Synonym for \p scan() + static void force_dispose() + { + scan(); + } + + /// Returns internal statistics + /** + The function clears \p st before gathering statistics. + + @note Internal statistics is available only if you compile + \p libcds and your program with \p -DCDS_ENABLE_HPSTAT key. + */ + static void statistics( stat& st ) + { + hp::smr::instance().statistics( st ); + } + + /// Returns post-mortem statistics + /** + Post-mortem statistics is gathered in the \p %HP object destructor + and can be accessible after destructing the global \p %HP object. + + @note Internal statistics is available only if you compile + \p libcds and your program with \p -DCDS_ENABLE_HPSTAT key. + + Usage: + \code + int main() + { + cds::Initialize(); + { + // Initialize HP SMR + cds::gc::HP hp; + + // deal with HP-based data structured + // ... + } + + // HP object destroyed + // Get total post-mortem statistics + cds::gc::HP::stat const& st = cds::gc::HP::postmortem_statistics(); + + printf( "HP statistics:\n" + "\tthread count = %llu\n" + "\tguard allocated = %llu\n" + "\tguard freed = %llu\n" + "\tretired data count = %llu\n" + "\tfree data count = %llu\n" + "\tscan() call count = %llu\n" + "\thelp_scan() call count = %llu\n", + st.thread_rec_count, + st.guard_allocated, st.guard_freed, + st.retired_count, st.free_count, + st.scan_count, st.help_scan_count + ); + + cds::Terminate(); + } + \endcode + */ + static stat const& postmortem_statistics(); + }; + +}} // namespace cds::gc + +#endif // #ifndef CDSLIB_GC_HP_SMR_H + diff --git a/cds/gc/impl/dhp_decl.h b/cds/gc/impl/dhp_decl.h deleted file mode 100644 index c87a4e03..00000000 --- a/cds/gc/impl/dhp_decl.h +++ /dev/null @@ -1,823 +0,0 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef CDSLIB_GC_IMPL_DHP_DECL_H -#define CDSLIB_GC_IMPL_DHP_DECL_H - -#include -#include -#include - -namespace cds { namespace gc { - - /// Dynamic Hazard Pointer garbage collector - /** @ingroup cds_garbage_collector - @headerfile cds/gc/dhp.h - - Implementation of Dynamic Hazard Pointer garbage collector. - - Sources: - - [2002] Maged M.Michael "Safe memory reclamation for dynamic lock-freeobjects using atomic reads and writes" - - [2003] Maged M.Michael "Hazard Pointers: Safe memory reclamation for lock-free objects" - - [2004] Andrei Alexandrescy, Maged Michael "Lock-free Data Structures with Hazard Pointers" - - Dynamic Hazard Pointers SMR (safe memory reclamation) provides an unbounded number of hazard pointer per thread - despite of classic Hazard Pointer SMR in which the count of the hazard pointef per thread is limited. - - See \ref cds_how_to_use "How to use" section for details how to apply garbage collector. - */ - class DHP - { - public: - /// Native guarded pointer type - /** - @headerfile cds/gc/dhp.h - */ - typedef void * guarded_pointer; - - /// Atomic reference - /** - @headerfile cds/gc/dhp.h - */ - template using atomic_ref = atomics::atomic; - - /// Atomic type - /** - @headerfile cds/gc/dhp.h - */ - template using atomic_type = atomics::atomic; - - /// Atomic marked pointer - /** - @headerfile cds/gc/dhp.h - */ - template using atomic_marked_ptr = atomics::atomic; - - /// Thread GC implementation for internal usage - /** - @headerfile cds/gc/dhp.h - */ - typedef dhp::ThreadGC thread_gc_impl; - - /// Thread-level garbage collector - /** - @headerfile cds/gc/dhp.h - This class performs automatically attaching/detaching Dynamic Hazard Pointer GC - for the current thread. - */ - class thread_gc: public thread_gc_impl - { - //@cond - bool m_bPersistent; - //@endcond - public: - /// Constructor - /** - The constructor attaches the current thread to the Dynamic Hazard Pointer GC - if it is not yet attached. - The \p bPersistent parameter specifies attachment persistence: - - \p true - the class destructor will not detach the thread from Dynamic Hazard Pointer GC. - - \p false (default) - the class destructor will detach the thread from Dynamic Hazard Pointer GC. - */ - thread_gc( - bool bPersistent = false - ) ; // inline in dhp_impl.h - - /// Destructor - /** - If the object has been created in persistent mode, the destructor does nothing. - Otherwise it detaches the current thread from Dynamic Hazard Pointer GC. - */ - ~thread_gc() ; // inline in dhp_impl.h - - public: // for internal use only!!! - //@cond - static dhp::details::guard_data* alloc_guard(); // inline in dhp_impl.h - static void free_guard( dhp::details::guard_data* g ); // inline in dhp_impl.h - //@endcond - }; - - - /// Dynamic Hazard Pointer guard - /** - @headerfile cds/gc/dhp.h - - A guard is the hazard pointer. - Additionally, the \p %Guard class manages allocation and deallocation of the hazard pointer - - \p %Guard object is movable but not copyable. - - The guard object can be in two states: - - unlinked - the guard is not linked with any internal hazard pointer. - In this state no operation except \p link() and move assignment is supported. - - linked (default) - the guard allocates an internal hazard pointer and fully operable. - - Due to performance reason the implementation does not check state of the guard in runtime. - - @warning Move assignment can transfer the guard in unlinked state, use with care. - */ - class Guard - { - public: - /// Default ctor allocates a guard (hazard pointer) from thread-private storage - Guard() CDS_NOEXCEPT - : m_guard( thread_gc::alloc_guard()) - {} - - /// Initilalizes an unlinked guard i.e. the guard contains no hazard pointer. Used for move semantics support - explicit Guard( std::nullptr_t ) CDS_NOEXCEPT - : m_guard( nullptr ) - {} - - /// Move ctor - \p src guard becomes unlinked (transfer internal guard ownership) - Guard( Guard&& src ) CDS_NOEXCEPT - : m_guard( src.m_guard ) - { - src.m_guard = nullptr; - } - - /// Move assignment: the internal guards are swapped between \p src and \p this - /** - @warning \p src will become in unlinked state if \p this was unlinked on entry. - */ - Guard& operator=( Guard&& src ) CDS_NOEXCEPT - { - std::swap( m_guard, src.m_guard ); - return *this; - } - - /// Copy ctor is prohibited - the guard is not copyable - Guard( Guard const& ) = delete; - - /// Copy assignment is prohibited - Guard& operator=( Guard const& ) = delete; - - ~Guard() - { - if ( m_guard ) - thread_gc::free_guard( m_guard ); - } - - /// Checks if the guard object linked with any internal hazard pointer - bool is_linked() const - { - return m_guard != nullptr; - } - - /// Links the guard with internal hazard pointer if the guard is in unlinked state - void link() - { - if ( !m_guard ) - m_guard = thread_gc::alloc_guard(); - } - - /// Unlinks the guard from internal hazard pointer; the guard becomes in unlinked state - void unlink() - { - if ( m_guard ) { - thread_gc::free_guard( m_guard ); - m_guard = nullptr; - } - } - - /// Protects a pointer of type atomic - /** - Return the value of \p toGuard - - The function tries to load \p toGuard and to store it - to the HP slot repeatedly until the guard's value equals \p toGuard - */ - template - T protect( atomics::atomic const& toGuard ) - { - T pCur = toGuard.load(atomics::memory_order_acquire); - T pRet; - do { - pRet = assign( pCur ); - pCur = toGuard.load(atomics::memory_order_acquire); - } while ( pRet != pCur ); - return pCur; - } - - /// Protects a converted pointer of type atomic - /** - Return the value of \p toGuard - - The function tries to load \p toGuard and to store result of \p f functor - to the HP slot repeatedly until the guard's value equals \p toGuard. - - The function is useful for intrusive containers when \p toGuard is a node pointer - that should be converted to a pointer to the value type before guarding. - The parameter \p f of type Func is a functor that makes this conversion: - \code - struct functor { - value_type * operator()( T * p ); - }; - \endcode - Really, the result of f( toGuard.load()) is assigned to the hazard pointer. - */ - template - T protect( atomics::atomic const& toGuard, Func f ) - { - T pCur = toGuard.load(atomics::memory_order_acquire); - T pRet; - do { - pRet = pCur; - assign( f( pCur )); - pCur = toGuard.load(atomics::memory_order_acquire); - } while ( pRet != pCur ); - return pCur; - } - - /// Store \p p to the guard - /** - The function is just an assignment, no loop is performed. - Can be used for a pointer that cannot be changed concurrently - or for already guarded pointer. - */ - template - T* assign( T* p ) - { - assert( m_guard != nullptr ); - m_guard->pPost.store( p, atomics::memory_order_release ); - return p; - } - - //@cond - std::nullptr_t assign( std::nullptr_t ) - { - clear(); - return nullptr; - } - //@endcond - - /// Store marked pointer \p p to the guard - /** - The function is just an assignment of p.ptr(), no loop is performed. - Can be used for a marked pointer that cannot be changed concurrently - or for already guarded pointer. - */ - template - T* assign( cds::details::marked_ptr p ) - { - return assign( p.ptr()); - } - - /// Copy from \p src guard to \p this guard - void copy( Guard const& src ) - { - assign( src.get_native()); - } - - /// Clears value of the guard - void clear() - { - assert( m_guard != nullptr ); - m_guard->pPost.store( nullptr, atomics::memory_order_release ); - } - - /// Gets the value currently protected (relaxed read) - template - T * get() const - { - return reinterpret_cast( get_native()); - } - - /// Gets native guarded pointer stored - void* get_native() const - { - assert( m_guard != nullptr ); - return m_guard->pPost.load( atomics::memory_order_acquire ); - } - - //@cond - dhp::details::guard_data* release() - { - dhp::details::guard_data* g = m_guard; - m_guard = nullptr; - return g; - } - - dhp::details::guard_data*& guard_ref() - { - return m_guard; - } - //@endcond - - private: - //@cond - dhp::details::guard_data* m_guard; - //@endcond - }; - - /// Array of Dynamic Hazard Pointer guards - /** - @headerfile cds/gc/dhp.h - The class is intended for allocating an array of hazard pointer guards. - Template parameter \p Count defines the size of the array. - - A \p %GuardArray object is not copy- and move-constructible - and not copy- and move-assignable. - */ - template - class GuardArray - { - public: - /// Rebind array for other size \p OtherCount - template - struct rebind { - typedef GuardArray other ; ///< rebinding result - }; - - /// Array capacity - static CDS_CONSTEXPR const size_t c_nCapacity = Count; - - public: - /// Default ctor allocates \p Count hazard pointers - GuardArray(); // inline in dhp_impl.h - - /// Move ctor is prohibited - GuardArray( GuardArray&& ) = delete; - - /// Move assignment is prohibited - GuardArray& operator=( GuardArray&& ) = delete; - - /// Copy ctor is prohibited - GuardArray( GuardArray const& ) = delete; - - /// Copy assignment is prohibited - GuardArray& operator=( GuardArray const& ) = delete; - - /// Frees allocated hazard pointers - ~GuardArray(); // inline in dhp_impl.h - - /// Protects a pointer of type \p atomic - /** - Return the value of \p toGuard - - The function tries to load \p toGuard and to store it - to the slot \p nIndex repeatedly until the guard's value equals \p toGuard - */ - template - T protect( size_t nIndex, atomics::atomic const& toGuard ) - { - T pRet; - do { - pRet = assign( nIndex, toGuard.load(atomics::memory_order_acquire)); - } while ( pRet != toGuard.load(atomics::memory_order_relaxed)); - - return pRet; - } - - /// Protects a pointer of type \p atomic - /** - Return the value of \p toGuard - - The function tries to load \p toGuard and to store it - to the slot \p nIndex repeatedly until the guard's value equals \p toGuard - - The function is useful for intrusive containers when \p toGuard is a node pointer - that should be converted to a pointer to the value type before guarding. - The parameter \p f of type Func is a functor to make that conversion: - \code - struct functor { - value_type * operator()( T * p ); - }; - \endcode - Actually, the result of f( toGuard.load()) is assigned to the hazard pointer. - */ - template - T protect( size_t nIndex, atomics::atomic const& toGuard, Func f ) - { - T pRet; - do { - assign( nIndex, f( pRet = toGuard.load(atomics::memory_order_acquire))); - } while ( pRet != toGuard.load(atomics::memory_order_relaxed)); - - return pRet; - } - - /// Store \p p to the slot \p nIndex - /** - The function is just an assignment, no loop is performed. - */ - template - T * assign( size_t nIndex, T * p ) - { - assert( nIndex < capacity()); - assert( m_arr[nIndex] != nullptr ); - - m_arr[nIndex]->pPost.store( p, atomics::memory_order_release ); - return p; - } - - /// Store marked pointer \p p to the guard - /** - The function is just an assignment of p.ptr(), no loop is performed. - Can be used for a marked pointer that cannot be changed concurrently - or for already guarded pointer. - */ - template - T * assign( size_t nIndex, cds::details::marked_ptr p ) - { - return assign( nIndex, p.ptr()); - } - - /// Copy guarded value from \p src guard to slot at index \p nIndex - void copy( size_t nIndex, Guard const& src ) - { - assign( nIndex, src.get_native()); - } - - /// Copy guarded value from slot \p nSrcIndex to slot at index \p nDestIndex - void copy( size_t nDestIndex, size_t nSrcIndex ) - { - assign( nDestIndex, get_native( nSrcIndex )); - } - - /// Clear value of the slot \p nIndex - void clear( size_t nIndex ) - { - assert( nIndex < capacity()); - assert( m_arr[nIndex] != nullptr ); - - m_arr[nIndex]->pPost.store( nullptr, atomics::memory_order_release ); - } - - /// Get current value of slot \p nIndex - template - T * get( size_t nIndex ) const - { - return reinterpret_cast( get_native( nIndex )); - } - - /// Get native guarded pointer stored - guarded_pointer get_native( size_t nIndex ) const - { - assert( nIndex < capacity()); - assert( m_arr[nIndex] != nullptr ); - - return m_arr[nIndex]->pPost.load( atomics::memory_order_acquire ); - } - - //@cond - dhp::details::guard_data* release( size_t nIndex ) CDS_NOEXCEPT - { - assert( nIndex < capacity()); - - dhp::details::guard_data* ret = m_arr[ nIndex ]; - m_arr[nIndex] = nullptr; - return ret; - } - //@endcond - - /// Capacity of the guard array - static CDS_CONSTEXPR size_t capacity() - { - return Count; - } - - private: - //@cond - dhp::details::guard_data* m_arr[c_nCapacity]; - //@endcond - }; - - /// Guarded pointer - /** - A guarded pointer is a pair of a pointer and GC's guard. - Usually, it is used for returning a pointer to the item from an lock-free container. - The guard prevents the pointer to be early disposed (freed) by GC. - After destructing \p %guarded_ptr object the pointer can be disposed (freed) automatically at any time. - - Template arguments: - - \p GuardedType - a type which the guard stores - - \p ValueType - a value type - - \p Cast - a functor for converting GuardedType* to ValueType*. Default is \p void (no casting). - - For intrusive containers, \p GuardedType is the same as \p ValueType and no casting is needed. - In such case the \p %guarded_ptr is: - @code - typedef cds::gc::DHP::guarded_ptr< foo > intrusive_guarded_ptr; - @endcode - - For standard (non-intrusive) containers \p GuardedType is not the same as \p ValueType and casting is needed. - For example: - @code - struct foo { - int const key; - std::string value; - }; - - struct value_accessor { - std::string* operator()( foo* pFoo ) const - { - return &(pFoo->value); - } - }; - - // Guarded ptr - typedef cds::gc::DHP::guarded_ptr< Foo, std::string, value_accessor > nonintrusive_guarded_ptr; - @endcode - - You don't need use this class directly. - All set/map container classes from \p libcds declare the typedef for \p %guarded_ptr with appropriate casting functor. - */ - template - class guarded_ptr - { - //@cond - struct trivial_cast { - ValueType * operator()( GuardedType * p ) const - { - return p; - } - }; - - template friend class guarded_ptr; - //@endcond - - public: - typedef GuardedType guarded_type; ///< Guarded type - typedef ValueType value_type; ///< Value type - - /// Functor for casting \p guarded_type to \p value_type - typedef typename std::conditional< std::is_same::value, trivial_cast, Cast >::type value_cast; - - public: - /// Creates empty guarded pointer - guarded_ptr() CDS_NOEXCEPT - : m_guard( nullptr ) - {} - - //@cond - explicit guarded_ptr( dhp::details::guard_data* g ) CDS_NOEXCEPT - : m_guard( g ) - {} - - /// Initializes guarded pointer with \p p - explicit guarded_ptr( guarded_type * p ) CDS_NOEXCEPT - { - reset( p ); - } - explicit guarded_ptr( std::nullptr_t ) CDS_NOEXCEPT - : m_guard( nullptr ) - {} - //@endcond - - /// Move ctor - guarded_ptr( guarded_ptr&& gp ) CDS_NOEXCEPT - : m_guard( gp.m_guard ) - { - gp.m_guard = nullptr; - } - - /// Move ctor - template - guarded_ptr( guarded_ptr&& gp ) CDS_NOEXCEPT - : m_guard( gp.m_guard ) - { - gp.m_guard = nullptr; - } - - /// Ctor from \p Guard - explicit guarded_ptr( Guard&& g ) CDS_NOEXCEPT - : m_guard( g.release()) - {} - - /// The guarded pointer is not copy-constructible - guarded_ptr( guarded_ptr const& gp ) = delete; - - /// Clears the guarded pointer - /** - \ref release is called if guarded pointer is not \ref empty - */ - ~guarded_ptr() CDS_NOEXCEPT - { - release(); - } - - /// Move-assignment operator - guarded_ptr& operator=( guarded_ptr&& gp ) CDS_NOEXCEPT - { - std::swap( m_guard, gp.m_guard ); - return *this; - } - - /// Move-assignment from \p Guard - guarded_ptr& operator=( Guard&& g ) CDS_NOEXCEPT - { - std::swap( m_guard, g.guard_ref()); - return *this; - } - - /// The guarded pointer is not copy-assignable - guarded_ptr& operator=(guarded_ptr const& gp) = delete; - - /// Returns a pointer to guarded value - value_type * operator ->() const CDS_NOEXCEPT - { - assert( !empty()); - return value_cast()( reinterpret_cast(m_guard->get())); - } - - /// Returns a reference to guarded value - value_type& operator *() CDS_NOEXCEPT - { - assert( !empty()); - return *value_cast()(reinterpret_cast(m_guard->get())); - } - - /// Returns const reference to guarded value - value_type const& operator *() const CDS_NOEXCEPT - { - assert( !empty()); - return *value_cast()(reinterpret_cast(m_guard->get())); - } - - /// Checks if the guarded pointer is \p nullptr - bool empty() const CDS_NOEXCEPT - { - return m_guard == nullptr || m_guard->get( atomics::memory_order_relaxed ) == nullptr; - } - - /// \p bool operator returns !empty() - explicit operator bool() const CDS_NOEXCEPT - { - return !empty(); - } - - /// Clears guarded pointer - /** - If the guarded pointer has been released, the pointer can be disposed (freed) at any time. - Dereferncing the guarded pointer after \p release() is dangerous. - */ - void release() CDS_NOEXCEPT - { - free_guard(); - } - - //@cond - // For internal use only!!! - void reset(guarded_type * p) CDS_NOEXCEPT - { - alloc_guard(); - assert( m_guard ); - m_guard->set( p ); - } - - //@endcond - - private: - //@cond - void alloc_guard() - { - if ( !m_guard ) - m_guard = thread_gc::alloc_guard(); - } - - void free_guard() - { - if ( m_guard ) { - thread_gc::free_guard( m_guard ); - m_guard = nullptr; - } - } - //@endcond - - private: - //@cond - dhp::details::guard_data* m_guard; - //@endcond - }; - - public: - /// Initializes %DHP memory manager singleton - /** - Constructor creates and initializes %DHP global object. - %DHP object should be created before using CDS data structure based on \p %cds::gc::DHP GC. Usually, - it is created in the \p main() function. - After creating of global object you may use CDS data structures based on \p %cds::gc::DHP. - - \par Parameters - - \p nLiberateThreshold - \p scan() threshold. When count of retired pointers reaches this value, - the \p scan() member function would be called for freeing retired pointers. - - \p nInitialThreadGuardCount - initial count of guard allocated for each thread. - When a thread is initialized the GC allocates local guard pool for the thread from common guard pool. - By perforce the local thread's guard pool is grown automatically from common pool. - When the thread terminated its guard pool is backed to common GC's pool. - - \p nEpochCount: internally, DHP memory manager uses epoch-based schema to solve - ABA problem for internal data. \p nEpochCount specifies the epoch count, - i.e. the count of simultaneously working threads that remove the elements - of DHP-based concurrent data structure. Default value is 16. - */ - DHP( - size_t nLiberateThreshold = 1024 - , size_t nInitialThreadGuardCount = 8 - , size_t nEpochCount = 16 - ) - { - dhp::GarbageCollector::Construct( nLiberateThreshold, nInitialThreadGuardCount, nEpochCount ); - } - - /// Destroys %DHP memory manager - /** - The destructor destroys %DHP global object. After calling of this function you may \b NOT - use CDS data structures based on \p %cds::gc::DHP. - Usually, %DHP object is destroyed at the end of your \p main(). - */ - ~DHP() - { - dhp::GarbageCollector::Destruct(); - } - - /// Checks if count of hazard pointer is no less than \p nCountNeeded - /** - The function always returns \p true since the guard count is unlimited for - \p %gc::DHP garbage collector. - */ - static CDS_CONSTEXPR bool check_available_guards( -#ifdef CDS_DOXYGEN_INVOKED - size_t nCountNeeded, -#else - size_t, -#endif - bool /*bRaiseException*/ = true ) - { - return true; - } - - /// Retire pointer \p p with function \p pFunc - /** - The function places pointer \p p to array of pointers ready for removing. - (so called retired pointer array). The pointer can be safely removed when no guarded pointer points to it. - Deleting the pointer is the function \p pFunc call. - */ - template - static void retire( T * p, void (* pFunc)(T *)) - { - dhp::GarbageCollector::instance().retirePtr( p, pFunc ); - } - - /// Retire pointer \p p with functor of type \p Disposer - /** - The function places pointer \p p to array of pointers ready for removing. - (so called retired pointer array). The pointer can be safely removed when no guarded pointer points to it. - - See \p gc::HP::retire for \p Disposer requirements. - */ - template - static void retire( T * p ) - { - retire( p, cds::details::static_functor::call ); - } - - /// Checks if Dynamic Hazard Pointer GC is constructed and may be used - static bool isUsed() - { - return dhp::GarbageCollector::isUsed(); - } - - /// Forced GC cycle call for current thread - /** - Usually, this function should not be called directly. - */ - static void scan() ; // inline in dhp_impl.h - - /// Synonym for \ref scan() - static void force_dispose() - { - scan(); - } - }; - -}} // namespace cds::gc - -#endif // #ifndef CDSLIB_GC_IMPL_DHP_DECL_H diff --git a/cds/gc/impl/dhp_impl.h b/cds/gc/impl/dhp_impl.h deleted file mode 100644 index 843276ec..00000000 --- a/cds/gc/impl/dhp_impl.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef CDSLIB_GC_IMPL_DHP_IMPL_H -#define CDSLIB_GC_IMPL_DHP_IMPL_H - -#include - -//@cond -namespace cds { namespace gc { - - namespace dhp { - - static inline ThreadGC& get_thread_gc() - { - return cds::threading::getGC(); - } - - //inline Guard::Guard() - //{ - // cds::threading::getGC().allocGuard( *this ); - //} - - //inline Guard::~Guard() - //{ - // cds::threading::getGC().freeGuard( *this ); - //} - - //template - //inline GuardArray::GuardArray() - //{ - // cds::threading::getGC().allocGuard( *this ); - //} - - //template - //inline GuardArray::~GuardArray() - //{ - // cds::threading::getGC().freeGuard( *this ); - //} - } // namespace dhp - - - inline DHP::thread_gc::thread_gc( - bool bPersistent - ) - : m_bPersistent( bPersistent ) - { - if ( !cds::threading::Manager::isThreadAttached()) - cds::threading::Manager::attachThread(); - } - - inline DHP::thread_gc::~thread_gc() - { - if ( !m_bPersistent ) - cds::threading::Manager::detachThread(); - } - - inline /*static*/ dhp::details::guard_data* DHP::thread_gc::alloc_guard() - { - return dhp::get_thread_gc().allocGuard(); - } - inline /*static*/ void DHP::thread_gc::free_guard( dhp::details::guard_data* g ) - { - if ( g ) - dhp::get_thread_gc().freeGuard( g ); - } - - template - inline DHP::GuardArray::GuardArray() - { - dhp::get_thread_gc().allocGuard( m_arr ); - } - - template - inline DHP::GuardArray::~GuardArray() - { - dhp::get_thread_gc().freeGuard( m_arr ); - } - - inline void DHP::scan() - { - cds::threading::getGC().scan(); - } - -}} // namespace cds::gc -//@endcond - -#endif // #ifndef CDSLIB_GC_IMPL_DHP_IMPL_H diff --git a/cds/gc/impl/hp_decl.h b/cds/gc/impl/hp_decl.h deleted file mode 100644 index 82d21e3d..00000000 --- a/cds/gc/impl/hp_decl.h +++ /dev/null @@ -1,883 +0,0 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef CDSLIB_GC_IMPL_HP_DECL_H -#define CDSLIB_GC_IMPL_HP_DECL_H - -#include // overflow_error -#include -#include - -namespace cds { namespace gc { - /// @defgroup cds_garbage_collector Garbage collectors - - /// Hazard Pointer garbage collector - /** @ingroup cds_garbage_collector - @headerfile cds/gc/hp.h - - Implementation of classic Hazard Pointer garbage collector. - - Sources: - - [2002] Maged M.Michael "Safe memory reclamation for dynamic lock-freeobjects using atomic reads and writes" - - [2003] Maged M.Michael "Hazard Pointers: Safe memory reclamation for lock-free objects" - - [2004] Andrei Alexandrescy, Maged Michael "Lock-free Data Structures with Hazard Pointers" - - Hazard Pointer garbage collector is a singleton. The main user-level part of Hazard Pointer schema is - GC class \p %cds::gc::HP and its nested classes. Before use any HP-related class you must initialize HP garbage collector - by contructing \p %cds::gc::HP object in beginning of your \p main(). - See \ref cds_how_to_use "How to use" section for details how to apply garbage collector. - */ - class HP - { - public: - /// Native guarded pointer type - /** - @headerfile cds/gc/hp.h - */ - typedef gc::hp::hazard_pointer guarded_pointer; - - /// Atomic reference - /** - @headerfile cds/gc/hp.h - */ - template using atomic_ref = atomics::atomic; - - /// Atomic marked pointer - /** - @headerfile cds/gc/hp.h - */ - template using atomic_marked_ptr = atomics::atomic; - - /// Atomic type - /** - @headerfile cds/gc/hp.h - */ - template using atomic_type = atomics::atomic; - - /// Thread GC implementation for internal usage - /** - @headerfile cds/gc/hp.h - */ - typedef hp::ThreadGC thread_gc_impl; - - /// Exception "Too many Hazard Pointer" - typedef hp::GarbageCollector::too_many_hazard_ptr too_many_hazard_ptr_exception; - - /// Wrapper for hp::ThreadGC class - /** - @headerfile cds/gc/hp.h - This class performs automatically attaching/detaching Hazard Pointer GC - for the current thread. - */ - class thread_gc: public thread_gc_impl - { - //@cond - bool m_bPersistent; - //@endcond - public: - - /// Constructor - /** - The constructor attaches the current thread to the Hazard Pointer GC - if it is not yet attached. - The \p bPersistent parameter specifies attachment persistence: - - \p true - the class destructor will not detach the thread from Hazard Pointer GC. - - \p false (default) - the class destructor will detach the thread from Hazard Pointer GC. - */ - thread_gc( - bool bPersistent = false - ) ; //inline in hp_impl.h - - /// Destructor - /** - If the object has been created in persistent mode, the destructor does nothing. - Otherwise it detaches the current thread from Hazard Pointer GC. - */ - ~thread_gc() ; // inline in hp_impl.h - - public: // for internal use only!!! - //@cond - static cds::gc::hp::details::hp_guard* alloc_guard(); // inline in hp_impl.h - static void free_guard( cds::gc::hp::details::hp_guard* g ); // inline in hp_impl.h - //@endcond - }; - - /// Hazard Pointer guard - /** - @headerfile cds/gc/hp.h - - A guard is a hazard pointer. - Additionally, the \p %Guard class manages allocation and deallocation of the hazard pointer. - - \p %Guard object is movable but not copyable. - - The guard object can be in two states: - - unlinked - the guard is not linked with any internal hazard pointer. - In this state no operation except \p link() and move assignment is supported. - - linked (default) - the guard allocates an internal hazard pointer and fully operable. - - Due to performance reason the implementation does not check state of the guard in runtime. - - @warning Move assignment can transfer the guard in unlinked state, use with care. - */ - class Guard - { - public: - /// Default ctor allocates a guard (hazard pointer) from thread-private storage - /** - @warning Can throw \p too_many_hazard_ptr_exception if internal hazard pointer objects are exhausted. - */ - Guard(); // inline in hp_impl.h - - /// Initilalizes an unlinked guard i.e. the guard contains no hazard pointer. Used for move semantics support - explicit Guard( std::nullptr_t ) CDS_NOEXCEPT - : m_guard( nullptr ) - {} - - /// Move ctor - \p src guard becomes unlinked (transfer internal guard ownership) - Guard( Guard&& src ) CDS_NOEXCEPT - : m_guard( src.m_guard ) - { - src.m_guard = nullptr; - } - - /// Move assignment: the internal guards are swapped between \p src and \p this - /** - @warning \p src will become in unlinked state if \p this was unlinked on entry. - */ - Guard& operator=( Guard&& src ) CDS_NOEXCEPT - { - std::swap( m_guard, src.m_guard ); - return *this; - } - - /// Copy ctor is prohibited - the guard is not copyable - Guard( Guard const& ) = delete; - - /// Copy assignment is prohibited - Guard& operator=( Guard const& ) = delete; - - /// Frees the internal hazard pointer if the guard is in linked state - ~Guard() - { - unlink(); - } - - /// Checks if the guard object linked with any internal hazard pointer - bool is_linked() const - { - return m_guard != nullptr; - } - - /// Links the guard with internal hazard pointer if the guard is in unlinked state - /** - @warning Can throw \p too_many_hazard_ptr_exception if internal hazard pointer objects are exhausted. - */ - void link(); // inline in hp_impl.h - - /// Unlinks the guard from internal hazard pointer; the guard becomes in unlinked state - void unlink(); // inline in hp_impl.h - - /// Protects a pointer of type \p atomic - /** - Return the value of \p toGuard - - The function tries to load \p toGuard and to store it - to the HP slot repeatedly until the guard's value equals \p toGuard - - @warning The guad object should be in linked state, otherwise the result is undefined - */ - template - T protect( atomics::atomic const& toGuard ) - { - assert( m_guard != nullptr ); - - T pCur = toGuard.load(atomics::memory_order_acquire); - T pRet; - do { - pRet = assign( pCur ); - pCur = toGuard.load(atomics::memory_order_acquire); - } while ( pRet != pCur ); - return pCur; - } - - /// Protects a converted pointer of type \p atomic - /** - Return the value of \p toGuard - - The function tries to load \p toGuard and to store result of \p f functor - to the HP slot repeatedly until the guard's value equals \p toGuard. - - The function is useful for intrusive containers when \p toGuard is a node pointer - that should be converted to a pointer to the value before protecting. - The parameter \p f of type Func is a functor that makes this conversion: - \code - struct functor { - value_type * operator()( T * p ); - }; - \endcode - Actually, the result of f( toGuard.load()) is assigned to the hazard pointer. - - @warning The guad object should be in linked state, otherwise the result is undefined - */ - template - T protect( atomics::atomic const& toGuard, Func f ) - { - assert( m_guard != nullptr ); - - T pCur = toGuard.load(atomics::memory_order_acquire); - T pRet; - do { - pRet = pCur; - assign( f( pCur )); - pCur = toGuard.load(atomics::memory_order_acquire); - } while ( pRet != pCur ); - return pCur; - } - - /// Store \p p to the guard - /** - The function equals to a simple assignment the value \p p to guard, no loop is performed. - Can be used for a pointer that cannot be changed concurrently - - @warning The guad object should be in linked state, otherwise the result is undefined - */ - template - T * assign( T* p ); // inline in hp_impl.h - - //@cond - std::nullptr_t assign( std::nullptr_t ) - { - assert(m_guard != nullptr ); - return *m_guard = nullptr; - } - //@endcond - - /// Copy a value guarded from \p src guard to \p this guard (valid only in linked state) - void copy( Guard const& src ) - { - assign( src.get_native()); - } - - /// Store marked pointer \p p to the guard - /** - The function equals to a simple assignment of p.ptr(), no loop is performed. - Can be used for a marked pointer that cannot be changed concurrently. - - @warning The guad object should be in linked state, otherwise the result is undefined - */ - template - T * assign( cds::details::marked_ptr p ) - { - return assign( p.ptr()); - } - - /// Clear value of the guard (valid only in linked state) - void clear() - { - assign( nullptr ); - } - - /// Get the value currently protected (valid only in linked state) - template - T * get() const - { - return reinterpret_cast( get_native()); - } - - /// Get native hazard pointer stored (valid only in linked state) - guarded_pointer get_native() const - { - assert( m_guard != nullptr ); - return m_guard->get(); - } - - //@cond - hp::details::hp_guard* release() - { - hp::details::hp_guard* g = m_guard; - m_guard = nullptr; - return g; - } - - hp::details::hp_guard*& guard_ref() - { - return m_guard; - } - //@endcond - - private: - //@cond - hp::details::hp_guard* m_guard; - //@endcond - }; - - /// Array of Hazard Pointer guards - /** - @headerfile cds/gc/hp.h - The class is intended for allocating an array of hazard pointer guards. - Template parameter \p Count defines the size of the array. - - */ - template - class GuardArray - { - public: - /// Rebind array for other size \p Count2 - template - struct rebind { - typedef GuardArray other; ///< rebinding result - }; - - /// Array capacity - static CDS_CONSTEXPR const size_t c_nCapacity = Count; - - public: - /// Default ctor allocates \p Count hazard pointers - GuardArray(); // inline in hp_impl.h - - /// Move ctor is prohibited - GuardArray( GuardArray&& ) = delete; - - /// Move assignment is prohibited - GuardArray& operator=( GuardArray&& ) = delete; - - /// Copy ctor is prohibited - GuardArray( GuardArray const& ) = delete; - - /// Copy assignment is prohibited - GuardArray& operator=( GuardArray const& ) = delete; - - /// Frees allocated hazard pointers - ~GuardArray(); // inline in hp_impl.h - - /// Protects a pointer of type \p atomic - /** - Return the value of \p toGuard - - The function tries to load \p toGuard and to store it - to the slot \p nIndex repeatedly until the guard's value equals \p toGuard - */ - template - T protect( size_t nIndex, atomics::atomic const& toGuard ) - { - assert( nIndex < capacity()); - - T pRet; - do { - pRet = assign( nIndex, toGuard.load(atomics::memory_order_acquire)); - } while ( pRet != toGuard.load(atomics::memory_order_acquire)); - - return pRet; - } - - /// Protects a pointer of type \p atomic - /** - Return the value of \p toGuard - - The function tries to load \p toGuard and to store it - to the slot \p nIndex repeatedly until the guard's value equals \p toGuard - - The function is useful for intrusive containers when \p toGuard is a node pointer - that should be converted to a pointer to the value type before guarding. - The parameter \p f of type Func is a functor that makes this conversion: - \code - struct functor { - value_type * operator()( T * p ); - }; - \endcode - Really, the result of f( toGuard.load()) is assigned to the hazard pointer. - */ - template - T protect( size_t nIndex, atomics::atomic const& toGuard, Func f ) - { - assert( nIndex < capacity()); - - T pRet; - do { - assign( nIndex, f( pRet = toGuard.load(atomics::memory_order_acquire))); - } while ( pRet != toGuard.load(atomics::memory_order_acquire)); - - return pRet; - } - - /// Store \p to the slot \p nIndex - /** - The function equals to a simple assignment, no loop is performed. - */ - template - T * assign( size_t nIndex, T * p ); // inline in hp_impl.h - - /// Store marked pointer \p p to the guard - /** - The function equals to a simple assignment of p.ptr(), no loop is performed. - Can be used for a marked pointer that cannot be changed concurrently. - */ - template - T * assign( size_t nIndex, cds::details::marked_ptr p ) - { - return assign( nIndex, p.ptr()); - } - - /// Copy guarded value from \p src guard to slot at index \p nIndex - void copy( size_t nIndex, Guard const& src ) - { - assign( nIndex, src.get_native()); - } - - /// Copy guarded value from slot \p nSrcIndex to the slot \p nDestIndex - void copy( size_t nDestIndex, size_t nSrcIndex ) - { - assign( nDestIndex, get_native( nSrcIndex )); - } - - /// Clear value of the slot \p nIndex - void clear( size_t nIndex ) - { - m_arr.clear( nIndex ); - } - - /// Get current value of slot \p nIndex - template - T * get( size_t nIndex ) const - { - return reinterpret_cast( get_native( nIndex )); - } - - /// Get native hazard pointer stored - guarded_pointer get_native( size_t nIndex ) const - { - assert( nIndex < capacity()); - return m_arr[nIndex]->get(); - } - - //@cond - hp::details::hp_guard* release( size_t nIndex ) CDS_NOEXCEPT - { - return m_arr.release( nIndex ); - } - //@endcond - - /// Capacity of the guard array - static CDS_CONSTEXPR size_t capacity() - { - return c_nCapacity; - } - - private: - //@cond - hp::details::hp_array m_arr; - //@endcond - }; - - /// Guarded pointer - /** - A guarded pointer is a pair of a pointer and GC's guard. - Usually, it is used for returning a pointer to the item from an lock-free container. - The guard prevents the pointer to be early disposed (freed) by GC. - After destructing \p %guarded_ptr object the pointer can be disposed (freed) automatically at any time. - - Template arguments: - - \p GuardedType - a type which the guard stores - - \p ValueType - a value type - - \p Cast - a functor for converting GuardedType* to ValueType*. Default is \p void (no casting). - - For intrusive containers, \p GuardedType is the same as \p ValueType and no casting is needed. - In such case the \p %guarded_ptr is: - @code - typedef cds::gc::HP::guarded_ptr< foo > intrusive_guarded_ptr; - @endcode - - For standard (non-intrusive) containers \p GuardedType is not the same as \p ValueType and casting is needed. - For example: - @code - struct foo { - int const key; - std::string value; - }; - - struct value_accessor { - std::string* operator()( foo* pFoo ) const - { - return &(pFoo->value); - } - }; - - // Guarded ptr - typedef cds::gc::HP::guarded_ptr< Foo, std::string, value_accessor > nonintrusive_guarded_ptr; - @endcode - - You don't need use this class directly. - All set/map container classes from \p libcds declare the typedef for \p %guarded_ptr with appropriate casting functor. - */ - template - class guarded_ptr - { - //@cond - struct trivial_cast { - ValueType * operator()( GuardedType * p ) const - { - return p; - } - }; - - template friend class guarded_ptr; - //@endcond - - public: - typedef GuardedType guarded_type; ///< Guarded type - typedef ValueType value_type; ///< Value type - - /// Functor for casting \p guarded_type to \p value_type - typedef typename std::conditional< std::is_same::value, trivial_cast, Cast >::type value_cast; - - public: - /// Creates empty guarded pointer - guarded_ptr() CDS_NOEXCEPT - : m_pGuard(nullptr) - {} - - //@cond - explicit guarded_ptr( hp::details::hp_guard* g ) CDS_NOEXCEPT - : m_pGuard( g ) - {} - - /// Initializes guarded pointer with \p p - explicit guarded_ptr( guarded_type* p ) CDS_NOEXCEPT - : m_pGuard( nullptr ) - { - reset(p); - } - explicit guarded_ptr( std::nullptr_t ) CDS_NOEXCEPT - : m_pGuard( nullptr ) - {} - //@endcond - - /// Move ctor - guarded_ptr( guarded_ptr&& gp ) CDS_NOEXCEPT - : m_pGuard( gp.m_pGuard ) - { - gp.m_pGuard = nullptr; - } - - /// Move ctor - template - guarded_ptr( guarded_ptr&& gp ) CDS_NOEXCEPT - : m_pGuard( gp.m_pGuard ) - { - gp.m_pGuard = nullptr; - } - - /// Ctor from \p Guard - explicit guarded_ptr( Guard&& g ) CDS_NOEXCEPT - : m_pGuard( g.release()) - {} - - /// The guarded pointer is not copy-constructible - guarded_ptr( guarded_ptr const& gp ) = delete; - - /// Clears the guarded pointer - /** - \ref release() is called if guarded pointer is not \ref empty() - */ - ~guarded_ptr() CDS_NOEXCEPT - { - release(); - } - - /// Move-assignment operator - guarded_ptr& operator=( guarded_ptr&& gp ) CDS_NOEXCEPT - { - std::swap( m_pGuard, gp.m_pGuard ); - return *this; - } - - /// Move-assignment from \p Guard - guarded_ptr& operator=( Guard&& g ) CDS_NOEXCEPT - { - std::swap( m_pGuard, g.guard_ref()); - return *this; - } - - /// The guarded pointer is not copy-assignable - guarded_ptr& operator=(guarded_ptr const& gp) = delete; - - /// Returns a pointer to guarded value - value_type * operator ->() const CDS_NOEXCEPT - { - assert( !empty()); - return value_cast()( reinterpret_cast(m_pGuard->get())); - } - - /// Returns a reference to guarded value - value_type& operator *() CDS_NOEXCEPT - { - assert( !empty()); - return *value_cast()(reinterpret_cast(m_pGuard->get())); - } - - /// Returns const reference to guarded value - value_type const& operator *() const CDS_NOEXCEPT - { - assert( !empty()); - return *value_cast()(reinterpret_cast(m_pGuard->get())); - } - - /// Checks if the guarded pointer is \p nullptr - bool empty() const CDS_NOEXCEPT - { - return !m_pGuard || m_pGuard->get( atomics::memory_order_relaxed ) == nullptr; - } - - /// \p bool operator returns !empty() - explicit operator bool() const CDS_NOEXCEPT - { - return !empty(); - } - - /// Clears guarded pointer - /** - If the guarded pointer has been released, the pointer can be disposed (freed) at any time. - Dereferncing the guarded pointer after \p release() is dangerous. - */ - void release() CDS_NOEXCEPT - { - free_guard(); - } - - //@cond - // For internal use only!!! - void reset(guarded_type * p) CDS_NOEXCEPT - { - alloc_guard(); - assert( m_pGuard ); - m_pGuard->set(p); - } - //@endcond - - private: - //@cond - void alloc_guard() - { - if ( !m_pGuard ) - m_pGuard = thread_gc::alloc_guard(); - } - - void free_guard() - { - if ( m_pGuard ) { - thread_gc::free_guard( m_pGuard ); - m_pGuard = nullptr; - } - } - //@endcond - - private: - //@cond - hp::details::hp_guard* m_pGuard; - //@endcond - }; - - public: - /// \p scan() type - enum class scan_type { - classic = hp::classic, ///< classic scan as described in Michael's papers - inplace = hp::inplace ///< inplace scan without allocation - }; - /// Initializes %HP singleton - /** - The constructor initializes GC singleton with passed parameters. - If GC instance is not exist then the function creates the instance. - Otherwise it does nothing. - - The Michael's %HP reclamation schema depends of three parameters: - - \p nHazardPtrCount - hazard pointer count per thread. Usually it is small number (up to 10) depending from - the data structure algorithms. By default, if \p nHazardPtrCount = 0, the function - uses maximum of the hazard pointer count for CDS library. - - \p nMaxThreadCount - max count of thread with using Hazard Pointer GC in your application. Default is 100. - - \p nMaxRetiredPtrCount - capacity of array of retired pointers for each thread. Must be greater than - nHazardPtrCount * nMaxThreadCount . Default is 2 * nHazardPtrCount * nMaxThreadCount . - */ - HP( - size_t nHazardPtrCount = 0, ///< Hazard pointer count per thread - size_t nMaxThreadCount = 0, ///< Max count of simultaneous working thread in your application - size_t nMaxRetiredPtrCount = 0, ///< Capacity of the array of retired objects for the thread - scan_type nScanType = scan_type::inplace ///< Scan type (see \p scan_type enum) - ) - { - hp::GarbageCollector::Construct( - nHazardPtrCount, - nMaxThreadCount, - nMaxRetiredPtrCount, - static_cast(nScanType) - ); - } - - /// Terminates GC singleton - /** - The destructor destroys %HP global object. After calling of this function you may \b NOT - use CDS data structures based on \p %cds::gc::HP. - Usually, %HP object is destroyed at the end of your \p main(). - */ - ~HP() - { - hp::GarbageCollector::Destruct( true ); - } - - /// Checks if count of hazard pointer is no less than \p nCountNeeded - /** - If \p bRaiseException is \p true (that is the default), the function raises - an \p std::overflow_error exception "Too few hazard pointers" - if \p nCountNeeded is more than the count of hazard pointer per thread. - */ - static bool check_available_guards( size_t nCountNeeded, bool bRaiseException = true ) - { - if ( hp::GarbageCollector::instance().getHazardPointerCount() < nCountNeeded ) { - if ( bRaiseException ) - throw std::overflow_error( "Too few hazard pointers" ); - return false; - } - return true; - } - - /// Returns max Hazard Pointer count - static size_t max_hazard_count() - { - return hp::GarbageCollector::instance().getHazardPointerCount(); - } - - /// Returns max count of thread - static size_t max_thread_count() - { - return hp::GarbageCollector::instance().getMaxThreadCount(); - } - - /// Returns capacity of retired pointer array - static size_t retired_array_capacity() - { - return hp::GarbageCollector::instance().getMaxRetiredPtrCount(); - } - - /// Retire pointer \p p with function \p pFunc - /** - The function places pointer \p p to array of pointers ready for removing. - (so called retired pointer array). The pointer can be safely removed when no hazard pointer points to it. - Deleting the pointer is the function \p pFunc call. - */ - template - static void retire( T * p, void (* pFunc)(T *)); // inline in hp_impl.h - - /// Retire pointer \p p with functor of type \p Disposer - /** - The function places pointer \p p to array of pointers ready for removing. - (so called retired pointer array). The pointer can be safely removed when no hazard pointer points to it. - - Deleting the pointer is an invocation of some object of type \p Disposer; the interface of \p Disposer is: - \code - template - struct disposer { - void operator()( T * p ) ; // disposing operator - }; - \endcode - Since the functor call can happen at any time after \p retire call, additional restrictions are imposed to \p Disposer type: - - it should be stateless functor - - it should be default-constructible - - the result of functor call with argument \p p should not depend on where the functor will be called. - - \par Examples: - Operator \p delete functor: - \code - template - struct disposer { - void operator ()( T * p ) { - delete p; - } - }; - - // How to call GC::retire method - int * p = new int; - - // ... use p in lock-free manner - - cds::gc::HP::retire( p ) ; // place p to retired pointer array of HP GC - \endcode - - Functor based on \p std::allocator : - \code - template > - struct disposer { - template - void operator()( T * p ) { - typedef typename ALLOC::templare rebind::other alloc_t; - alloc_t a; - a.destroy( p ); - a.deallocate( p, 1 ); - } - }; - \endcode - */ - template - static void retire( T * p ); // inline in hp_impl.h - - /// Get current scan strategy - static scan_type getScanType() - { - return static_cast( hp::GarbageCollector::instance().getScanType()); - } - - /// Set current scan strategy - static void setScanType( - scan_type nScanType ///< new scan strategy - ) - { - hp::GarbageCollector::instance().setScanType( static_cast(nScanType)); - } - - /// Checks if Hazard Pointer GC is constructed and may be used - static bool isUsed() - { - return hp::GarbageCollector::isUsed(); - } - - /// Forced GC cycle call for current thread - /** - Usually, this function should not be called directly. - */ - static void scan() ; // inline in hp_impl.h - - /// Synonym for \ref scan() - static void force_dispose() - { - scan(); - } - }; -}} // namespace cds::gc - -#endif // #ifndef CDSLIB_GC_IMPL_HP_DECL_H diff --git a/cds/gc/impl/hp_impl.h b/cds/gc/impl/hp_impl.h deleted file mode 100644 index 31cff44b..00000000 --- a/cds/gc/impl/hp_impl.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef CDSLIB_GC_IMPL_HP_IMPL_H -#define CDSLIB_GC_IMPL_HP_IMPL_H - -#include -#include - -//@cond -namespace cds { namespace gc { - - namespace hp { - static inline ThreadGC& get_thread_gc() - { - return cds::threading::getGC(); - } - } // namespace hp - - inline HP::thread_gc::thread_gc( - bool bPersistent - ) - : m_bPersistent( bPersistent ) - { - if ( !threading::Manager::isThreadAttached()) - threading::Manager::attachThread(); - } - - inline HP::thread_gc::~thread_gc() - { - if ( !m_bPersistent ) - cds::threading::Manager::detachThread(); - } - - inline /*static*/ cds::gc::hp::details::hp_guard* HP::thread_gc::alloc_guard() - { - return hp::get_thread_gc().allocGuard(); - } - - inline /*static*/ void HP::thread_gc::free_guard( cds::gc::hp::details::hp_guard* g ) - { - hp::get_thread_gc().freeGuard( g ); - } - - inline HP::Guard::Guard() - : m_guard( hp::get_thread_gc().allocGuard()) - { - if ( !m_guard ) - throw too_many_hazard_ptr_exception(); - } - - template - inline T * HP::Guard::assign( T * p ) - { - assert( m_guard != nullptr ); - - T * pp = ( *m_guard = p ); - hp::get_thread_gc().sync(); - return pp; - } - - inline void HP::Guard::link() - { - if ( !m_guard ) { - m_guard = hp::get_thread_gc().allocGuard(); - if ( !m_guard ) - throw too_many_hazard_ptr_exception(); - } - } - - inline void HP::Guard::unlink() - { - if ( m_guard ) { - hp::get_thread_gc().freeGuard( m_guard ); - m_guard = nullptr; - } - } - - template - inline HP::GuardArray::GuardArray() - { - if ( hp::get_thread_gc().allocGuard( m_arr ) != Count ) - throw too_many_hazard_ptr_exception(); - } - - template - inline HP::GuardArray::~GuardArray() - { - hp::get_thread_gc().freeGuard( m_arr ); - } - - template - template - inline T * HP::GuardArray::assign( size_t nIndex, T* p ) - { - assert( nIndex < capacity()); - - m_arr.set(nIndex, p); - hp::get_thread_gc().sync(); - return p; - } - - template - inline void HP::retire( T * p, void (* pFunc)(T *)) - { - cds::threading::getGC().retirePtr( p, pFunc ); - } - - template - inline void HP::retire( T * p ) - { - hp::get_thread_gc().retirePtr( p, cds::details::static_functor::call ); - } - - inline void HP::scan() - { - hp::get_thread_gc().scan(); - } - -}} // namespace cds::gc -//@endcond - -#endif // #ifndef CDSLIB_GC_IMPL_HP_IMPL_H diff --git a/cds/threading/details/_common.h b/cds/threading/details/_common.h index c6f10231..69b73f1c 100644 --- a/cds/threading/details/_common.h +++ b/cds/threading/details/_common.h @@ -31,9 +31,6 @@ #ifndef CDSLIB_THREADING__COMMON_H #define CDSLIB_THREADING__COMMON_H -#include -#include - #include #include #include @@ -99,9 +96,6 @@ namespace cds { // (called by dtor of GC thread object, for example, by dtor of cds::gc::HP::thread_gc) static void detachThread(); - // Get cds::gc::HP thread GC implementation for current thread - static gc::HP::thread_gc_impl& getHZPGC(); - // Get cds::gc::DHP thread GC implementation for current thread; static gc::DHP::thread_gc_impl& getDHPGC(); }; @@ -137,9 +131,6 @@ namespace cds { struct ThreadData { //@cond - char CDS_DATA_ALIGNMENT(8) m_hpManagerPlaceholder[sizeof(cds::gc::HP::thread_gc_impl)]; ///< Michael's Hazard Pointer GC placeholder - char CDS_DATA_ALIGNMENT(8) m_dhpManagerPlaceholder[sizeof(cds::gc::DHP::thread_gc_impl)]; ///< Dynamic Hazard Pointer GC placeholder - cds::urcu::details::thread_data< cds::urcu::general_instant_tag > * m_pGPIRCU; cds::urcu::details::thread_data< cds::urcu::general_buffered_tag > * m_pGPBRCU; cds::urcu::details::thread_data< cds::urcu::general_threaded_tag > * m_pGPTRCU; @@ -150,8 +141,8 @@ namespace cds { //@endcond - cds::gc::HP::thread_gc_impl * m_hpManager ; ///< Michael's Hazard Pointer GC thread-specific data - cds::gc::DHP::thread_gc_impl * m_dhpManager ; ///< Dynamic Hazard Pointer GC thread-specific data + //cds::gc::HP::thread_gc_impl * m_hpManager ; ///< Michael's Hazard Pointer GC thread-specific data + //cds::gc::DHP::thread_gc_impl * m_dhpManager ; ///< Dynamic Hazard Pointer GC thread-specific data size_t m_nFakeProcessorNumber ; ///< fake "current processor" number @@ -164,7 +155,7 @@ namespace cds { //@cond static CDS_EXPORT_API atomics::atomic s_nLastUsedProcNo; - static CDS_EXPORT_API size_t s_nProcCount; + static CDS_EXPORT_API size_t s_nProcCount; //@endcond //@cond @@ -178,32 +169,10 @@ namespace cds { #endif , m_nFakeProcessorNumber( s_nLastUsedProcNo.fetch_add(1, atomics::memory_order_relaxed) % s_nProcCount ) , m_nAttachCount(0) - { - if (cds::gc::HP::isUsed()) - m_hpManager = new (m_hpManagerPlaceholder) cds::gc::HP::thread_gc_impl; - else - m_hpManager = nullptr; - - if ( cds::gc::DHP::isUsed()) - m_dhpManager = new (m_dhpManagerPlaceholder) cds::gc::DHP::thread_gc_impl; - else - m_dhpManager = nullptr; - } + {} ~ThreadData() { - if ( m_hpManager ) { - typedef cds::gc::HP::thread_gc_impl hp_thread_gc_impl; - m_hpManager->~hp_thread_gc_impl(); - m_hpManager = nullptr; - } - - if ( m_dhpManager ) { - typedef cds::gc::DHP::thread_gc_impl dhp_thread_gc_impl; - m_dhpManager->~dhp_thread_gc_impl(); - m_dhpManager = nullptr; - } - assert( m_pGPIRCU == nullptr ); assert( m_pGPBRCU == nullptr ); assert( m_pGPTRCU == nullptr ); @@ -213,63 +182,8 @@ namespace cds { #endif } - void init() - { - if ( m_nAttachCount++ == 0 ) { - if ( cds::gc::HP::isUsed()) - m_hpManager->init(); - if ( cds::gc::DHP::isUsed()) - m_dhpManager->init(); - - if ( cds::urcu::details::singleton::isUsed()) - m_pGPIRCU = cds::urcu::details::singleton::attach_thread(); - if ( cds::urcu::details::singleton::isUsed()) - m_pGPBRCU = cds::urcu::details::singleton::attach_thread(); - if ( cds::urcu::details::singleton::isUsed()) - m_pGPTRCU = cds::urcu::details::singleton::attach_thread(); -#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED - if ( cds::urcu::details::singleton::isUsed()) - m_pSHBRCU = cds::urcu::details::singleton::attach_thread(); - if ( cds::urcu::details::singleton::isUsed()) - m_pSHTRCU = cds::urcu::details::singleton::attach_thread(); -#endif - } - } - - bool fini() - { - if ( --m_nAttachCount == 0 ) { - if ( cds::gc::DHP::isUsed()) - m_dhpManager->fini(); - if ( cds::gc::HP::isUsed()) - m_hpManager->fini(); - - if ( cds::urcu::details::singleton::isUsed()) { - cds::urcu::details::singleton::detach_thread( m_pGPIRCU ); - m_pGPIRCU = nullptr; - } - if ( cds::urcu::details::singleton::isUsed()) { - cds::urcu::details::singleton::detach_thread( m_pGPBRCU ); - m_pGPBRCU = nullptr; - } - if ( cds::urcu::details::singleton::isUsed()) { - cds::urcu::details::singleton::detach_thread( m_pGPTRCU ); - m_pGPTRCU = nullptr; - } -#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED - if ( cds::urcu::details::singleton::isUsed()) { - cds::urcu::details::singleton::detach_thread( m_pSHBRCU ); - m_pSHBRCU = nullptr; - } - if ( cds::urcu::details::singleton::isUsed()) { - cds::urcu::details::singleton::detach_thread( m_pSHTRCU ); - m_pSHTRCU = nullptr; - } -#endif - return true; - } - return false; - } + CDS_EXPORT_API void init(); + CDS_EXPORT_API bool fini(); size_t fake_current_processor() { @@ -280,6 +194,6 @@ namespace cds { //@endcond } // namespace threading -} // namespace cds::threading +} // namespace cds #endif // #ifndef CDSLIB_THREADING__COMMON_H diff --git a/cds/threading/details/cxx11_manager.h b/cds/threading/details/cxx11_manager.h index 84960a58..353b18fc 100644 --- a/cds/threading/details/cxx11_manager.h +++ b/cds/threading/details/cxx11_manager.h @@ -123,30 +123,6 @@ namespace cds { namespace threading { return p; } - /// Get gc::HP thread GC implementation for current thread - /** - The object returned may be uninitialized if you did not call attachThread in the beginning of thread execution - or if you did not use gc::HP. - To initialize gc::HP GC you must constuct cds::gc::HP object in the beginning of your application - */ - static gc::HP::thread_gc_impl& getHZPGC() - { - assert( _threadData()->m_hpManager != nullptr ); - return *(_threadData()->m_hpManager); - } - - /// Get gc::DHP thread GC implementation for current thread - /** - The object returned may be uninitialized if you did not call attachThread in the beginning of thread execution - or if you did not use gc::DHP. - To initialize gc::DHP GC you must constuct cds::gc::DHP object in the beginning of your application - */ - static gc::DHP::thread_gc_impl& getDHPGC() - { - assert( _threadData()->m_dhpManager != nullptr ); - return *(_threadData()->m_dhpManager); - } - //@cond static size_t fake_current_processor() { diff --git a/cds/threading/details/gcc_manager.h b/cds/threading/details/gcc_manager.h index 41657eec..98d6d9aa 100644 --- a/cds/threading/details/gcc_manager.h +++ b/cds/threading/details/gcc_manager.h @@ -123,30 +123,6 @@ namespace cds { namespace threading { return p; } - /// Get gc::HP thread GC implementation for current thread - /** - The object returned may be uninitialized if you did not call attachThread in the beginning of thread execution - or if you did not use gc::HP. - To initialize gc::HP GC you must constuct cds::gc::HP object in the beginning of your application - */ - static gc::HP::thread_gc_impl& getHZPGC() - { - assert( _threadData()->m_hpManager ); - return *(_threadData()->m_hpManager); - } - - /// Get gc::DHP thread GC implementation for current thread - /** - The object returned may be uninitialized if you did not call attachThread in the beginning of thread execution - or if you did not use gc::DHP. - To initialize gc::DHP GC you must constuct cds::gc::DHP object in the beginning of your application - */ - static gc::DHP::thread_gc_impl& getDHPGC() - { - assert( _threadData()->m_dhpManager ); - return *(_threadData()->m_dhpManager); - } - //@cond static size_t fake_current_processor() { diff --git a/cds/threading/details/msvc_manager.h b/cds/threading/details/msvc_manager.h index 03f0684f..2aaffd0e 100644 --- a/cds/threading/details/msvc_manager.h +++ b/cds/threading/details/msvc_manager.h @@ -123,30 +123,6 @@ namespace cds { namespace threading { return p; } - /// Get gc::HP thread GC implementation for current thread - /** - The object returned may be uninitialized if you did not call attachThread in the beginning of thread execution - or if you did not use gc::HP. - To initialize gc::HP GC you must constuct cds::gc::HP object in the beginning of your application - */ - static gc::HP::thread_gc_impl& getHZPGC() - { - assert( _threadData()->m_hpManager ); - return *(_threadData()->m_hpManager); - } - - /// Get gc::DHP thread GC implementation for current thread - /** - The object returned may be uninitialized if you did not call attachThread in the beginning of thread execution - or if you did not use gc::DHP. - To initialize gc::DHP GC you must constuct cds::gc::DHP object in the beginning of your application - */ - static gc::DHP::thread_gc_impl& getDHPGC() - { - assert( _threadData()->m_dhpManager ); - return *(_threadData()->m_dhpManager); - } - //@cond static size_t fake_current_processor() { diff --git a/cds/threading/details/pthread_manager.h b/cds/threading/details/pthread_manager.h index f91c5930..60b18988 100644 --- a/cds/threading/details/pthread_manager.h +++ b/cds/threading/details/pthread_manager.h @@ -217,28 +217,6 @@ namespace cds { namespace threading { return _threadData( do_getData ); } - /// Get gc::HP thread GC implementation for current thread - /** - The object returned may be uninitialized if you did not call attachThread in the beginning of thread execution - or if you did not use gc::HP. - To initialize gc::HP GC you must constuct cds::gc::HP object in the beginning of your application - */ - static gc::HP::thread_gc_impl& getHZPGC() - { - return *(_threadData( do_getData )->m_hpManager); - } - - /// Get gc::DHP thread GC implementation for current thread - /** - The object returned may be uninitialized if you did not call attachThread in the beginning of thread execution - or if you did not use gc::DHP. - To initialize gc::DHP GC you must constuct cds::gc::DHP object in the beginning of your application - */ - static gc::DHP::thread_gc_impl& getDHPGC() - { - return *(_threadData( do_getData )->m_dhpManager); - } - //@cond static size_t fake_current_processor() { diff --git a/cds/threading/details/wintls_manager.h b/cds/threading/details/wintls_manager.h index 28af704c..ca24c273 100644 --- a/cds/threading/details/wintls_manager.h +++ b/cds/threading/details/wintls_manager.h @@ -183,9 +183,8 @@ namespace cds { namespace threading { ThreadData * pData = _threadData( do_attachThread ); assert( pData ); - if ( pData ) { + if ( pData ) pData->init(); - } else throw api_exception( api_error_code(-1), "cds::threading::wintls::Manager::attachThread" ); } @@ -216,28 +215,6 @@ namespace cds { namespace threading { return _threadData( do_getData ); } - /// Get gc::HP thread GC implementation for current thread - /** - The object returned may be uninitialized if you did not call attachThread in the beginning of thread execution - or if you did not use gc::HP. - To initialize gc::HP GC you must constuct cds::gc::HP object in the beginning of your application - */ - static gc::HP::thread_gc_impl& getHZPGC() - { - return *(_threadData( do_getData )->m_hpManager); - } - - /// Get gc::DHP thread GC implementation for current thread - /** - The object returned may be uninitialized if you did not call attachThread in the beginning of thread execution - or if you did not use gc::DHP. - To initialize gc::DHP GC you must constuct cds::gc::DHP object in the beginning of your application - */ - static gc::DHP::thread_gc_impl& getDHPGC() - { - return *(_threadData( do_getData )->m_dhpManager); - } - //@cond static size_t fake_current_processor() { diff --git a/cds/threading/model.h b/cds/threading/model.h index 01eea051..8182865f 100644 --- a/cds/threading/model.h +++ b/cds/threading/model.h @@ -46,32 +46,6 @@ namespace cds { namespace threading { */ template cds::urcu::details::thread_data * getRCU(); - /// Get cds::gc::HP thread GC implementation for current thread - /** - The object returned may be uninitialized if you did not call attachThread in the beginning of thread execution - or if you did not use cds::gc::HP. - To initialize cds::gc::HP GC you must constuct cds::gc::HP object in the beginning of your application, - see \ref cds_how_to_use "How to use libcds" - */ - template <> - inline cds::gc::HP::thread_gc_impl& getGC() - { - return Manager::getHZPGC(); - } - - /// Get cds::gc::DHP thread GC implementation for current thread - /** - The object returned may be uninitialized if you did not call attachThread in the beginning of thread execution - or if you did not use cds::gc::DHP. - To initialize cds::gc::DHP GC you must constuct cds::gc::DHP object in the beginning of your application, - see \ref cds_how_to_use "How to use libcds" - */ - template <> - inline cds::gc::DHP::thread_gc_impl& getGC() - { - return Manager::getDHPGC(); - } - //@cond template<> inline cds::urcu::details::thread_data * getRCU() diff --git a/change.log b/change.log index e1226fdc..2968e951 100644 --- a/change.log +++ b/change.log @@ -1,3 +1,19 @@ +2.3.0 + General release + - Changed: cds::gc::HP is totally refactored: + - simplified internal structures; + - added ability to specify an external allocator for internal data; + - external API for gc::HP is slightly changed: now scan type + cannot be changed on the fly; it can be specified only in + construction time. + - Changed: cds::gc::DHP is totally refactored to overcome some internal + limitations. Now gc::DHP is fully adaptive variant of Hazard Pointer + SMR, any dependencies on thread count is removed, count of retired + data and hazard pointers per thread are increased automaticaly by perforce. + External API of gc::DHP class is changed: now only initial count + of hazard pointers can be specified in the constructor. Like new gc::HP, + the new gc::DHP supports an external allocator for internal data. + 2.2.0 04.01.2017 General release - Changed: CMake is used for build libcds. Ancient build.sh has been removed diff --git a/doxygen/cds.doxy b/doxygen/cds.doxy index 81cfc8e9..6bdae828 100644 --- a/doxygen/cds.doxy +++ b/doxygen/cds.doxy @@ -1399,7 +1399,8 @@ PREDEFINED = CDS_BUILD_BITS=64 \ CDS_CXX11_INLINE_NAMESPACE=inline \ CDS_NOEXCEPT=noexcept() \ CDS_CONSTEXPR=constexpr \ - CDS_CXX11_INHERITING_CTOR + CDS_CXX11_INHERITING_CTOR \ + CDS_EXCEPTION_ENABLED # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/projects/Win/vc14/cds.vcxproj b/projects/Win/vc14/cds.vcxproj index 662a0523..436d1240 100644 --- a/projects/Win/vc14/cds.vcxproj +++ b/projects/Win/vc14/cds.vcxproj @@ -151,7 +151,7 @@ /wd4512 /wd4127 /Zc:inline %(AdditionalOptions) Disabled $(SolutionDir)..\..\..\;$(BOOST_PATH);%(AdditionalIncludeDirectories) - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;CDS_BUILD_LIB;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;CDS_BUILD_LIB;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -182,7 +182,7 @@ /wd4512 /wd4127 /Zc:inline %(AdditionalOptions) Disabled $(SolutionDir)..\..\..\;$(BOOST_PATH);%(AdditionalIncludeDirectories) - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;CDS_BUILD_LIB;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;CDS_BUILD_LIB;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -219,7 +219,7 @@ true false $(SolutionDir)..\..\..\;$(BOOST_PATH);%(AdditionalIncludeDirectories) - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0500;CDS_BUILD_LIB;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0500;CDS_BUILD_LIB;%(PreprocessorDefinitions) true MultiThreadedDLL StreamingSIMDExtensions2 @@ -270,7 +270,7 @@ false false $(SolutionDir)..\..\..\;$(BOOST_PATH);%(AdditionalIncludeDirectories) - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;CDS_BUILD_LIB;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;CDS_BUILD_LIB;%(PreprocessorDefinitions) MultiThreadedDLL NotUsing Level3 @@ -312,7 +312,7 @@ /wd4512 /wd4127 /Zc:inline %(AdditionalOptions) Disabled $(SolutionDir)..\..\..\;$(BOOST_PATH);%(AdditionalIncludeDirectories) - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_USE_VLD;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;CDS_BUILD_LIB;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;CDS_USE_VLD;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;CDS_BUILD_LIB;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -343,7 +343,7 @@ /wd4512 /wd4127 /Zc:inline %(AdditionalOptions) Disabled $(SolutionDir)..\..\..\;$(BOOST_PATH);%(AdditionalIncludeDirectories) - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_USE_VLD;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;CDS_BUILD_LIB;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;CDS_USE_VLD;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;CDS_BUILD_LIB;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -367,10 +367,11 @@ - + - + + @@ -507,15 +508,11 @@ - - - - + + - - - - + + diff --git a/projects/Win/vc14/cds.vcxproj.filters b/projects/Win/vc14/cds.vcxproj.filters index 31fbdb50..21487873 100644 --- a/projects/Win/vc14/cds.vcxproj.filters +++ b/projects/Win/vc14/cds.vcxproj.filters @@ -126,9 +126,6 @@ {00a14aa8-3035-4b56-bc86-442ca9bf8f44} - - {3195cce2-1710-4b79-a1cf-6c7cea085fa3} - {03d212fb-73f8-4f0e-9aff-f22b0783fee8} @@ -173,10 +170,13 @@ Source Files - + + Source Files + + Source Files - + Source Files @@ -1090,30 +1090,6 @@ Source Files - - Header Files\cds\gc\details - - - Header Files\cds\gc\details - - - Header Files\cds\gc\details - - - Header Files\cds\gc\details - - - Header Files\cds\gc\impl - - - Header Files\cds\gc\impl - - - Header Files\cds\gc\impl - - - Header Files\cds\gc\impl - Header Files\cds\algo @@ -1267,5 +1243,17 @@ Header Files\cds\container\details + + Header Files\cds\gc + + + Header Files\cds\gc + + + Header Files\cds\gc\details + + + Header Files\cds\details + \ No newline at end of file diff --git a/projects/Win/vc14/gtest-deque.vcxproj b/projects/Win/vc14/gtest-deque.vcxproj index 9ef36575..fb609851 100644 --- a/projects/Win/vc14/gtest-deque.vcxproj +++ b/projects/Win/vc14/gtest-deque.vcxproj @@ -138,7 +138,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -153,7 +153,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -168,7 +168,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -183,7 +183,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -200,7 +200,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -219,7 +219,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) diff --git a/projects/Win/vc14/gtest-ilist-iterable.vcxproj b/projects/Win/vc14/gtest-ilist-iterable.vcxproj index 7f344608..7ecf8fde 100644 --- a/projects/Win/vc14/gtest-ilist-iterable.vcxproj +++ b/projects/Win/vc14/gtest-ilist-iterable.vcxproj @@ -146,7 +146,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 @@ -162,7 +162,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 @@ -178,7 +178,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 @@ -194,7 +194,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 @@ -212,7 +212,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 @@ -232,7 +232,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 diff --git a/projects/Win/vc14/gtest-ilist-lazy.vcxproj b/projects/Win/vc14/gtest-ilist-lazy.vcxproj index 4874330c..8f37014b 100644 --- a/projects/Win/vc14/gtest-ilist-lazy.vcxproj +++ b/projects/Win/vc14/gtest-ilist-lazy.vcxproj @@ -152,7 +152,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 @@ -168,7 +168,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 @@ -184,7 +184,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 @@ -200,7 +200,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 @@ -218,7 +218,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 @@ -238,7 +238,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 diff --git a/projects/Win/vc14/gtest-ilist-michael.vcxproj b/projects/Win/vc14/gtest-ilist-michael.vcxproj index ff58ce2d..4ec4a1c2 100644 --- a/projects/Win/vc14/gtest-ilist-michael.vcxproj +++ b/projects/Win/vc14/gtest-ilist-michael.vcxproj @@ -152,7 +152,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 @@ -168,7 +168,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 @@ -184,7 +184,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 @@ -200,7 +200,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 @@ -218,7 +218,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 @@ -238,7 +238,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) 4503 diff --git a/projects/Win/vc14/gtest-iset-feldman.vcxproj b/projects/Win/vc14/gtest-iset-feldman.vcxproj index cd6c78a0..7ab3712b 100644 --- a/projects/Win/vc14/gtest-iset-feldman.vcxproj +++ b/projects/Win/vc14/gtest-iset-feldman.vcxproj @@ -156,7 +156,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -173,7 +173,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -190,7 +190,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -207,7 +207,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -226,7 +226,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -247,7 +247,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-iset-michael-iterable.vcxproj b/projects/Win/vc14/gtest-iset-michael-iterable.vcxproj index d44176bf..bc42ee96 100644 --- a/projects/Win/vc14/gtest-iset-michael-iterable.vcxproj +++ b/projects/Win/vc14/gtest-iset-michael-iterable.vcxproj @@ -147,7 +147,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -164,7 +164,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -181,7 +181,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -198,7 +198,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -217,7 +217,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -238,7 +238,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-iset-michael-lazy.vcxproj b/projects/Win/vc14/gtest-iset-michael-lazy.vcxproj index 6e487b0b..74e43ff6 100644 --- a/projects/Win/vc14/gtest-iset-michael-lazy.vcxproj +++ b/projects/Win/vc14/gtest-iset-michael-lazy.vcxproj @@ -166,7 +166,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -183,7 +183,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -200,7 +200,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -217,7 +217,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -236,7 +236,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -257,7 +257,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-iset-michael.vcxproj b/projects/Win/vc14/gtest-iset-michael.vcxproj index 27886b01..223c0b18 100644 --- a/projects/Win/vc14/gtest-iset-michael.vcxproj +++ b/projects/Win/vc14/gtest-iset-michael.vcxproj @@ -166,7 +166,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -183,7 +183,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -200,7 +200,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -217,7 +217,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -236,7 +236,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -257,7 +257,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-iset-skip.vcxproj b/projects/Win/vc14/gtest-iset-skip.vcxproj index 0adc2dfc..351b622b 100644 --- a/projects/Win/vc14/gtest-iset-skip.vcxproj +++ b/projects/Win/vc14/gtest-iset-skip.vcxproj @@ -159,7 +159,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -176,7 +176,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -193,7 +193,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -210,7 +210,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -229,7 +229,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -250,7 +250,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-iset-split-iterable.vcxproj b/projects/Win/vc14/gtest-iset-split-iterable.vcxproj index 05d91b40..58e16c0a 100644 --- a/projects/Win/vc14/gtest-iset-split-iterable.vcxproj +++ b/projects/Win/vc14/gtest-iset-split-iterable.vcxproj @@ -147,7 +147,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -164,7 +164,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -181,7 +181,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -198,7 +198,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -217,7 +217,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -238,7 +238,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-iset-split-lazy.vcxproj b/projects/Win/vc14/gtest-iset-split-lazy.vcxproj index e0f2e785..5b7fc968 100644 --- a/projects/Win/vc14/gtest-iset-split-lazy.vcxproj +++ b/projects/Win/vc14/gtest-iset-split-lazy.vcxproj @@ -194,7 +194,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -211,7 +211,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -228,7 +228,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -245,7 +245,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -264,7 +264,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -285,7 +285,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-iset-split-michael.vcxproj b/projects/Win/vc14/gtest-iset-split-michael.vcxproj index 16e8d396..9a1aa69d 100644 --- a/projects/Win/vc14/gtest-iset-split-michael.vcxproj +++ b/projects/Win/vc14/gtest-iset-split-michael.vcxproj @@ -194,7 +194,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -211,7 +211,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -228,7 +228,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -245,7 +245,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -264,7 +264,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -285,7 +285,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-list-iterable.vcxproj b/projects/Win/vc14/gtest-list-iterable.vcxproj index 6e81e2d4..52bcc53f 100644 --- a/projects/Win/vc14/gtest-list-iterable.vcxproj +++ b/projects/Win/vc14/gtest-list-iterable.vcxproj @@ -153,7 +153,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -168,7 +168,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -183,7 +183,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -198,7 +198,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -215,7 +215,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -234,7 +234,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) diff --git a/projects/Win/vc14/gtest-list-lazy.vcxproj b/projects/Win/vc14/gtest-list-lazy.vcxproj index bd763d6a..7e28cf31 100644 --- a/projects/Win/vc14/gtest-list-lazy.vcxproj +++ b/projects/Win/vc14/gtest-list-lazy.vcxproj @@ -179,7 +179,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -194,7 +194,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -209,7 +209,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -224,7 +224,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -241,7 +241,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -260,7 +260,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) diff --git a/projects/Win/vc14/gtest-list-michael.vcxproj b/projects/Win/vc14/gtest-list-michael.vcxproj index fe272d5f..a5f29927 100644 --- a/projects/Win/vc14/gtest-list-michael.vcxproj +++ b/projects/Win/vc14/gtest-list-michael.vcxproj @@ -193,7 +193,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -208,7 +208,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -223,7 +223,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -238,7 +238,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -255,7 +255,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -274,7 +274,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) diff --git a/projects/Win/vc14/gtest-map-feldman.vcxproj b/projects/Win/vc14/gtest-map-feldman.vcxproj index 8ef7686c..1670d530 100644 --- a/projects/Win/vc14/gtest-map-feldman.vcxproj +++ b/projects/Win/vc14/gtest-map-feldman.vcxproj @@ -153,7 +153,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -170,7 +170,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -187,7 +187,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -204,7 +204,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -223,7 +223,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -244,7 +244,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-map-michael-iterable.vcxproj b/projects/Win/vc14/gtest-map-michael-iterable.vcxproj index 13c1ea5a..7a044cc6 100644 --- a/projects/Win/vc14/gtest-map-michael-iterable.vcxproj +++ b/projects/Win/vc14/gtest-map-michael-iterable.vcxproj @@ -148,7 +148,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -165,7 +165,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -182,7 +182,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -199,7 +199,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -218,7 +218,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -239,7 +239,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-map-michael-lazy.vcxproj b/projects/Win/vc14/gtest-map-michael-lazy.vcxproj index bc6f8604..6c4de62e 100644 --- a/projects/Win/vc14/gtest-map-michael-lazy.vcxproj +++ b/projects/Win/vc14/gtest-map-michael-lazy.vcxproj @@ -160,7 +160,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -177,7 +177,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -194,7 +194,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -211,7 +211,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -230,7 +230,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -251,7 +251,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-map-michael.vcxproj b/projects/Win/vc14/gtest-map-michael.vcxproj index 60d4d543..c13442be 100644 --- a/projects/Win/vc14/gtest-map-michael.vcxproj +++ b/projects/Win/vc14/gtest-map-michael.vcxproj @@ -166,7 +166,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -183,7 +183,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -200,7 +200,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -217,7 +217,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -236,7 +236,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -257,7 +257,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-map-skip.vcxproj b/projects/Win/vc14/gtest-map-skip.vcxproj index 482286ef..7a7779cf 100644 --- a/projects/Win/vc14/gtest-map-skip.vcxproj +++ b/projects/Win/vc14/gtest-map-skip.vcxproj @@ -169,7 +169,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -186,7 +186,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -203,7 +203,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -220,7 +220,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -239,7 +239,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -260,7 +260,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-map-split-iterable.vcxproj b/projects/Win/vc14/gtest-map-split-iterable.vcxproj index c06e636c..7760500f 100644 --- a/projects/Win/vc14/gtest-map-split-iterable.vcxproj +++ b/projects/Win/vc14/gtest-map-split-iterable.vcxproj @@ -146,7 +146,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -163,7 +163,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -180,7 +180,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -197,7 +197,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -216,7 +216,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -237,7 +237,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-map-split-lazy.vcxproj b/projects/Win/vc14/gtest-map-split-lazy.vcxproj index 57314049..5e1f8a0d 100644 --- a/projects/Win/vc14/gtest-map-split-lazy.vcxproj +++ b/projects/Win/vc14/gtest-map-split-lazy.vcxproj @@ -195,7 +195,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -212,7 +212,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -229,7 +229,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -246,7 +246,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -265,7 +265,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -286,7 +286,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-map-split-michael.vcxproj b/projects/Win/vc14/gtest-map-split-michael.vcxproj index e39603bd..051152eb 100644 --- a/projects/Win/vc14/gtest-map-split-michael.vcxproj +++ b/projects/Win/vc14/gtest-map-split-michael.vcxproj @@ -195,7 +195,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -212,7 +212,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -229,7 +229,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -246,7 +246,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -265,7 +265,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -286,7 +286,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-misc.vcxproj b/projects/Win/vc14/gtest-misc.vcxproj index bd9cf5d5..f381e59a 100644 --- a/projects/Win/vc14/gtest-misc.vcxproj +++ b/projects/Win/vc14/gtest-misc.vcxproj @@ -147,7 +147,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -162,7 +162,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -177,7 +177,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -192,7 +192,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -209,7 +209,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -228,7 +228,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) diff --git a/projects/Win/vc14/gtest-pqueue.vcxproj b/projects/Win/vc14/gtest-pqueue.vcxproj index 5e7e2808..b70d3ae6 100644 --- a/projects/Win/vc14/gtest-pqueue.vcxproj +++ b/projects/Win/vc14/gtest-pqueue.vcxproj @@ -146,7 +146,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -161,7 +161,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -176,7 +176,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -191,7 +191,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -208,7 +208,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -227,7 +227,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) diff --git a/projects/Win/vc14/gtest-queue.vcxproj b/projects/Win/vc14/gtest-queue.vcxproj index b6f03324..28f044fb 100644 --- a/projects/Win/vc14/gtest-queue.vcxproj +++ b/projects/Win/vc14/gtest-queue.vcxproj @@ -172,7 +172,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -187,7 +187,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -202,7 +202,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -217,7 +217,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -234,7 +234,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -253,7 +253,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) diff --git a/projects/Win/vc14/gtest-set-feldman.vcxproj b/projects/Win/vc14/gtest-set-feldman.vcxproj index 9311deb0..db736d9c 100644 --- a/projects/Win/vc14/gtest-set-feldman.vcxproj +++ b/projects/Win/vc14/gtest-set-feldman.vcxproj @@ -155,7 +155,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -172,7 +172,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -189,7 +189,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -206,7 +206,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -225,7 +225,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -246,7 +246,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-set-michael-iterable.vcxproj b/projects/Win/vc14/gtest-set-michael-iterable.vcxproj index effd95a0..401d3997 100644 --- a/projects/Win/vc14/gtest-set-michael-iterable.vcxproj +++ b/projects/Win/vc14/gtest-set-michael-iterable.vcxproj @@ -149,7 +149,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -166,7 +166,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -183,7 +183,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -200,7 +200,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -219,7 +219,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -240,7 +240,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-set-michael-lazy.vcxproj b/projects/Win/vc14/gtest-set-michael-lazy.vcxproj index f2128bc6..5212bf08 100644 --- a/projects/Win/vc14/gtest-set-michael-lazy.vcxproj +++ b/projects/Win/vc14/gtest-set-michael-lazy.vcxproj @@ -168,7 +168,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -185,7 +185,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -202,7 +202,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -219,7 +219,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -238,7 +238,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -259,7 +259,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-set-michael.vcxproj b/projects/Win/vc14/gtest-set-michael.vcxproj index 498db415..c307f181 100644 --- a/projects/Win/vc14/gtest-set-michael.vcxproj +++ b/projects/Win/vc14/gtest-set-michael.vcxproj @@ -168,7 +168,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -185,7 +185,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -202,7 +202,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -219,7 +219,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -238,7 +238,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -259,7 +259,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-set-skip.vcxproj b/projects/Win/vc14/gtest-set-skip.vcxproj index 7df889c6..27a974dc 100644 --- a/projects/Win/vc14/gtest-set-skip.vcxproj +++ b/projects/Win/vc14/gtest-set-skip.vcxproj @@ -168,7 +168,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -185,7 +185,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -202,7 +202,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -219,7 +219,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -238,7 +238,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -259,7 +259,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-set-split-iterable.vcxproj b/projects/Win/vc14/gtest-set-split-iterable.vcxproj index 526c3054..01b0f9a1 100644 --- a/projects/Win/vc14/gtest-set-split-iterable.vcxproj +++ b/projects/Win/vc14/gtest-set-split-iterable.vcxproj @@ -149,7 +149,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -166,7 +166,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -183,7 +183,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -200,7 +200,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -219,7 +219,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -240,7 +240,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-set-split-lazy.vcxproj b/projects/Win/vc14/gtest-set-split-lazy.vcxproj index 1f881f54..4e92cee3 100644 --- a/projects/Win/vc14/gtest-set-split-lazy.vcxproj +++ b/projects/Win/vc14/gtest-set-split-lazy.vcxproj @@ -196,7 +196,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -213,7 +213,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -230,7 +230,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -247,7 +247,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -266,7 +266,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -287,7 +287,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-set-split-michael.vcxproj b/projects/Win/vc14/gtest-set-split-michael.vcxproj index e4ce8efd..1654bd48 100644 --- a/projects/Win/vc14/gtest-set-split-michael.vcxproj +++ b/projects/Win/vc14/gtest-set-split-michael.vcxproj @@ -196,7 +196,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -213,7 +213,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -230,7 +230,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -247,7 +247,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -266,7 +266,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 @@ -287,7 +287,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) 4503 diff --git a/projects/Win/vc14/gtest-stack.vcxproj b/projects/Win/vc14/gtest-stack.vcxproj index 6dfc3752..599cd878 100644 --- a/projects/Win/vc14/gtest-stack.vcxproj +++ b/projects/Win/vc14/gtest-stack.vcxproj @@ -147,7 +147,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -162,7 +162,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -177,7 +177,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -192,7 +192,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -209,7 +209,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -228,7 +228,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) diff --git a/projects/Win/vc14/gtest-tree-bronson.vcxproj b/projects/Win/vc14/gtest-tree-bronson.vcxproj index e84f0e3d..b2575a6f 100644 --- a/projects/Win/vc14/gtest-tree-bronson.vcxproj +++ b/projects/Win/vc14/gtest-tree-bronson.vcxproj @@ -157,7 +157,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj /Bv %(AdditionalOptions) @@ -173,7 +173,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj /Bv %(AdditionalOptions) @@ -189,7 +189,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj /Bv %(AdditionalOptions) @@ -205,7 +205,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj /Bv %(AdditionalOptions) @@ -223,7 +223,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj /Bv %(AdditionalOptions) @@ -243,7 +243,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj /Bv %(AdditionalOptions) diff --git a/projects/Win/vc14/gtest-tree-ellen.vcxproj b/projects/Win/vc14/gtest-tree-ellen.vcxproj index 536a4620..ad700723 100644 --- a/projects/Win/vc14/gtest-tree-ellen.vcxproj +++ b/projects/Win/vc14/gtest-tree-ellen.vcxproj @@ -241,7 +241,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj /Bv %(AdditionalOptions) @@ -257,7 +257,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj /Bv %(AdditionalOptions) @@ -273,7 +273,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj /Bv %(AdditionalOptions) @@ -289,7 +289,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj /Bv %(AdditionalOptions) @@ -307,7 +307,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj /Bv %(AdditionalOptions) @@ -327,7 +327,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj /Bv %(AdditionalOptions) diff --git a/projects/Win/vc14/stress-framework.vcxproj b/projects/Win/vc14/stress-framework.vcxproj index 1359fe48..fa2f3962 100644 --- a/projects/Win/vc14/stress-framework.vcxproj +++ b/projects/Win/vc14/stress-framework.vcxproj @@ -188,7 +188,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -203,7 +203,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -218,7 +218,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -233,7 +233,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -250,7 +250,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -269,7 +269,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) diff --git a/projects/Win/vc14/stress-freelist.vcxproj b/projects/Win/vc14/stress-freelist.vcxproj index 2edee2cd..fff1140b 100644 --- a/projects/Win/vc14/stress-freelist.vcxproj +++ b/projects/Win/vc14/stress-freelist.vcxproj @@ -140,7 +140,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -155,7 +155,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -170,7 +170,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -185,7 +185,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -202,7 +202,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -221,7 +221,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) diff --git a/projects/Win/vc14/stress-map-delodd.vcxproj b/projects/Win/vc14/stress-map-delodd.vcxproj index ff391596..ffaf262e 100644 --- a/projects/Win/vc14/stress-map-delodd.vcxproj +++ b/projects/Win/vc14/stress-map-delodd.vcxproj @@ -166,7 +166,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -182,7 +182,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -198,7 +198,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -214,7 +214,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -232,7 +232,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -252,7 +252,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) diff --git a/projects/Win/vc14/stress-map-find_int.vcxproj b/projects/Win/vc14/stress-map-find_int.vcxproj index 82b1004a..8f08222c 100644 --- a/projects/Win/vc14/stress-map-find_int.vcxproj +++ b/projects/Win/vc14/stress-map-find_int.vcxproj @@ -168,7 +168,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -184,7 +184,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -200,7 +200,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -216,7 +216,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -234,7 +234,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -254,7 +254,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) diff --git a/projects/Win/vc14/stress-map-find_string.vcxproj b/projects/Win/vc14/stress-map-find_string.vcxproj index 16c36646..a8933c8f 100644 --- a/projects/Win/vc14/stress-map-find_string.vcxproj +++ b/projects/Win/vc14/stress-map-find_string.vcxproj @@ -182,7 +182,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -198,7 +198,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -214,7 +214,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -230,7 +230,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -248,7 +248,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -268,7 +268,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) diff --git a/projects/Win/vc14/stress-map-insdel-func.vcxproj b/projects/Win/vc14/stress-map-insdel-func.vcxproj index 03c4723f..b78ace4b 100644 --- a/projects/Win/vc14/stress-map-insdel-func.vcxproj +++ b/projects/Win/vc14/stress-map-insdel-func.vcxproj @@ -167,7 +167,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -183,7 +183,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -199,7 +199,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -215,7 +215,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -233,7 +233,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -253,7 +253,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) diff --git a/projects/Win/vc14/stress-map-insdel-int.vcxproj b/projects/Win/vc14/stress-map-insdel-int.vcxproj index a7af9239..8f0b642a 100644 --- a/projects/Win/vc14/stress-map-insdel-int.vcxproj +++ b/projects/Win/vc14/stress-map-insdel-int.vcxproj @@ -168,7 +168,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -184,7 +184,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -200,7 +200,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -216,7 +216,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -234,7 +234,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -254,7 +254,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) diff --git a/projects/Win/vc14/stress-map-insdel-item-int.vcxproj b/projects/Win/vc14/stress-map-insdel-item-int.vcxproj index e09d7750..4e94427d 100644 --- a/projects/Win/vc14/stress-map-insdel-item-int.vcxproj +++ b/projects/Win/vc14/stress-map-insdel-item-int.vcxproj @@ -167,7 +167,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -183,7 +183,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -199,7 +199,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -215,7 +215,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -233,7 +233,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -253,7 +253,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) diff --git a/projects/Win/vc14/stress-map-insdel-string.vcxproj b/projects/Win/vc14/stress-map-insdel-string.vcxproj index b5b77175..04a7a601 100644 --- a/projects/Win/vc14/stress-map-insdel-string.vcxproj +++ b/projects/Win/vc14/stress-map-insdel-string.vcxproj @@ -175,7 +175,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -191,7 +191,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -207,7 +207,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -223,7 +223,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -241,7 +241,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -261,7 +261,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) diff --git a/projects/Win/vc14/stress-map-insdelfind.vcxproj b/projects/Win/vc14/stress-map-insdelfind.vcxproj index 3cd3e6a5..16bbd6ef 100644 --- a/projects/Win/vc14/stress-map-insdelfind.vcxproj +++ b/projects/Win/vc14/stress-map-insdelfind.vcxproj @@ -168,7 +168,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -184,7 +184,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -200,7 +200,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -216,7 +216,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -234,7 +234,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -254,7 +254,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) diff --git a/projects/Win/vc14/stress-map-insfind-int.vcxproj b/projects/Win/vc14/stress-map-insfind-int.vcxproj index e054e6af..42f2973a 100644 --- a/projects/Win/vc14/stress-map-insfind-int.vcxproj +++ b/projects/Win/vc14/stress-map-insfind-int.vcxproj @@ -168,7 +168,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -184,7 +184,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -200,7 +200,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -216,7 +216,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -234,7 +234,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -254,7 +254,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\map;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) diff --git a/projects/Win/vc14/stress-pqueue.vcxproj b/projects/Win/vc14/stress-pqueue.vcxproj index 20e765a2..e3be51b0 100644 --- a/projects/Win/vc14/stress-pqueue.vcxproj +++ b/projects/Win/vc14/stress-pqueue.vcxproj @@ -152,7 +152,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -167,7 +167,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -182,7 +182,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -197,7 +197,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -214,7 +214,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -233,7 +233,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) diff --git a/projects/Win/vc14/stress-queue.vcxproj b/projects/Win/vc14/stress-queue.vcxproj index 000aceca..f203b17c 100644 --- a/projects/Win/vc14/stress-queue.vcxproj +++ b/projects/Win/vc14/stress-queue.vcxproj @@ -178,7 +178,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -193,7 +193,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -208,7 +208,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -223,7 +223,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -240,7 +240,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -259,7 +259,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress;$(BOOST_PATH);%(AdditionalIncludeDirectories) diff --git a/projects/Win/vc14/stress-set-delodd.vcxproj b/projects/Win/vc14/stress-set-delodd.vcxproj index 504174a9..c48eb87b 100644 --- a/projects/Win/vc14/stress-set-delodd.vcxproj +++ b/projects/Win/vc14/stress-set-delodd.vcxproj @@ -168,7 +168,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -184,7 +184,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -200,7 +200,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -216,7 +216,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -234,7 +234,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -254,7 +254,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) diff --git a/projects/Win/vc14/stress-set-insdel_func.vcxproj b/projects/Win/vc14/stress-set-insdel_func.vcxproj index ad8d90fe..ec77df3c 100644 --- a/projects/Win/vc14/stress-set-insdel_func.vcxproj +++ b/projects/Win/vc14/stress-set-insdel_func.vcxproj @@ -166,7 +166,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -182,7 +182,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -198,7 +198,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -214,7 +214,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -232,7 +232,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -252,7 +252,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) diff --git a/projects/Win/vc14/stress-set-insdel_string.vcxproj b/projects/Win/vc14/stress-set-insdel_string.vcxproj index c25bd838..7ebc517a 100644 --- a/projects/Win/vc14/stress-set-insdel_string.vcxproj +++ b/projects/Win/vc14/stress-set-insdel_string.vcxproj @@ -174,7 +174,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -190,7 +190,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -206,7 +206,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -222,7 +222,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -240,7 +240,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -260,7 +260,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) diff --git a/projects/Win/vc14/stress-set-insdelfind.vcxproj b/projects/Win/vc14/stress-set-insdelfind.vcxproj index a3ab653b..8a861438 100644 --- a/projects/Win/vc14/stress-set-insdelfind.vcxproj +++ b/projects/Win/vc14/stress-set-insdelfind.vcxproj @@ -163,7 +163,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -179,7 +179,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -195,7 +195,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -211,7 +211,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_SCL_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -229,7 +229,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -249,7 +249,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_SCL_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_SCL_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) diff --git a/projects/Win/vc14/stress-set-iteration.vcxproj b/projects/Win/vc14/stress-set-iteration.vcxproj index 62ccbbcb..0ac5ab71 100644 --- a/projects/Win/vc14/stress-set-iteration.vcxproj +++ b/projects/Win/vc14/stress-set-iteration.vcxproj @@ -148,7 +148,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -164,7 +164,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -180,7 +180,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -196,7 +196,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -214,7 +214,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) @@ -234,7 +234,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDSUNIT_USE_URCU;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress\set;$(SolutionDir)..\..\..\test\stress\;$(BOOST_PATH);%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) diff --git a/projects/Win/vc14/stress-stack.vcxproj b/projects/Win/vc14/stress-stack.vcxproj index f346dbec..cf0f3509 100644 --- a/projects/Win/vc14/stress-stack.vcxproj +++ b/projects/Win/vc14/stress-stack.vcxproj @@ -147,7 +147,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -162,7 +162,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -177,7 +177,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -192,7 +192,7 @@ NotUsing Level3 Disabled - _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -209,7 +209,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) @@ -228,7 +228,7 @@ MaxSpeed true true - _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _ENABLE_ATOMIC_ALIGNMENT_FIX;CDS_ENABLE_HPSTAT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) diff --git a/src/dhp.cpp b/src/dhp.cpp new file mode 100644 index 00000000..2e8ef2a1 --- /dev/null +++ b/src/dhp.cpp @@ -0,0 +1,488 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include + +#include +#include + +namespace cds { namespace gc { namespace dhp { + + namespace { + void * default_alloc_memory( size_t size ) + { + return new uintptr_t[( size + sizeof( uintptr_t ) - 1 ) / sizeof( uintptr_t )]; + } + + void default_free_memory( void* p ) + { + delete[] reinterpret_cast( p ); + } + + struct defaults { + static size_t const c_extended_guard_block_size = 16; + }; + + void* ( *s_alloc_memory )( size_t size ) = default_alloc_memory; + void( *s_free_memory )( void* p ) = default_free_memory; + + template + class allocator + { + public: + typedef T value_type; + + allocator() {} + allocator( allocator const& ) {} + template + allocator( allocator const& ) {} + + T* allocate( size_t nCount ) + { + return reinterpret_cast( s_alloc_memory( sizeof( value_type ) * nCount )); + } + + void deallocate( T* p, size_t /*nCount*/ ) + { + s_free_memory( reinterpret_cast( p )); + } + }; + + } // namespace + + /*static*/ CDS_EXPORT_API smr* smr::instance_ = nullptr; + thread_local thread_data* tls_ = nullptr; + + CDS_EXPORT_API hp_allocator::~hp_allocator() + { + while ( guard_block* gp = static_cast( free_list_.get())) { + gp->~guard_block(); + s_free_memory( gp ); + } + } + + CDS_EXPORT_API guard_block* hp_allocator::alloc() + { + guard_block* gb; + auto block = free_list_.get(); + if ( block ) + gb = static_cast< guard_block* >( block ); + else { + // allocate new block + gb = new( s_alloc_memory( sizeof( guard_block ) + sizeof( guard ) * defaults::c_extended_guard_block_size )) guard_block; + new ( gb->first() ) guard[defaults::c_extended_guard_block_size]; + } + + // links guards in the block + guard* p = gb->first(); + for ( guard* last = p + defaults::c_extended_guard_block_size - 1; p != last; ++p ) { + p->clear( atomics::memory_order_relaxed ); + p->next_ = p + 1; + } + p->next_ = nullptr; + p->clear(); + + return gb; + } + + CDS_EXPORT_API retired_allocator::~retired_allocator() + { + while ( retired_block* rb = static_cast( free_list_.get() ) ) { + rb->~retired_block(); + s_free_memory( rb ); + } + } + + CDS_EXPORT_API retired_block* retired_allocator::alloc() + { + retired_block* rb; + auto block = free_list_.get(); + if ( block ) + rb = static_cast< retired_block* >( block ); + else { + // allocate new block + rb = new( s_alloc_memory( sizeof( retired_block ) + sizeof( retired_ptr ) * retired_block::c_capacity )) retired_block; + new ( rb->first()) retired_ptr[retired_block::c_capacity]; + } + + rb->next_ = nullptr; + return rb; + } + + struct smr::thread_record: thread_data + { + atomics::atomic m_pNextNode; ///< next hazard ptr record in list + atomics::atomic m_idOwner; ///< Owner thread id; 0 - the record is free (not owned) + atomics::atomic m_bFree; ///< true if record is free (not owned) + + thread_record( guard* guards, size_t guard_count ) + : thread_data( guards, guard_count ) + , m_bFree( false ) + {} + }; + + /*static*/ CDS_EXPORT_API thread_data* smr::tls() + { + assert( tls_ != nullptr ); + return tls_; + } + + /*static*/ CDS_EXPORT_API void smr::set_memory_allocator( + void* ( *alloc_func )( size_t size ), + void( *free_func )( void * p ) + ) + { + // The memory allocation functions may be set BEFORE initializing DHP SMR!!! + assert( instance_ == nullptr ); + + s_alloc_memory = alloc_func; + s_free_memory = free_func; + } + + /*static*/ CDS_EXPORT_API void smr::construct( size_t nInitialHazardPtrCount ) + { + if ( !instance_ ) { + instance_ = new( s_alloc_memory( sizeof( smr ))) smr( nInitialHazardPtrCount ); + } + } + + /*static*/ CDS_EXPORT_API void smr::destruct( bool bDetachAll ) + { + if ( instance_ ) { + if ( bDetachAll ) + instance_->detach_all_thread(); + + instance_->~smr(); + s_free_memory( instance_ ); + instance_ = nullptr; + } + } + + CDS_EXPORT_API smr::smr( size_t nInitialHazardPtrCount ) + : thread_list_( nullptr ) + , initial_hazard_count_( nInitialHazardPtrCount < 4 ? 16 : nInitialHazardPtrCount ) + , last_plist_size_( initial_hazard_count_ * 64 ) + {} + + CDS_EXPORT_API smr::~smr() + { + CDS_DEBUG_ONLY( const cds::OS::ThreadId nullThreadId = cds::OS::c_NullThreadId; ) + CDS_DEBUG_ONLY( const cds::OS::ThreadId mainThreadId = cds::OS::get_current_thread_id(); ) + + thread_record* pHead = thread_list_.load( atomics::memory_order_relaxed ); + thread_list_.store( nullptr, atomics::memory_order_relaxed ); + + thread_record* pNext = nullptr; + for ( thread_record* hprec = pHead; hprec; hprec = pNext ) + { + assert( hprec->m_idOwner.load( atomics::memory_order_relaxed ) == nullThreadId + || hprec->m_idOwner.load( atomics::memory_order_relaxed ) == mainThreadId + || !cds::OS::is_thread_alive( hprec->m_idOwner.load( atomics::memory_order_relaxed ) ) + ); + + retired_array& retired = hprec->retired_; + + // delete retired data + for ( retired_block* block = retired.list_head_; block && block != retired.current_block_; block = block->next_ ) { + for ( retired_ptr* p = block->first(); p != block->last(); ++p ) + p->free(); + } + if ( retired.current_block_ ) { + for ( retired_ptr* p = retired.current_block_->first(); p != retired.current_cell_; ++p ) + p->free(); + } + hprec->retired_.fini(); + hprec->hazards_.clear(); + + pNext = hprec->m_pNextNode.load( atomics::memory_order_relaxed ); + hprec->m_bFree.store( true, atomics::memory_order_relaxed ); + destroy_thread_data( hprec ); + } + } + + /*static*/ CDS_EXPORT_API void smr::attach_thread() + { + if ( !tls_ ) + tls_ = instance().alloc_thread_data(); + } + + /*static*/ CDS_EXPORT_API void smr::detach_thread() + { + thread_data* rec = tls_; + if ( rec ) { + tls_ = nullptr; + instance().free_thread_data( static_cast( rec ) ); + } + } + + CDS_EXPORT_API void smr::detach_all_thread() + { + thread_record * pNext = nullptr; + const cds::OS::ThreadId nullThreadId = cds::OS::c_NullThreadId; + + for ( thread_record * hprec = thread_list_.load( atomics::memory_order_relaxed ); hprec; hprec = pNext ) { + pNext = hprec->m_pNextNode.load( atomics::memory_order_relaxed ); + if ( hprec->m_idOwner.load( atomics::memory_order_relaxed ) != nullThreadId ) { + free_thread_data( hprec ); + } + } + } + + CDS_EXPORT_API smr::thread_record* smr::create_thread_data() + { + size_t const guard_array_size = sizeof( guard ) * initial_hazard_count_; + + /* + The memory is allocated by contnuous block + Memory layout: + +--------------------------+ + | | + | thread_record | + | hazards_ +---+ + | retired_ | | + | | | + |--------------------------| | + | hazard_ptr[] |<--+ + | initial HP array | + | | + +--------------------------+ + */ + + char* mem = reinterpret_cast( s_alloc_memory( sizeof( thread_record ) + guard_array_size )); + return new( mem ) thread_record( + reinterpret_cast( mem + sizeof( thread_record ) ), initial_hazard_count_ + ); + } + + CDS_EXPORT_API void smr::destroy_thread_data( thread_record* pRec ) + { + // all retired pointers must be freed + pRec->~thread_record(); + s_free_memory( pRec ); + } + + CDS_EXPORT_API smr::thread_record* smr::alloc_thread_data() + { + thread_record * hprec = nullptr; + const cds::OS::ThreadId nullThreadId = cds::OS::c_NullThreadId; + const cds::OS::ThreadId curThreadId = cds::OS::get_current_thread_id(); + + // First try to reuse a free (non-active) DHP record + for ( hprec = thread_list_.load( atomics::memory_order_acquire ); hprec; hprec = hprec->m_pNextNode.load( atomics::memory_order_relaxed ) ) { + cds::OS::ThreadId thId = nullThreadId; + if ( !hprec->m_idOwner.compare_exchange_strong( thId, curThreadId, atomics::memory_order_relaxed, atomics::memory_order_relaxed ) ) + continue; + hprec->m_bFree.store( false, atomics::memory_order_release ); + break; + } + + if ( !hprec ) { + // No HP records available for reuse + // Allocate and push a new HP record + hprec = create_thread_data(); + hprec->m_idOwner.store( curThreadId, atomics::memory_order_relaxed ); + + thread_record* pOldHead = thread_list_.load( atomics::memory_order_relaxed ); + do { + hprec->m_pNextNode.store( pOldHead, atomics::memory_order_relaxed ); + } while ( !thread_list_.compare_exchange_weak( pOldHead, hprec, atomics::memory_order_release, atomics::memory_order_acquire ) ); + } + + hprec->hazards_.init(); + hprec->retired_.init(); + + return hprec; + } + + CDS_EXPORT_API void smr::free_thread_data( thread_record* pRec ) + { + assert( pRec != nullptr ); + //CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_RetireHPRec ) + + pRec->hazards_.clear(); + scan( pRec ); + help_scan( pRec ); + + if ( pRec->retired_.empty() ) { + pRec->retired_.fini(); + pRec->m_bFree.store( true, std::memory_order_release ); + } + else { + // Free all empty blocks + retired_block* free_block = pRec->retired_.current_block_->next_; + if ( free_block ) { + pRec->retired_.current_block_->next_ = nullptr; + while ( free_block ) { + retired_block* next = free_block->next_; + retired_allocator_.free( free_block ); + free_block = next; + --pRec->retired_.block_count_; + } + } + } + + pRec->m_idOwner.store( cds::OS::c_NullThreadId, atomics::memory_order_release ); + } + + namespace { + typedef std::vector> hp_vector; + + inline void copy_hazards( hp_vector& vect, guard const* arr, size_t size ) + { + for ( guard const* end = arr + size; arr != end; ++arr ) { + void* hp = arr->get(); + if ( hp ) + vect.push_back( hp ); + } + } + + inline size_t retire_data( hp_vector const& plist, retired_array& stg, retired_block* block, size_t block_size ) + { + auto hp_begin = plist.begin(); + auto hp_end = plist.end(); + size_t count = 0; + + for ( retired_ptr* p = block->first(), *end = p + block_size; p != end; ++p ) { + if ( cds_unlikely( std::binary_search( hp_begin, hp_end, p->m_p ))) + stg.safe_push( p ); + else { + p->free(); + ++count; + } + } + + return count; + } + + } // namespace + + CDS_EXPORT_API void smr::scan( thread_data* pThreadRec ) + { + thread_record* pRec = static_cast( pThreadRec ); + + hp_vector plist; + size_t plist_size = last_plist_size_.load( std::memory_order_relaxed ); + plist.reserve( plist_size ); + + // Stage 1: Scan HP list and insert non-null values in plist + thread_record* pNode = thread_list_.load( atomics::memory_order_acquire ); + while ( pNode ) { + if ( pNode->m_idOwner.load( std::memory_order_relaxed ) != cds::OS::c_NullThreadId ) { + copy_hazards( plist, pNode->hazards_.array_, pNode->hazards_.initial_capacity_ ); + + for ( guard_block* block = pNode->hazards_.extended_list_; block; block = block->next_ ) + copy_hazards( plist, block->first(), defaults::c_extended_guard_block_size ); + } + + pNode = pNode->m_pNextNode.load( atomics::memory_order_relaxed ); + } + + // Store plist size for next scan() call (vector reallocation optimization) + if ( plist.size() > plist_size ) + last_plist_size_.compare_exchange_weak( plist_size, plist.size(), std::memory_order_relaxed, std::memory_order_relaxed ); + + // Sort plist to simplify search in + std::sort( plist.begin(), plist.end() ); + + // Stage 2: Search plist + size_t free_count = 0; + retired_block* last_block = pRec->retired_.current_block_; + retired_ptr* last_block_cell = pRec->retired_.current_cell_; + + pRec->retired_.current_block_ = pRec->retired_.list_head_; + pRec->retired_.current_cell_ = pRec->retired_.current_block_->first(); + + for ( retired_block* block = pRec->retired_.list_head_; block; block = block->next_ ) { + bool const end_block = block == last_block; + size_t const size = end_block ? last_block_cell - block->first() : retired_block::c_capacity; + + free_count += retire_data( plist, pRec->retired_, block, size ); + + if ( end_block ) + break; + } + + // If the count of freed elements is too small, increase retired array + if ( free_count == 0 && last_block == pRec->retired_.list_tail_ && last_block_cell == last_block->last() ) + pRec->retired_.extend(); + } + + CDS_EXPORT_API void smr::help_scan( thread_data* pThis ) + { + assert( static_cast( pThis )->m_idOwner.load( atomics::memory_order_relaxed ) == cds::OS::get_current_thread_id() ); + + const cds::OS::ThreadId nullThreadId = cds::OS::c_NullThreadId; + const cds::OS::ThreadId curThreadId = cds::OS::get_current_thread_id(); + for ( thread_record* hprec = thread_list_.load( atomics::memory_order_acquire ); hprec; hprec = hprec->m_pNextNode.load( atomics::memory_order_relaxed ) ) + { + // If m_bFree == true then hprec->retired_ is empty - we don't need to see it + if ( hprec->m_bFree.load( atomics::memory_order_acquire ) ) { + assert( hprec->retired_.empty() ); + continue; + } + + // Owns hprec + // Several threads may work concurrently so we use atomic technique + { + cds::OS::ThreadId curOwner = hprec->m_idOwner.load( atomics::memory_order_relaxed ); + if ( curOwner == nullThreadId || !cds::OS::is_thread_alive( curOwner ) ) { + if ( !hprec->m_idOwner.compare_exchange_strong( curOwner, curThreadId, atomics::memory_order_acquire, atomics::memory_order_relaxed ) ) + continue; + } + else + continue; + } + + // We own the thread record successfully. Now, we can see whether it has retired pointers. + // If it has ones then we move to pThis that is private for current thread. + retired_array& src = hprec->retired_; + retired_array& dest = pThis->retired_; + + for ( retired_block* block = src.list_head_; block; block = block->next_ ) { + retired_ptr* last = block == src.current_block_ ? src.current_cell_ : block->last(); + for ( retired_ptr* p = block->first(); p != last; ++p ) { + if ( !dest.push( *p ) ) + scan( pThis ); + } + + if ( block == src.current_block_ ) + break; + } + + src.fini(); + hprec->m_bFree.store( true, atomics::memory_order_relaxed ); + hprec->m_idOwner.store( nullThreadId, atomics::memory_order_release ); + } + + scan( pThis ); + } + +}}} // namespace cds::gc::dhp diff --git a/src/dhp_gc.cpp b/src/dhp_gc.cpp deleted file mode 100644 index bf378700..00000000 --- a/src/dhp_gc.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -// Dynamic Hazard Pointer memory manager implementation - -#include // std::fill -#include // std::hash - -#include -#include - -namespace cds { namespace gc { namespace dhp { - - namespace details { - - class liberate_set { - typedef retired_ptr_node * item_type; - typedef cds::details::Allocator allocator_type; - - size_t const m_nBucketCount; - item_type * m_Buckets; - - item_type& bucket( retired_ptr_node& node ) const - { - return bucket( node.m_ptr.m_p ); - } - item_type& bucket( guard_data::guarded_ptr p ) const - { - return m_Buckets[ std::hash()( p ) & (m_nBucketCount - 1) ]; - } - - public: - liberate_set( size_t nBucketCount ) - : m_nBucketCount( nBucketCount ) - { - assert( nBucketCount > 0 ); - assert( (nBucketCount & (nBucketCount - 1)) == 0 ); - - m_Buckets = allocator_type().NewArray( nBucketCount ); - std::fill( m_Buckets, m_Buckets + nBucketCount, nullptr ); - } - - ~liberate_set() - { - allocator_type().Delete( m_Buckets, m_nBucketCount ); - } - - void insert( retired_ptr_node& node ) - { - node.m_pNext.store( nullptr, atomics::memory_order_relaxed ); - - item_type& refBucket = bucket( node ); - if ( refBucket ) { - item_type p = refBucket; - item_type prev = nullptr; - do { - if ( p->m_ptr.m_p >= node.m_ptr.m_p ) { - node.m_pNext.store( p, atomics::memory_order_relaxed ); - if ( prev ) - prev->m_pNext.store( &node, atomics::memory_order_relaxed ); - else - refBucket = &node; - return; - } - prev = p; - p = p->m_pNext.load(atomics::memory_order_relaxed); - } while ( p ); - - assert( prev != nullptr ); - prev->m_pNext.store( &node, atomics::memory_order_relaxed ); - } - else - refBucket = &node; - } - - struct erase_result - { - item_type head; - item_type tail; - size_t size; - - erase_result() - : head( nullptr ) - , tail( nullptr ) - , size(0) - {} - }; - - erase_result erase( guard_data::guarded_ptr ptr ) - { - item_type& refBucket = bucket( ptr ); - item_type p = refBucket; - item_type pPrev = nullptr; - - erase_result ret; - while ( p && p->m_ptr.m_p <= ptr ) { - if ( p->m_ptr.m_p == ptr ) { - if ( pPrev ) - pPrev->m_pNext.store( p->m_pNext.load(atomics::memory_order_relaxed ), atomics::memory_order_relaxed ); - else - refBucket = p->m_pNext.load(atomics::memory_order_relaxed); - - if ( ret.head ) - ret.tail->m_pNext.store( p, atomics::memory_order_relaxed ); - else - ret.head = p; - ret.tail = p; - ++ret.size; - } - else - pPrev = p; - p = p->m_pNext.load( atomics::memory_order_relaxed ); - } - - if ( ret.tail ) - ret.tail->m_pNext.store( nullptr, atomics::memory_order_relaxed ); - return ret; - } - - typedef std::pair list_range; - - list_range free_all() - { - item_type pTail = nullptr; - list_range ret = std::make_pair( pTail, pTail ); - - item_type const * pEndBucket = m_Buckets + m_nBucketCount; - for ( item_type * ppBucket = m_Buckets; ppBucket < pEndBucket; ++ppBucket ) { - item_type pBucket = *ppBucket; - if ( pBucket ) { - if ( ret.first ) - pTail->m_pNextFree.store( pBucket, atomics::memory_order_relaxed ); - else - ret.first = pBucket; - - pTail = pBucket; - for (;;) { - item_type pNext = pTail->m_pNext.load( atomics::memory_order_relaxed ); - pTail->m_ptr.free(); - pTail->m_pNext.store( nullptr, atomics::memory_order_relaxed ); - - /* - while ( pTail->m_pNextFree.load( atomics::memory_order_relaxed )) { - pTail = pTail->m_pNextFree.load( atomics::memory_order_relaxed ); - pTail->m_ptr.free(); - pTail->m_pNext.store( nullptr, atomics::memory_order_relaxed ); - } - */ - - if ( pNext ) { - pTail->m_pNextFree.store( pNext, atomics::memory_order_relaxed ); - pTail = pNext; - } - else - break; - } - } - } - - if ( pTail ) - pTail->m_pNextFree.store( nullptr, atomics::memory_order_relaxed ); - ret.second = pTail; - return ret; - } - }; - } - - GarbageCollector * GarbageCollector::m_pManager = nullptr; - - void CDS_STDCALL GarbageCollector::Construct( - size_t nLiberateThreshold - , size_t nInitialThreadGuardCount - , size_t nEpochCount - ) - { - if ( !m_pManager ) { - m_pManager = new GarbageCollector( nLiberateThreshold, nInitialThreadGuardCount, nEpochCount ); - } - } - - void CDS_STDCALL GarbageCollector::Destruct() - { - delete m_pManager; - m_pManager = nullptr; - } - - GarbageCollector::GarbageCollector( size_t nLiberateThreshold, size_t nInitialThreadGuardCount, size_t nEpochCount ) - : m_nLiberateThreshold( nLiberateThreshold ? nLiberateThreshold : 1024 ) - , m_nInitialThreadGuardCount( nInitialThreadGuardCount ? nInitialThreadGuardCount : 8 ) - , m_RetiredAllocator( static_cast( nEpochCount ? nEpochCount : 16 )) - , m_bStatEnabled( false ) - {} - - GarbageCollector::~GarbageCollector() - { - scan(); - } - - void GarbageCollector::scan() - { - details::retired_ptr_buffer::privatize_result retiredList = m_RetiredBuffer.privatize(); - if ( retiredList.first ) { - - size_t nLiberateThreshold = m_nLiberateThreshold.load(atomics::memory_order_relaxed); - details::liberate_set set( beans::ceil2( retiredList.second > nLiberateThreshold ? retiredList.second : nLiberateThreshold )); - - // Get list of retired pointers - size_t nRetiredCount = 0; - details::retired_ptr_node * pHead = retiredList.first; - while ( pHead ) { - details::retired_ptr_node * pNext = pHead->m_pNext.load( atomics::memory_order_relaxed ); - pHead->m_pNextFree.store( nullptr, atomics::memory_order_relaxed ); - set.insert( *pHead ); - pHead = pNext; - ++nRetiredCount; - } - - // Liberate cycle - - details::retired_ptr_node dummy; - dummy.m_pNext.store( nullptr, atomics::memory_order_relaxed ); - details::retired_ptr_node * pBusyLast = &dummy; - size_t nBusyCount = 0; - - for ( details::guard_data * pGuard = m_GuardPool.begin(); pGuard; pGuard = pGuard->pGlobalNext.load(atomics::memory_order_acquire)) - { - // get guarded pointer - details::guard_data::guarded_ptr valGuarded = pGuard->pPost.load(atomics::memory_order_acquire); - - if ( valGuarded ) { - auto retired = set.erase( valGuarded ); - if ( retired.head ) { - // Retired pointer is being guarded - // [retired.head, retired.tail] is the list linked by m_pNext field - - pBusyLast->m_pNext.store( retired.head, atomics::memory_order_relaxed ); - pBusyLast = retired.tail; - nBusyCount += retired.size; - } - } - } - - // Place [dummy.m_pNext, pBusyLast] back to m_RetiredBuffer - if ( nBusyCount ) - m_RetiredBuffer.push_list( dummy.m_pNext.load(atomics::memory_order_relaxed), pBusyLast, nBusyCount ); - - // Free all retired pointers - details::liberate_set::list_range range = set.free_all(); - - m_RetiredAllocator.inc_epoch(); - - if ( range.first ) { - assert( range.second != nullptr ); - m_RetiredAllocator.free_range( range.first, range.second ); - } - else if ( nRetiredCount >= nLiberateThreshold ) { - // scan() cycle did not free any retired pointer - double scan() threshold - m_nLiberateThreshold.compare_exchange_strong( nLiberateThreshold, nLiberateThreshold * 2, atomics::memory_order_release, atomics::memory_order_relaxed ); - } - } - } -}}} // namespace cds::gc::dhp diff --git a/src/hp.cpp b/src/hp.cpp new file mode 100644 index 00000000..1b0259d7 --- /dev/null +++ b/src/hp.cpp @@ -0,0 +1,512 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include + +#include +#include + +namespace cds { namespace gc { namespace hp { + + namespace { + void * default_alloc_memory( size_t size ) + { + return new uintptr_t[( size + sizeof( uintptr_t ) - 1 ) / sizeof( uintptr_t) ]; + } + + void default_free_memory( void* p ) + { + delete[] reinterpret_cast( p ); + } + + void* ( *s_alloc_memory )( size_t size ) = default_alloc_memory; + void ( *s_free_memory )( void* p ) = default_free_memory; + + template + class allocator + { + public: + typedef T value_type; + + allocator() {} + allocator( allocator const& ) {} + template + allocator( allocator const& ) {} + + T* allocate( size_t nCount ) + { + return reinterpret_cast( s_alloc_memory( sizeof( value_type ) * nCount ) ); + } + + void deallocate( T* p, size_t /*nCount*/ ) + { + s_free_memory( reinterpret_cast( p ) ); + } + }; + + struct defaults { + static const size_t c_nHazardPointerPerThread = 8; + static const size_t c_nMaxThreadCount = 100; + }; + + size_t calc_retired_size( size_t nSize, size_t nHPCount, size_t nThreadCount ) + { + size_t const min_size = nHPCount * nThreadCount; + return nSize < min_size ? min_size * 2 : nSize; + } + + stat s_postmortem_stat; + } // namespace + + /*static*/ CDS_EXPORT_API smr* smr::instance_ = nullptr; + thread_local thread_data* tls_ = nullptr; + + /*static*/ CDS_EXPORT_API thread_data* smr::tls() + { + assert( tls_ != nullptr ); + return tls_; + } + + struct smr::thread_record: thread_data + { + atomics::atomic m_pNextNode; ///< next hazard ptr record in list + atomics::atomic m_idOwner; ///< Owner thread id; 0 - the record is free (not owned) + atomics::atomic m_bFree; ///< true if record is free (not owned) + + thread_record( guard* guards, size_t guard_count, retired_ptr* retired_arr, size_t retired_capacity ) + : thread_data( guards, guard_count, retired_arr, retired_capacity ) + , m_bFree( false ) + {} + }; + + /*static*/ CDS_EXPORT_API void smr::set_memory_allocator( + void* ( *alloc_func )( size_t size ), + void( *free_func )( void * p ) + ) + { + // The memory allocation functions may be set BEFORE initializing HP SMR!!! + assert( instance_ == nullptr ); + + s_alloc_memory = alloc_func; + s_free_memory = free_func; + } + + + /*static*/ CDS_EXPORT_API void smr::construct( size_t nHazardPtrCount, size_t nMaxThreadCount, size_t nMaxRetiredPtrCount, scan_type nScanType ) + { + if ( !instance_ ) { + instance_ = new( s_alloc_memory(sizeof(smr))) smr( nHazardPtrCount, nMaxThreadCount, nMaxRetiredPtrCount, nScanType ); + } + } + + /*static*/ CDS_EXPORT_API void smr::destruct( bool bDetachAll ) + { + if ( instance_ ) { + if ( bDetachAll ) + instance_->detach_all_thread(); + + instance_->~smr(); + s_free_memory( instance_ ); + instance_ = nullptr; + } + } + + CDS_EXPORT_API smr::smr( size_t nHazardPtrCount, size_t nMaxThreadCount, size_t nMaxRetiredPtrCount, scan_type nScanType ) + : thread_list_( nullptr ) + , hazard_ptr_count_( nHazardPtrCount == 0 ? defaults::c_nHazardPointerPerThread : nHazardPtrCount ) + , max_thread_count_( nMaxThreadCount == 0 ? defaults::c_nMaxThreadCount : nMaxThreadCount ) + , max_retired_ptr_count_( calc_retired_size( nMaxRetiredPtrCount, hazard_ptr_count_, max_thread_count_ )) + , scan_type_( nScanType ) + , scan_func_( nScanType == classic ? &smr::classic_scan : &smr::inplace_scan ) + {} + + CDS_EXPORT_API smr::~smr() + { + CDS_DEBUG_ONLY( const cds::OS::ThreadId nullThreadId = cds::OS::c_NullThreadId; ) + CDS_DEBUG_ONLY( const cds::OS::ThreadId mainThreadId = cds::OS::get_current_thread_id();) + + CDS_HPSTAT( statistics( s_postmortem_stat )); + + thread_record* pHead = thread_list_.load( atomics::memory_order_relaxed ); + thread_list_.store( nullptr, atomics::memory_order_relaxed ); + + thread_record* pNext = nullptr; + for ( thread_record* hprec = pHead; hprec; hprec = pNext ) + { + assert( hprec->m_idOwner.load( atomics::memory_order_relaxed ) == nullThreadId + || hprec->m_idOwner.load( atomics::memory_order_relaxed ) == mainThreadId + || !cds::OS::is_thread_alive( hprec->m_idOwner.load( atomics::memory_order_relaxed ) ) + ); + + retired_array& arr = hprec->retired_; + for ( retired_ptr* cur{ arr.first() }, *last{ arr.last() }; cur != last; ++cur ) { + cur->free(); + CDS_HPSTAT( ++s_postmortem_stat.free_count ); + } + + arr.reset( 0 ); + pNext = hprec->m_pNextNode.load( atomics::memory_order_relaxed ); + hprec->m_bFree.store( true, atomics::memory_order_relaxed ); + destroy_thread_data( hprec ); + } + } + + + CDS_EXPORT_API smr::thread_record* smr::create_thread_data() + { + size_t const guard_array_size = thread_hp_storage::calc_array_size( get_hazard_ptr_count()); + size_t const retired_array_size = retired_array::calc_array_size( get_max_retired_ptr_count()); + size_t const nSize = sizeof( thread_record ) + guard_array_size + retired_array_size; + + /* + The memory is allocated by contnuous block + Memory layout: + +--------------------------+ + | | + | thread_record | + | hazards_ +---+ + +---| retired_ | | + | | | | + | |--------------------------| | + | | hazard_ptr[] |<--+ + | | | + | | | + | |--------------------------| + +-->| retired_ptr[] | + | | + | | + +--------------------------+ + */ + + char* mem = reinterpret_cast( s_alloc_memory( nSize )); + return new( mem ) thread_record( + reinterpret_cast( mem + sizeof( thread_record )), get_hazard_ptr_count(), + reinterpret_cast( mem + sizeof( thread_record ) + guard_array_size ), get_max_retired_ptr_count() + ); + } + + CDS_EXPORT_API void smr::destroy_thread_data( thread_record* pRec ) + { + // all retired pointers must be freed + assert( pRec->retired_.size() == 0 ); + + pRec->~thread_record(); + s_free_memory( pRec ); + } + + + CDS_EXPORT_API smr::thread_record* smr::alloc_thread_data() + { + //CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_AllocHPRec ) + + thread_record * hprec; + const cds::OS::ThreadId nullThreadId = cds::OS::c_NullThreadId; + const cds::OS::ThreadId curThreadId = cds::OS::get_current_thread_id(); + + // First try to reuse a free (non-active) HP record + for ( hprec = thread_list_.load( atomics::memory_order_acquire ); hprec; hprec = hprec->m_pNextNode.load( atomics::memory_order_relaxed ) ) { + cds::OS::ThreadId thId = nullThreadId; + if ( !hprec->m_idOwner.compare_exchange_strong( thId, curThreadId, atomics::memory_order_relaxed, atomics::memory_order_relaxed ) ) + continue; + hprec->m_bFree.store( false, atomics::memory_order_release ); + return hprec; + } + + // No HP records available for reuse + // Allocate and push a new HP record + hprec = create_thread_data(); + hprec->m_idOwner.store( curThreadId, atomics::memory_order_relaxed ); + + thread_record* pOldHead = thread_list_.load( atomics::memory_order_relaxed ); + do { + hprec->m_pNextNode.store( pOldHead, atomics::memory_order_relaxed ); + } while ( !thread_list_.compare_exchange_weak( pOldHead, hprec, atomics::memory_order_release, atomics::memory_order_acquire ) ); + + return hprec; + } + + CDS_EXPORT_API void smr::free_thread_data( smr::thread_record* pRec ) + { + assert( pRec != nullptr ); + //CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_RetireHPRec ) + + pRec->hazards_.clear(); + scan( pRec ); + help_scan( pRec ); + pRec->m_idOwner.store( cds::OS::c_NullThreadId, atomics::memory_order_release ); + } + + CDS_EXPORT_API void smr::detach_all_thread() + { + thread_record * pNext = nullptr; + const cds::OS::ThreadId nullThreadId = cds::OS::c_NullThreadId; + + for ( thread_record * hprec = thread_list_.load( atomics::memory_order_relaxed ); hprec; hprec = pNext ) { + pNext = hprec->m_pNextNode.load( atomics::memory_order_relaxed ); + if ( hprec->m_idOwner.load( atomics::memory_order_relaxed ) != nullThreadId ) { + free_thread_data( hprec ); + } + } + } + + /*static*/ CDS_EXPORT_API void smr::attach_thread() + { + if ( !tls_ ) + tls_ = instance().alloc_thread_data(); + } + + /*static*/ CDS_EXPORT_API void smr::detach_thread() + { + thread_data* rec = tls_; + if ( rec ) { + tls_ = nullptr; + instance().free_thread_data( static_cast( rec )); + } + } + + + CDS_EXPORT_API void smr::inplace_scan( thread_data* pThreadRec ) + { + thread_record* pRec = static_cast( pThreadRec ); + + //CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_ScanCallCount ) + + // In-place scan algo uses LSB of retired ptr as a mark for internal purposes. + // It is correct if all retired pointers are ar least 2-byte aligned (LSB is zero). + // If it is wrong, we use classic scan algorithm + + // Check if all retired pointers has zero LSB + // LSB is used for marking pointers that cannot be deleted yet + retired_ptr* first_retired = pRec->retired_.first(); + retired_ptr* last_retired = pRec->retired_.last(); + if ( first_retired == last_retired ) + return; + + for ( auto it = first_retired; it != last_retired; ++it ) { + if ( it->m_n & 1 ) { + // found a pointer with LSB bit set - use classic_scan + classic_scan( pRec ); + return; + } + } + + CDS_HPSTAT( ++pRec->stat_.scan_count ); + + // Sort retired pointer array + std::sort( first_retired, last_retired, retired_ptr::less ); + + // Check double free +# ifdef _DEBUG + { + auto it = first_retired; + auto itPrev = it; + while ( ++it != last_retired ) { + assert( itPrev->m_p < it->m_p ); + itPrev = it; + } + } +# endif + + // Search guarded pointers in retired array + thread_record* pNode = thread_list_.load( atomics::memory_order_acquire ); + + { + retired_ptr dummy_retired; + while ( pNode ) { + if ( !pNode->m_bFree.load( atomics::memory_order_relaxed )) { + thread_hp_storage& hpstg = pNode->hazards_; + for ( size_t i = 0; i < hazard_ptr_count_; ++i ) { + pRec->sync(); + void * hptr = hpstg[i].get(); + if ( hptr ) { + dummy_retired.m_p = hptr; + retired_ptr* it = std::lower_bound( first_retired, last_retired, dummy_retired, retired_ptr::less ); + if ( it != last_retired && it->m_p == hptr ) { + // Mark retired pointer as guarded + it->m_n |= 1; + } + } + } + } + pNode = pNode->m_pNextNode.load( atomics::memory_order_relaxed ); + } + } + + // Move all marked pointers to head of array + { + retired_ptr* insert_pos = first_retired; + for ( retired_ptr* it = first_retired; it != last_retired; ++it ) { + if ( it->m_n & 1 ) { + it->m_n &= ~uintptr_t(1); + if ( insert_pos != it ) + *insert_pos = *it; + ++insert_pos; + } + else { + // Retired pointer may be freed + it->free(); + CDS_HPSTAT( ++pRec->stat_.free_count ); + } + } + const size_t nDeferred = insert_pos - first_retired; + pRec->retired_.reset( nDeferred ); + } + } + + CDS_EXPORT_API void smr::classic_scan( thread_data* pThreadRec ) + { + thread_record* pRec = static_cast( pThreadRec ); + + CDS_HPSTAT( ++pRec->stat_.scan_count ); + + std::vector< void*, allocator> plist; + plist.reserve( get_max_thread_count() * get_hazard_ptr_count()); + assert( plist.size() == 0 ); + + // Stage 1: Scan HP list and insert non-null values in plist + + thread_record* pNode = thread_list_.load( atomics::memory_order_acquire ); + + while ( pNode ) { + for ( size_t i = 0; i < get_hazard_ptr_count(); ++i ) { + pRec->sync(); + void * hptr = pNode->hazards_[i].get(); + if ( hptr ) + plist.push_back( hptr ); + } + pNode = pNode->m_pNextNode.load( atomics::memory_order_relaxed ); + } + + // Sort plist to simplify search in + std::sort( plist.begin(), plist.end() ); + + // Stage 2: Search plist + retired_array& retired = pRec->retired_; + + retired_ptr* first_retired = retired.first(); + retired_ptr* last_retired = retired.last(); + + { + auto itBegin = plist.begin(); + auto itEnd = plist.end(); + retired_ptr* insert_pos = first_retired; + for ( retired_ptr* it = first_retired; it != last_retired; ++it ) { + if ( std::binary_search( itBegin, itEnd, first_retired->m_p ) ) { + if ( insert_pos != it ) + *insert_pos = *it; + ++insert_pos; + } + else { + it->free(); + CDS_HPSTAT( ++pRec->stat_.free_count ); + } + } + + retired.reset( insert_pos - first_retired ); + + //CDS_HAZARDPTR_STATISTIC( m_Stat.m_DeferredNode += nDeferredCount ) + //CDS_HAZARDPTR_STATISTIC( m_Stat.m_DeletedNode += ( itRetiredEnd - arrRetired.begin() ) - nDeferredCount ) + } + } + + CDS_EXPORT_API void smr::help_scan( thread_data* pThis ) + { + assert( static_cast( pThis )->m_idOwner.load( atomics::memory_order_relaxed ) == cds::OS::get_current_thread_id() ); + + CDS_HPSTAT( ++pThis->stat_.help_scan_count ); + + const cds::OS::ThreadId nullThreadId = cds::OS::c_NullThreadId; + const cds::OS::ThreadId curThreadId = cds::OS::get_current_thread_id(); + for ( thread_record* hprec = thread_list_.load( atomics::memory_order_acquire ); hprec; hprec = hprec->m_pNextNode.load( atomics::memory_order_relaxed )) + { + // If m_bFree == true then hprec->retired_ is empty - we don't need to see it + if ( hprec->m_bFree.load( atomics::memory_order_acquire )) + continue; + + // Owns hprec if it is empty. + // Several threads may work concurrently so we use atomic technique only. + { + cds::OS::ThreadId curOwner = hprec->m_idOwner.load( atomics::memory_order_relaxed ); + if ( curOwner == nullThreadId || !cds::OS::is_thread_alive( curOwner ) ) { + if ( !hprec->m_idOwner.compare_exchange_strong( curOwner, curThreadId, atomics::memory_order_acquire, atomics::memory_order_relaxed ) ) + continue; + } + else + continue; + } + + // We own the thread record successfully. Now, we can see whether it has retired pointers. + // If it has ones then we move to pThis that is private for current thread. + retired_array& src = hprec->retired_; + retired_array& dest = pThis->retired_; + assert( !dest.full() ); + + retired_ptr* src_first = src.first(); + retired_ptr* src_last = src.last(); + + for ( ; src_first != src_last; ++src_first ) { + if ( !dest.push( std::move( *src_first ))) + scan( pThis ); + } + + src.reset( 0 ); + + hprec->m_bFree.store( true, atomics::memory_order_relaxed ); + hprec->m_idOwner.store( nullThreadId, atomics::memory_order_release ); + + scan( pThis ); + } + } + + void smr::statistics( stat& st ) + { + st.clear(); +# ifdef CDS_ENABLE_HPSTAT + for ( thread_record* hprec = thread_list_.load( atomics::memory_order_acquire ); hprec; hprec = hprec->m_pNextNode.load( atomics::memory_order_relaxed ) ) + { + ++st.thread_rec_count; + st.guard_allocated += hprec->hazards_.alloc_guard_count_; + st.guard_freed += hprec->hazards_.free_guard_count_; + st.retired_count += hprec->retired_.retire_call_count_; + st.free_count += hprec->stat_.free_count; + st.scan_count += hprec->stat_.scan_count; + st.help_scan_count += hprec->stat_.help_scan_count; + } +# endif + } + +}}} // namespace cds::gc::hp + +/*static*/ cds::gc::HP::stat const& cds::gc::HP::postmortem_statistics() +{ + return cds::gc::hp::s_postmortem_stat; +} + diff --git a/src/hp_gc.cpp b/src/hp_gc.cpp deleted file mode 100644 index b4ab05de..00000000 --- a/src/hp_gc.cpp +++ /dev/null @@ -1,427 +0,0 @@ -/* - This file is a part of libcds - Concurrent Data Structures library - - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 - - Source code repo: http://github.com/khizmax/libcds/ - Download: http://sourceforge.net/projects/libcds/files/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - File: hzp_gc.cpp - - Hazard Pointers memory reclamation strategy implementation - - Editions: - 2008.02.10 Maxim.Khiszinsky Created -*/ - -#include - -#include // std::sort -#include "hp_const.h" - -#define CDS_HAZARDPTR_STATISTIC( _x ) if ( m_bStatEnabled ) { _x; } - -namespace cds { namespace gc { - namespace hp { - - /// Max array size of retired pointers - static const size_t c_nMaxRetireNodeCount = c_nHazardPointerPerThread * c_nMaxThreadCount * 2; - - GarbageCollector * GarbageCollector::m_pHZPManager = nullptr; - - void CDS_STDCALL GarbageCollector::Construct( size_t nHazardPtrCount, size_t nMaxThreadCount, size_t nMaxRetiredPtrCount, scan_type nScanType ) - { - if ( !m_pHZPManager ) { - m_pHZPManager = new GarbageCollector( nHazardPtrCount, nMaxThreadCount, nMaxRetiredPtrCount, nScanType ); - } - } - - void CDS_STDCALL GarbageCollector::Destruct( bool bDetachAll ) - { - if ( m_pHZPManager ) { - if ( bDetachAll ) - m_pHZPManager->detachAllThread(); - - delete m_pHZPManager; - m_pHZPManager = nullptr; - } - } - - GarbageCollector::GarbageCollector( - size_t nHazardPtrCount, - size_t nMaxThreadCount, - size_t nMaxRetiredPtrCount, - scan_type nScanType - ) - : m_pListHead( nullptr ) - ,m_bStatEnabled( false ) - ,m_nHazardPointerCount( nHazardPtrCount == 0 ? c_nHazardPointerPerThread : nHazardPtrCount ) - ,m_nMaxThreadCount( nMaxThreadCount == 0 ? c_nMaxThreadCount : nMaxThreadCount ) - ,m_nMaxRetiredPtrCount( nMaxRetiredPtrCount > c_nMaxRetireNodeCount ? nMaxRetiredPtrCount : c_nMaxRetireNodeCount ) - ,m_nScanType( nScanType ) - {} - - GarbageCollector::~GarbageCollector() - { - CDS_DEBUG_ONLY( const cds::OS::ThreadId nullThreadId = cds::OS::c_NullThreadId; ) - CDS_DEBUG_ONLY( const cds::OS::ThreadId mainThreadId = cds::OS::get_current_thread_id() ;) - - hplist_node * pHead = m_pListHead.load( atomics::memory_order_relaxed ); - m_pListHead.store( nullptr, atomics::memory_order_relaxed ); - - hplist_node * pNext = nullptr; - for ( hplist_node * hprec = pHead; hprec; hprec = pNext ) { - assert( hprec->m_idOwner.load( atomics::memory_order_relaxed ) == nullThreadId - || hprec->m_idOwner.load( atomics::memory_order_relaxed ) == mainThreadId - || !cds::OS::is_thread_alive( hprec->m_idOwner.load( atomics::memory_order_relaxed )) - ); - details::retired_vector& vect = hprec->m_arrRetired; - details::retired_vector::iterator itRetired = vect.begin(); - details::retired_vector::iterator itRetiredEnd = vect.end(); - while ( itRetired != itRetiredEnd ) { - itRetired->free(); - ++itRetired; - } - vect.clear(); - pNext = hprec->m_pNextNode.load( atomics::memory_order_relaxed ); - hprec->m_bFree.store( true, atomics::memory_order_relaxed ); - DeleteHPRec( hprec ); - } - } - - inline GarbageCollector::hplist_node * GarbageCollector::NewHPRec( OS::ThreadId owner ) - { - CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_AllocNewHPRec ) - return new hplist_node( *this, owner ); - } - - inline void GarbageCollector::DeleteHPRec( hplist_node * pNode ) - { - CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_DeleteHPRec ) - assert( pNode->m_arrRetired.size() == 0 ); - delete pNode; - } - - details::hp_record * GarbageCollector::alloc_hp_record() - { - CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_AllocHPRec ) - - hplist_node * hprec; - const cds::OS::ThreadId nullThreadId = cds::OS::c_NullThreadId; - const cds::OS::ThreadId curThreadId = cds::OS::get_current_thread_id(); - - // First try to reuse a retired (non-active) HP record - for ( hprec = m_pListHead.load( atomics::memory_order_relaxed ); hprec; hprec = hprec->m_pNextNode.load( atomics::memory_order_relaxed )) { - cds::OS::ThreadId thId = nullThreadId; - if ( !hprec->m_idOwner.compare_exchange_strong( thId, curThreadId, atomics::memory_order_acquire, atomics::memory_order_relaxed )) - continue; - hprec->m_bFree.store( false, atomics::memory_order_relaxed ); - return hprec; - } - - // No HP records available for reuse - // Allocate and push a new HP record - hprec = NewHPRec( curThreadId ); - - hplist_node * pOldHead = m_pListHead.load( atomics::memory_order_relaxed ); - do { - hprec->m_pNextNode.store( pOldHead, atomics::memory_order_relaxed ); - } while ( !m_pListHead.compare_exchange_weak( pOldHead, hprec, atomics::memory_order_acq_rel, atomics::memory_order_acquire )); - - return hprec; - } - - void GarbageCollector::free_hp_record( details::hp_record * pRec ) - { - assert( pRec != nullptr ); - CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_RetireHPRec ) - - pRec->clear(); - Scan( pRec ); - HelpScan( pRec ); - hplist_node * pNode = static_cast( pRec ); - pNode->m_idOwner.store( cds::OS::c_NullThreadId, atomics::memory_order_release ); - } - - void GarbageCollector::detachAllThread() - { - hplist_node * pNext = nullptr; - const cds::OS::ThreadId nullThreadId = cds::OS::c_NullThreadId; - for ( hplist_node * hprec = m_pListHead.load(atomics::memory_order_relaxed); hprec; hprec = pNext ) { - pNext = hprec->m_pNextNode.load( atomics::memory_order_relaxed ); - if ( hprec->m_idOwner.load(atomics::memory_order_relaxed) != nullThreadId ) { - free_hp_record( hprec ); - } - } - } - - void GarbageCollector::classic_scan( details::hp_record * pRec ) - { - CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_ScanCallCount ) - - std::vector< void * > plist; - plist.reserve( m_nMaxThreadCount * m_nHazardPointerCount ); - assert( plist.size() == 0 ); - - // Stage 1: Scan HP list and insert non-null values in plist - - hplist_node * pNode = m_pListHead.load(atomics::memory_order_relaxed); - - while ( pNode ) { - for ( size_t i = 0; i < m_nHazardPointerCount; ++i ) { - pRec->sync(); - void * hptr = pNode->m_hzp[i].get(); - if ( hptr ) - plist.push_back( hptr ); - } - pNode = pNode->m_pNextNode.load( atomics::memory_order_relaxed ); - } - - // Sort plist to simplify search in - std::sort( plist.begin(), plist.end()); - - // Stage 2: Search plist - details::retired_vector& arrRetired = pRec->m_arrRetired; - - details::retired_vector::iterator itRetired = arrRetired.begin(); - details::retired_vector::iterator itRetiredEnd = arrRetired.end(); - // arrRetired is not a std::vector! - // clear() is just set up item counter to 0, the items is not destroyed - arrRetired.clear(); - - { - std::vector< void * >::iterator itBegin = plist.begin(); - std::vector< void * >::iterator itEnd = plist.end(); - size_t nDeferredCount = 0; - while ( itRetired != itRetiredEnd ) { - if ( std::binary_search( itBegin, itEnd, itRetired->m_p )) { - arrRetired.push( *itRetired ); - ++nDeferredCount; - } - else - itRetired->free(); - ++itRetired; - } - CDS_HAZARDPTR_STATISTIC( m_Stat.m_DeferredNode += nDeferredCount ) - CDS_HAZARDPTR_STATISTIC( m_Stat.m_DeletedNode += (itRetiredEnd - arrRetired.begin()) - nDeferredCount ) - } - } - - void GarbageCollector::inplace_scan( details::hp_record * pRec ) - { - CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_ScanCallCount ) - - // In-place scan algo uses LSB of retired ptr as a mark for internal purposes. - // It is correct if all retired pointers are ar least 2-byte aligned (LSB is zero). - // If it is wrong, we use classic scan algorithm - - // Check if all retired pointers has zero LSB - // LSB is used for marking pointers that cannot be deleted yet - details::retired_vector::iterator itRetired = pRec->m_arrRetired.begin(); - details::retired_vector::iterator itRetiredEnd = pRec->m_arrRetired.end(); - for ( auto it = itRetired; it != itRetiredEnd; ++it ) { - if ( it->m_n & 1 ) { - // found a pointer with LSB bit set - use classic_scan - classic_scan( pRec ); - return; - } - } - - // Sort retired pointer array - std::sort( itRetired, itRetiredEnd, cds::gc::details::retired_ptr::less ); - - // Check double free - /* - { - auto it = itRetired; - auto itPrev = it; - while ( ++it != itRetiredEnd ) { - if ( it->m_p == itPrev->m_p ) - throw std::runtime_error( "Double free" ); - itPrev = it; - } - } - */ - - // Search guarded pointers in retired array - hplist_node * pNode = m_pListHead.load( atomics::memory_order_relaxed ); - - { - details::retired_ptr dummyRetired; - while ( pNode ) { - if ( !pNode->m_bFree.load( atomics::memory_order_relaxed )) { - for ( size_t i = 0; i < m_nHazardPointerCount; ++i ) { - pRec->sync(); - void * hptr = pNode->m_hzp[i].get(); - if ( hptr ) { - dummyRetired.m_p = hptr; - details::retired_vector::iterator it = std::lower_bound( itRetired, itRetiredEnd, dummyRetired, cds::gc::details::retired_ptr::less ); - if ( it != itRetiredEnd && it->m_p == hptr ) { - // Mark retired pointer as guarded - it->m_n |= 1; - } - } - } - } - pNode = pNode->m_pNextNode.load( atomics::memory_order_relaxed ); - } - } - - // Move all marked pointers to head of array - { - auto itInsert = itRetired; - for ( auto it = itRetired; it != itRetiredEnd; ++it ) { - if ( it->m_n & 1 ) { - it->m_n &= ~1; - if ( itInsert != it ) - *itInsert = *it; - ++itInsert; - } - else { - // Retired pointer may be freed - it->free(); - } - } - const size_t nDeferred = itInsert - itRetired; - pRec->m_arrRetired.size( nDeferred ); - CDS_HAZARDPTR_STATISTIC( m_Stat.m_DeferredNode += nDeferred ) - CDS_HAZARDPTR_STATISTIC( m_Stat.m_DeletedNode += (itRetiredEnd - itRetired) - nDeferred ) - } - } - - void GarbageCollector::HelpScan( details::hp_record * pThis ) - { - CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_HelpScanCallCount ) - - assert( static_cast(pThis)->m_idOwner.load(atomics::memory_order_relaxed) == cds::OS::get_current_thread_id()); - - const cds::OS::ThreadId nullThreadId = cds::OS::c_NullThreadId; - const cds::OS::ThreadId curThreadId = cds::OS::get_current_thread_id(); - for ( hplist_node * hprec = m_pListHead.load(atomics::memory_order_relaxed); hprec; hprec = hprec->m_pNextNode.load( atomics::memory_order_relaxed )) { - - // If m_bFree == true then hprec->m_arrRetired is empty - we don't need to see it - if ( hprec->m_bFree.load(atomics::memory_order_relaxed)) - continue; - - // Owns hprec if it is empty. - // Several threads may work concurrently so we use atomic technique only. - { - cds::OS::ThreadId curOwner = hprec->m_idOwner.load(atomics::memory_order_relaxed); - if ( curOwner == nullThreadId || !cds::OS::is_thread_alive( curOwner )) { - if ( !hprec->m_idOwner.compare_exchange_strong( curOwner, curThreadId, atomics::memory_order_acquire, atomics::memory_order_relaxed )) - continue; - } - else - continue; - //else { - // curOwner = nullThreadId; - // if ( !hprec->m_idOwner.compare_exchange_strong( curOwner, curThreadId, atomics::memory_order_acquire, atomics::memory_order_relaxed )) - // continue; - //} - } - - // We own the thread successfully. Now, we can see whether hp_record has retired pointers. - // If it has ones then we move to pThis that is private for current thread. - details::retired_vector& src = hprec->m_arrRetired; - details::retired_vector& dest = pThis->m_arrRetired; - assert( !dest.isFull()); - details::retired_vector::iterator itRetired = src.begin(); - - // TSan can issue a warning here: - // read src.m_nSize in src.end() - // write src.m_nSize in src.clear() - // This is false positive since we own hprec - CDS_TSAN_ANNOTATE_IGNORE_READS_BEGIN; - details::retired_vector::iterator itRetiredEnd = src.end(); - CDS_TSAN_ANNOTATE_IGNORE_READS_END; - - while ( itRetired != itRetiredEnd ) { - dest.push( *itRetired ); - if ( dest.isFull()) { - CDS_HAZARDPTR_STATISTIC( ++m_Stat.m_CallScanFromHelpScan ) - Scan( pThis ); - } - ++itRetired; - } - - // TSan: write src.m_nSize, see a comment above - CDS_TSAN_ANNOTATE_IGNORE_WRITES_BEGIN; - src.clear(); - CDS_TSAN_ANNOTATE_IGNORE_WRITES_END; - - hprec->m_bFree.store(true, atomics::memory_order_relaxed); - hprec->m_idOwner.store( nullThreadId, atomics::memory_order_release ); - - Scan( pThis ); - } - } - - GarbageCollector::InternalState& GarbageCollector::getInternalState( GarbageCollector::InternalState& stat) const - { - stat.nHPCount = m_nHazardPointerCount; - stat.nMaxThreadCount = m_nMaxThreadCount; - stat.nMaxRetiredPtrCount = m_nMaxRetiredPtrCount; - stat.nHPRecSize = sizeof( hplist_node ) - + sizeof(details::retired_ptr) * m_nMaxRetiredPtrCount; - - stat.nHPRecAllocated = - stat.nHPRecUsed = - stat.nTotalRetiredPtrCount = - stat.nRetiredPtrInFreeHPRecs = 0; - - for ( hplist_node * hprec = m_pListHead.load(atomics::memory_order_relaxed); hprec; hprec = hprec->m_pNextNode.load( atomics::memory_order_relaxed )) { - ++stat.nHPRecAllocated; - stat.nTotalRetiredPtrCount += hprec->m_arrRetired.size(); - - if ( hprec->m_bFree.load(atomics::memory_order_relaxed)) { - // Free HP record - stat.nRetiredPtrInFreeHPRecs += hprec->m_arrRetired.size(); - } - else { - // Used HP record - ++stat.nHPRecUsed; - } - } - - // Events - stat.evcAllocHPRec = m_Stat.m_AllocHPRec; - stat.evcRetireHPRec = m_Stat.m_RetireHPRec; - stat.evcAllocNewHPRec= m_Stat.m_AllocNewHPRec; - stat.evcDeleteHPRec = m_Stat.m_DeleteHPRec; - - stat.evcScanCall = m_Stat.m_ScanCallCount; - stat.evcHelpScanCall = m_Stat.m_HelpScanCallCount; - stat.evcScanFromHelpScan= m_Stat.m_CallScanFromHelpScan; - - stat.evcDeletedNode = m_Stat.m_DeletedNode; - stat.evcDeferredNode = m_Stat.m_DeferredNode; - - return stat; - } - - - } //namespace hp -}} // namespace cds::gc diff --git a/src/init.cpp b/src/init.cpp index 1ef64d9f..7e324eaf 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -49,9 +49,6 @@ namespace cds { - CDS_EXPORT_API atomics::atomic threading::ThreadData::s_nLastUsedProcNo(0); - CDS_EXPORT_API size_t threading::ThreadData::s_nProcCount = 1; - #if CDS_OS_INTERFACE == CDS_OSI_WINDOWS CDS_EXPORT_API DWORD cds::threading::wintls::Manager::Holder::m_key = TLS_OUT_OF_INDEXES; # if CDS_COMPILER == CDS_COMPILER_MSVC || CDS_COMPILER == CDS_COMPILER_INTEL diff --git a/src/thread_data.cpp b/src/thread_data.cpp new file mode 100644 index 00000000..1a45b09e --- /dev/null +++ b/src/thread_data.cpp @@ -0,0 +1,99 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include + +namespace cds { namespace threading { + + CDS_EXPORT_API atomics::atomic ThreadData::s_nLastUsedProcNo( 0 ); + CDS_EXPORT_API size_t ThreadData::s_nProcCount = 1; + + CDS_EXPORT_API void ThreadData::init() + { + if ( m_nAttachCount++ == 0 ) { + if ( cds::gc::HP::isUsed() ) + cds::gc::hp::smr::attach_thread(); + if ( cds::gc::DHP::isUsed() ) + cds::gc::dhp::smr::attach_thread(); + + if ( cds::urcu::details::singleton::isUsed() ) + m_pGPIRCU = cds::urcu::details::singleton::attach_thread(); + if ( cds::urcu::details::singleton::isUsed() ) + m_pGPBRCU = cds::urcu::details::singleton::attach_thread(); + if ( cds::urcu::details::singleton::isUsed() ) + m_pGPTRCU = cds::urcu::details::singleton::attach_thread(); +#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED + if ( cds::urcu::details::singleton::isUsed() ) + m_pSHBRCU = cds::urcu::details::singleton::attach_thread(); + if ( cds::urcu::details::singleton::isUsed() ) + m_pSHTRCU = cds::urcu::details::singleton::attach_thread(); +#endif + } + } + + CDS_EXPORT_API bool ThreadData::fini() + { + if ( --m_nAttachCount == 0 ) { + if ( cds::gc::DHP::isUsed() ) + cds::gc::dhp::smr::detach_thread(); + if ( cds::gc::HP::isUsed() ) + cds::gc::hp::smr::detach_thread(); + + if ( cds::urcu::details::singleton::isUsed() ) { + cds::urcu::details::singleton::detach_thread( m_pGPIRCU ); + m_pGPIRCU = nullptr; + } + if ( cds::urcu::details::singleton::isUsed() ) { + cds::urcu::details::singleton::detach_thread( m_pGPBRCU ); + m_pGPBRCU = nullptr; + } + if ( cds::urcu::details::singleton::isUsed() ) { + cds::urcu::details::singleton::detach_thread( m_pGPTRCU ); + m_pGPTRCU = nullptr; + } +#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED + if ( cds::urcu::details::singleton::isUsed() ) { + cds::urcu::details::singleton::detach_thread( m_pSHBRCU ); + m_pSHBRCU = nullptr; + } + if ( cds::urcu::details::singleton::isUsed() ) { + cds::urcu::details::singleton::detach_thread( m_pSHTRCU ); + m_pSHTRCU = nullptr; + } +#endif + return true; + } + return false; + } + + +}} // namespace cds::threading diff --git a/test/stress/data/test-debug.conf b/test/stress/data/test-debug.conf index 9c57b513..c9f9a939 100644 --- a/test/stress/data/test-debug.conf +++ b/test/stress/data/test-debug.conf @@ -1,12 +1,12 @@ [General] # HZP scan strategy, possible values are "classic", "inplace". Default is "classic" -HZP_scan_strategy=inplace +hp_scan_strategy=inplace hazard_pointer_count=72 +#hp_max_thread_count=32 +#hp_retired_ptr_count=256 # cds::gc::DHP initialization parameters -dhp_liberate_threshold=1024 dhp_init_guard_count=8 -dhp_epoch_count=16 # cds::urcu::gc initialization parameters rcu_buffer_size=256 diff --git a/test/stress/data/test-express-x86.conf b/test/stress/data/test-express-x86.conf index 8362345b..f87e6e39 100644 --- a/test/stress/data/test-express-x86.conf +++ b/test/stress/data/test-express-x86.conf @@ -1,13 +1,13 @@ [General] # HZP scan strategy, possible values are "classic", "inplace". Default is "classic" -HZP_scan_strategy=inplace +hp_scan_strategy=inplace # Hazard pointer count per thread, for gc::HP hazard_pointer_count=72 +#hp_max_thread_count=32 +#hp_retired_ptr_count=256 # cds::gc::DHP initialization parameters -dhp_liberate_threshold=1024 dhp_init_guard_count=16 -dhp_epoch_count=16 # cds::urcu::gc initialization parameters rcu_buffer_size=256 diff --git a/test/stress/data/test-express.conf b/test/stress/data/test-express.conf index 559b893f..7f29c24c 100644 --- a/test/stress/data/test-express.conf +++ b/test/stress/data/test-express.conf @@ -1,13 +1,13 @@ [General] -# HZP scan strategy, possible values are "classic", "inplace". Default is "classic" -HZP_scan_strategy=inplace +# HP scan strategy, possible values are "classic", "inplace". Default is "classic" +hp_scan_strategy=inplace # Hazard pointer count per thread, for gc::HP hazard_pointer_count=72 +#hp_max_thread_count=32 +#hp_retired_ptr_count=256 # cds::gc::DHP initialization parameters -dhp_liberate_threshold=1024 dhp_init_guard_count=16 -dhp_epoch_count=16 # cds::urcu::gc initialization parameters rcu_buffer_size=256 diff --git a/test/stress/data/test.conf b/test/stress/data/test.conf index bc3ec554..db48a835 100644 --- a/test/stress/data/test.conf +++ b/test/stress/data/test.conf @@ -1,12 +1,12 @@ [General] # HZP scan strategy, possible values are "classic", "inplace". Default is "classic" -HZP_scan_strategy=inplace +hp_scan_strategy=inplace hazard_pointer_count=72 +#hp_max_thread_count=32 +#hp_retired_ptr_count=256 # cds::gc::DHP initialization parameters -dhp_liberate_threshold=1024 dhp_init_guard_count=16 -dhp_epoch_count=16 # cds::urcu::gc initialization parameters rcu_buffer_size=256 diff --git a/test/stress/main.cpp b/test/stress/main.cpp index cd3da6de..0c7acd83 100644 --- a/test/stress/main.cpp +++ b/test/stress/main.cpp @@ -58,13 +58,15 @@ int main( int argc, char **argv ) cds_test::config const& general_cfg = cds_test::stress_fixture::get_config( "General" ); // Init SMR - cds::gc::HP hzpGC( general_cfg.get_size_t( "hazard_pointer_count", 16 )); - hzpGC.setScanType( general_cfg.get( "HZP_scan_strategy", "inplace" ) == "inplace" ? cds::gc::HP::scan_type::inplace : cds::gc::HP::scan_type::classic ); + cds::gc::HP hzpGC( + general_cfg.get_size_t( "hazard_pointer_count", 16 ), + general_cfg.get_size_t( "hp_max_thread_count", 0 ), + general_cfg.get_size_t( "hp_retired_ptr_count", 0 ), + general_cfg.get( "hp_scan_strategy", "inplace" ) == "inplace" ? cds::gc::HP::scan_type::inplace : cds::gc::HP::scan_type::classic + ); cds::gc::DHP dhpGC( - general_cfg.get_size_t( "dhp_liberate_threshold", 1024 ), - general_cfg.get_size_t( "dhp_init_guard_count", 16 ), - general_cfg.get_size_t( "dhp_epoch_count", 16 ) + general_cfg.get_size_t( "dhp_init_guard_count", 16 ) ); #ifdef CDSUNIT_USE_URCU diff --git a/test/unit/intrusive-list/intrusive_iterable_dhp.cpp b/test/unit/intrusive-list/intrusive_iterable_dhp.cpp index 011bb32e..8f98641d 100644 --- a/test/unit/intrusive-list/intrusive_iterable_dhp.cpp +++ b/test/unit/intrusive-list/intrusive_iterable_dhp.cpp @@ -42,14 +42,14 @@ namespace { { typedef ci::IterableList< gc_type, item_type > list_type; - cds::gc::dhp::GarbageCollector::Construct( 16, list_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( list_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/intrusive-list/intrusive_lazy_dhp.cpp b/test/unit/intrusive-list/intrusive_lazy_dhp.cpp index 9f94b5ba..d9191647 100644 --- a/test/unit/intrusive-list/intrusive_lazy_dhp.cpp +++ b/test/unit/intrusive-list/intrusive_lazy_dhp.cpp @@ -53,14 +53,14 @@ namespace { }; typedef ci::LazyList< gc_type, base_item, traits > list_type; - cds::gc::dhp::GarbageCollector::Construct( 16, list_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( list_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/intrusive-list/intrusive_michael_dhp.cpp b/test/unit/intrusive-list/intrusive_michael_dhp.cpp index 7376205d..8f19c84c 100644 --- a/test/unit/intrusive-list/intrusive_michael_dhp.cpp +++ b/test/unit/intrusive-list/intrusive_michael_dhp.cpp @@ -50,14 +50,14 @@ namespace { }; typedef ci::MichaelList< gc_type, base_item, traits > list_type; - cds::gc::dhp::GarbageCollector::Construct( 16, list_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( list_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/intrusive-set/intrusive_feldman_hashset_dhp.cpp b/test/unit/intrusive-set/intrusive_feldman_hashset_dhp.cpp index 944fe188..13feb875 100644 --- a/test/unit/intrusive-set/intrusive_feldman_hashset_dhp.cpp +++ b/test/unit/intrusive-set/intrusive_feldman_hashset_dhp.cpp @@ -53,14 +53,14 @@ namespace { >::type > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/intrusive-set/intrusive_michael_iterable_dhp.cpp b/test/unit/intrusive-set/intrusive_michael_iterable_dhp.cpp index fc211b79..1fabda22 100644 --- a/test/unit/intrusive-set/intrusive_michael_iterable_dhp.cpp +++ b/test/unit/intrusive-set/intrusive_michael_iterable_dhp.cpp @@ -50,14 +50,14 @@ namespace { typedef ci::IterableList< gc_type, item_type, list_traits > list_type; typedef ci::MichaelHashSet< gc_type, list_type > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/intrusive-set/intrusive_michael_lazy_dhp.cpp b/test/unit/intrusive-set/intrusive_michael_lazy_dhp.cpp index 448a0578..2d315e07 100644 --- a/test/unit/intrusive-set/intrusive_michael_lazy_dhp.cpp +++ b/test/unit/intrusive-set/intrusive_michael_lazy_dhp.cpp @@ -59,14 +59,14 @@ namespace { typedef ci::LazyList< gc_type, base_item_type, list_traits > list_type; typedef ci::MichaelHashSet< gc_type, list_type > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/intrusive-set/intrusive_michael_michael_dhp.cpp b/test/unit/intrusive-set/intrusive_michael_michael_dhp.cpp index bfc5f59a..75901131 100644 --- a/test/unit/intrusive-set/intrusive_michael_michael_dhp.cpp +++ b/test/unit/intrusive-set/intrusive_michael_michael_dhp.cpp @@ -55,14 +55,14 @@ namespace { typedef ci::MichaelList< gc_type, base_item_type, list_traits > list_type; typedef ci::MichaelHashSet< gc_type, list_type > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/intrusive-set/intrusive_skiplist_dhp.cpp b/test/unit/intrusive-set/intrusive_skiplist_dhp.cpp index 166c6288..92d8320a 100644 --- a/test/unit/intrusive-set/intrusive_skiplist_dhp.cpp +++ b/test/unit/intrusive-set/intrusive_skiplist_dhp.cpp @@ -55,14 +55,14 @@ namespace { >::type > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/intrusive-set/intrusive_split_iterable_dhp.cpp b/test/unit/intrusive-set/intrusive_split_iterable_dhp.cpp index cc302b3f..32cdf780 100644 --- a/test/unit/intrusive-set/intrusive_split_iterable_dhp.cpp +++ b/test/unit/intrusive-set/intrusive_split_iterable_dhp.cpp @@ -52,14 +52,14 @@ namespace { typedef ci::IterableList< gc_type, item_type, list_traits > list_type; typedef ci::SplitListSet< gc_type, list_type > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/intrusive-set/intrusive_split_lazy_dhp.cpp b/test/unit/intrusive-set/intrusive_split_lazy_dhp.cpp index 8f6f79bf..0d4da1ec 100644 --- a/test/unit/intrusive-set/intrusive_split_lazy_dhp.cpp +++ b/test/unit/intrusive-set/intrusive_split_lazy_dhp.cpp @@ -60,14 +60,14 @@ namespace { typedef ci::LazyList< gc_type, base_item_type, list_traits > list_type; typedef ci::SplitListSet< gc_type, list_type > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/intrusive-set/intrusive_split_michael_dhp.cpp b/test/unit/intrusive-set/intrusive_split_michael_dhp.cpp index e4fbfcf2..dc378b6f 100644 --- a/test/unit/intrusive-set/intrusive_split_michael_dhp.cpp +++ b/test/unit/intrusive-set/intrusive_split_michael_dhp.cpp @@ -56,14 +56,14 @@ namespace { typedef ci::MichaelList< gc_type, base_item_type, list_traits > list_type; typedef ci::SplitListSet< gc_type, list_type > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/list/iterable_dhp.cpp b/test/unit/list/iterable_dhp.cpp index 58919472..38a064fa 100644 --- a/test/unit/list/iterable_dhp.cpp +++ b/test/unit/list/iterable_dhp.cpp @@ -42,14 +42,14 @@ namespace { { typedef cc::IterableList< gc_type, item > list_type; - cds::gc::dhp::GarbageCollector::Construct( 16, list_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( list_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/list/kv_iterable_dhp.cpp b/test/unit/list/kv_iterable_dhp.cpp index 10084259..8b725ed6 100644 --- a/test/unit/list/kv_iterable_dhp.cpp +++ b/test/unit/list/kv_iterable_dhp.cpp @@ -42,14 +42,14 @@ namespace { { typedef cc::IterableKVList< gc_type, key_type, value_type > list_type; - cds::gc::dhp::GarbageCollector::Construct( 16, list_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( list_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/list/kv_lazy_dhp.cpp b/test/unit/list/kv_lazy_dhp.cpp index 33751fbe..bd5c0431 100644 --- a/test/unit/list/kv_lazy_dhp.cpp +++ b/test/unit/list/kv_lazy_dhp.cpp @@ -42,14 +42,14 @@ namespace { { typedef cc::LazyKVList< gc_type, key_type, value_type > list_type; - cds::gc::dhp::GarbageCollector::Construct( 16, list_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::Construct( list_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::Destruct(); } }; diff --git a/test/unit/list/kv_michael_dhp.cpp b/test/unit/list/kv_michael_dhp.cpp index 064ed198..c0bc4181 100644 --- a/test/unit/list/kv_michael_dhp.cpp +++ b/test/unit/list/kv_michael_dhp.cpp @@ -42,14 +42,14 @@ namespace { { typedef cc::MichaelKVList< gc_type, key_type, value_type > list_type; - cds::gc::dhp::GarbageCollector::Construct( 16, list_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::Construct( list_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::Destruct(); } }; diff --git a/test/unit/list/lazy_dhp.cpp b/test/unit/list/lazy_dhp.cpp index 13c9fff9..9a2b2ef1 100644 --- a/test/unit/list/lazy_dhp.cpp +++ b/test/unit/list/lazy_dhp.cpp @@ -42,14 +42,14 @@ namespace { { typedef cc::LazyList< gc_type, item > list_type; - cds::gc::dhp::GarbageCollector::Construct( 16, list_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::Construct( list_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::Destruct(); } }; diff --git a/test/unit/list/michael_dhp.cpp b/test/unit/list/michael_dhp.cpp index c6e15225..3cac39b8 100644 --- a/test/unit/list/michael_dhp.cpp +++ b/test/unit/list/michael_dhp.cpp @@ -42,7 +42,7 @@ namespace { { typedef cc::MichaelList< gc_type, item > list_type; - cds::gc::dhp::GarbageCollector::Construct( 16, list_type::c_nHazardPtrCount ); + cds::gc::dhp::GarbageCollector::Construct( list_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } diff --git a/test/unit/map/feldman_hashmap_dhp.cpp b/test/unit/map/feldman_hashmap_dhp.cpp index ae5ee38b..a1411b47 100644 --- a/test/unit/map/feldman_hashmap_dhp.cpp +++ b/test/unit/map/feldman_hashmap_dhp.cpp @@ -45,15 +45,14 @@ namespace { { typedef cc::FeldmanHashMap< gc_type, key_type, value_type > map_type; - // +1 - for guarded_ptr - cds::gc::dhp::GarbageCollector::Construct( 16, map_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( map_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/map/michael_iterable_dhp.cpp b/test/unit/map/michael_iterable_dhp.cpp index 79e93c59..c341b053 100644 --- a/test/unit/map/michael_iterable_dhp.cpp +++ b/test/unit/map/michael_iterable_dhp.cpp @@ -48,14 +48,14 @@ namespace { typedef cc::IterableKVList< gc_type, key_type, value_type > list_type; typedef cc::MichaelHashMap< gc_type, list_type > map_type; - cds::gc::dhp::GarbageCollector::Construct( 16, map_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( map_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/map/michael_lazy_dhp.cpp b/test/unit/map/michael_lazy_dhp.cpp index 07f3dac4..33ac2647 100644 --- a/test/unit/map/michael_lazy_dhp.cpp +++ b/test/unit/map/michael_lazy_dhp.cpp @@ -48,14 +48,14 @@ namespace { typedef cc::LazyKVList< gc_type, key_type, value_type > list_type; typedef cc::MichaelHashMap< gc_type, list_type > map_type; - cds::gc::dhp::GarbageCollector::Construct( 16, map_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( map_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/map/michael_michael_dhp.cpp b/test/unit/map/michael_michael_dhp.cpp index ffe6ad79..175d665c 100644 --- a/test/unit/map/michael_michael_dhp.cpp +++ b/test/unit/map/michael_michael_dhp.cpp @@ -48,14 +48,14 @@ namespace { typedef cc::MichaelKVList< gc_type, key_type, value_type > list_type; typedef cc::MichaelHashMap< gc_type, list_type > map_type; - cds::gc::dhp::GarbageCollector::Construct( 16, map_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( map_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/map/skiplist_dhp.cpp b/test/unit/map/skiplist_dhp.cpp index 9633f497..410beed7 100644 --- a/test/unit/map/skiplist_dhp.cpp +++ b/test/unit/map/skiplist_dhp.cpp @@ -45,14 +45,14 @@ namespace { { typedef cc::SkipListMap< gc_type, key_type, value_type > map_type; - cds::gc::dhp::GarbageCollector::Construct( 16, map_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( map_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/map/split_iterable_dhp.cpp b/test/unit/map/split_iterable_dhp.cpp index 72eded29..27f6d5ae 100644 --- a/test/unit/map/split_iterable_dhp.cpp +++ b/test/unit/map/split_iterable_dhp.cpp @@ -55,14 +55,14 @@ namespace { }; typedef cc::SplitListMap< gc_type, key_type, value_type, map_traits > map_type; - cds::gc::dhp::GarbageCollector::Construct( 16, map_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( map_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/map/split_lazy_dhp.cpp b/test/unit/map/split_lazy_dhp.cpp index 4bfa6217..1979ebef 100644 --- a/test/unit/map/split_lazy_dhp.cpp +++ b/test/unit/map/split_lazy_dhp.cpp @@ -55,14 +55,14 @@ namespace { }; typedef cc::SplitListMap< gc_type, key_type, value_type, map_traits > map_type; - cds::gc::dhp::GarbageCollector::Construct( 16, map_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( map_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/map/split_michael_dhp.cpp b/test/unit/map/split_michael_dhp.cpp index e88affdb..4d7f6f29 100644 --- a/test/unit/map/split_michael_dhp.cpp +++ b/test/unit/map/split_michael_dhp.cpp @@ -55,15 +55,14 @@ namespace { }; typedef cc::SplitListMap< gc_type, key_type, value_type, map_traits > map_type; - // +1 - for guarded_ptr - cds::gc::dhp::GarbageCollector::Construct( 16, map_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( map_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct( true ); } }; diff --git a/test/unit/queue/basket_queue_dhp.cpp b/test/unit/queue/basket_queue_dhp.cpp index ac81bb3d..6c2992ba 100644 --- a/test/unit/queue/basket_queue_dhp.cpp +++ b/test/unit/queue/basket_queue_dhp.cpp @@ -45,7 +45,7 @@ namespace { { typedef cc::BasketQueue< gc_type, int > queue_type; - cds::gc::dhp::GarbageCollector::Construct( 16, queue_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( queue_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } diff --git a/test/unit/queue/intrusive_basket_queue_dhp.cpp b/test/unit/queue/intrusive_basket_queue_dhp.cpp index 22b70014..522ecc9e 100644 --- a/test/unit/queue/intrusive_basket_queue_dhp.cpp +++ b/test/unit/queue/intrusive_basket_queue_dhp.cpp @@ -55,7 +55,7 @@ namespace { >::type > queue_type; - cds::gc::dhp::GarbageCollector::Construct( 16, queue_type::c_nHazardPtrCount ); + cds::gc::dhp::GarbageCollector::Construct( queue_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } diff --git a/test/unit/queue/intrusive_moirqueue_dhp.cpp b/test/unit/queue/intrusive_moirqueue_dhp.cpp index 426e0cbc..4345479b 100644 --- a/test/unit/queue/intrusive_moirqueue_dhp.cpp +++ b/test/unit/queue/intrusive_moirqueue_dhp.cpp @@ -55,14 +55,14 @@ namespace { >::type > queue_type; - cds::gc::dhp::GarbageCollector::Construct( 16, queue_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( queue_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } template diff --git a/test/unit/queue/intrusive_msqueue_dhp.cpp b/test/unit/queue/intrusive_msqueue_dhp.cpp index 3f54d8ac..2108ca6b 100644 --- a/test/unit/queue/intrusive_msqueue_dhp.cpp +++ b/test/unit/queue/intrusive_msqueue_dhp.cpp @@ -55,14 +55,14 @@ namespace { >::type > queue_type; - cds::gc::dhp::GarbageCollector::Construct( 16, queue_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( queue_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } template diff --git a/test/unit/queue/intrusive_optqueue_dhp.cpp b/test/unit/queue/intrusive_optqueue_dhp.cpp index 26b561e6..9f8c662b 100644 --- a/test/unit/queue/intrusive_optqueue_dhp.cpp +++ b/test/unit/queue/intrusive_optqueue_dhp.cpp @@ -55,14 +55,14 @@ namespace { >::type > queue_type; - cds::gc::dhp::GarbageCollector::Construct( 16, queue_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( queue_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } template diff --git a/test/unit/queue/intrusive_segmented_queue_dhp.cpp b/test/unit/queue/intrusive_segmented_queue_dhp.cpp index 6648debf..24ac1eaa 100644 --- a/test/unit/queue/intrusive_segmented_queue_dhp.cpp +++ b/test/unit/queue/intrusive_segmented_queue_dhp.cpp @@ -49,14 +49,14 @@ namespace { { typedef ci::SegmentedQueue< gc_type, item > queue_type; - cds::gc::dhp::GarbageCollector::Construct( 16, queue_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( queue_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::hp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } template diff --git a/test/unit/queue/moirqueue_dhp.cpp b/test/unit/queue/moirqueue_dhp.cpp index 17cefbae..15fca504 100644 --- a/test/unit/queue/moirqueue_dhp.cpp +++ b/test/unit/queue/moirqueue_dhp.cpp @@ -45,14 +45,14 @@ namespace { { typedef cc::MoirQueue< gc_type, int > queue_type; - cds::gc::dhp::GarbageCollector::Construct( 16, queue_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( queue_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/queue/msqueue_dhp.cpp b/test/unit/queue/msqueue_dhp.cpp index 1fe87c20..2ae32820 100644 --- a/test/unit/queue/msqueue_dhp.cpp +++ b/test/unit/queue/msqueue_dhp.cpp @@ -45,14 +45,14 @@ namespace { { typedef cc::MSQueue< gc_type, int > queue_type; - cds::gc::dhp::GarbageCollector::Construct( 16, queue_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( queue_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/queue/optimistic_queue_dhp.cpp b/test/unit/queue/optimistic_queue_dhp.cpp index dfb9ad7b..9a1c7c56 100644 --- a/test/unit/queue/optimistic_queue_dhp.cpp +++ b/test/unit/queue/optimistic_queue_dhp.cpp @@ -45,14 +45,14 @@ namespace { { typedef cc::OptimisticQueue< gc_type, int > queue_type; - cds::gc::dhp::GarbageCollector::Construct( 16, queue_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( queue_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/queue/segmented_queue_dhp.cpp b/test/unit/queue/segmented_queue_dhp.cpp index 5385e833..8280f58d 100644 --- a/test/unit/queue/segmented_queue_dhp.cpp +++ b/test/unit/queue/segmented_queue_dhp.cpp @@ -46,14 +46,14 @@ namespace { { typedef cc::SegmentedQueue< gc_type, int > queue_type; - cds::gc::dhp::GarbageCollector::Construct( 16, queue_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( queue_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/set/feldman_hashset_dhp.cpp b/test/unit/set/feldman_hashset_dhp.cpp index 0cbf463b..ed26b087 100644 --- a/test/unit/set/feldman_hashset_dhp.cpp +++ b/test/unit/set/feldman_hashset_dhp.cpp @@ -49,14 +49,14 @@ namespace { }; typedef cc::FeldmanHashSet< gc_type, int_item, set_traits > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/set/michael_iterable_dhp.cpp b/test/unit/set/michael_iterable_dhp.cpp index 8093524c..26f8d44a 100644 --- a/test/unit/set/michael_iterable_dhp.cpp +++ b/test/unit/set/michael_iterable_dhp.cpp @@ -47,14 +47,14 @@ namespace { typedef cc::IterableList< gc_type, int_item > list_type; typedef cc::MichaelHashSet< gc_type, list_type > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/set/michael_lazy_dhp.cpp b/test/unit/set/michael_lazy_dhp.cpp index e7744c1e..c4123462 100644 --- a/test/unit/set/michael_lazy_dhp.cpp +++ b/test/unit/set/michael_lazy_dhp.cpp @@ -47,14 +47,14 @@ namespace { typedef cc::LazyList< gc_type, int_item > list_type; typedef cc::MichaelHashSet< gc_type, list_type > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/set/michael_michael_dhp.cpp b/test/unit/set/michael_michael_dhp.cpp index c678772f..327082a2 100644 --- a/test/unit/set/michael_michael_dhp.cpp +++ b/test/unit/set/michael_michael_dhp.cpp @@ -47,14 +47,14 @@ namespace { typedef cc::MichaelList< gc_type, int_item > list_type; typedef cc::MichaelHashSet< gc_type, list_type > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/set/skiplist_dhp.cpp b/test/unit/set/skiplist_dhp.cpp index 0c17e55b..cd34b788 100644 --- a/test/unit/set/skiplist_dhp.cpp +++ b/test/unit/set/skiplist_dhp.cpp @@ -45,14 +45,14 @@ namespace { { typedef cc::SkipListSet< gc_type, int_item > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/set/split_iterable_dhp.cpp b/test/unit/set/split_iterable_dhp.cpp index 760a6ffe..d00989be 100644 --- a/test/unit/set/split_iterable_dhp.cpp +++ b/test/unit/set/split_iterable_dhp.cpp @@ -55,14 +55,14 @@ namespace { }; typedef cc::SplitListSet< gc_type, int_item, set_traits > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/set/split_lazy_dhp.cpp b/test/unit/set/split_lazy_dhp.cpp index e404cb56..98b825ca 100644 --- a/test/unit/set/split_lazy_dhp.cpp +++ b/test/unit/set/split_lazy_dhp.cpp @@ -55,14 +55,14 @@ namespace { }; typedef cc::SplitListSet< gc_type, int_item, set_traits > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/set/split_michael_dhp.cpp b/test/unit/set/split_michael_dhp.cpp index 4b5154ce..ebf3df72 100644 --- a/test/unit/set/split_michael_dhp.cpp +++ b/test/unit/set/split_michael_dhp.cpp @@ -55,14 +55,14 @@ namespace { }; typedef cc::SplitListSet< gc_type, int_item, set_traits > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/stack/intrusive_treiber_stack_dhp.cpp b/test/unit/stack/intrusive_treiber_stack_dhp.cpp index 6d694683..8c59a56d 100644 --- a/test/unit/stack/intrusive_treiber_stack_dhp.cpp +++ b/test/unit/stack/intrusive_treiber_stack_dhp.cpp @@ -56,14 +56,14 @@ namespace { >::type > stack_type; - cds::gc::dhp::GarbageCollector::Construct( 16, stack_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( stack_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } template diff --git a/test/unit/stack/treiber_stack_dhp.cpp b/test/unit/stack/treiber_stack_dhp.cpp index 0ed854dc..0ef7731f 100644 --- a/test/unit/stack/treiber_stack_dhp.cpp +++ b/test/unit/stack/treiber_stack_dhp.cpp @@ -47,14 +47,14 @@ namespace { { typedef cc::TreiberStack< gc_type, int > stack_type; - cds::gc::dhp::GarbageCollector::Construct( 16, stack_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( stack_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } template diff --git a/test/unit/tree/ellen_bintree_map_dhp.cpp b/test/unit/tree/ellen_bintree_map_dhp.cpp index 0ed544d7..0d1a7155 100644 --- a/test/unit/tree/ellen_bintree_map_dhp.cpp +++ b/test/unit/tree/ellen_bintree_map_dhp.cpp @@ -46,14 +46,14 @@ namespace { { typedef cc::EllenBinTreeMap< gc_type, key_type, value_type > map_type; - cds::gc::dhp::GarbageCollector::Construct( 16, map_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( map_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/tree/ellen_bintree_set_dhp.cpp b/test/unit/tree/ellen_bintree_set_dhp.cpp index 248863fc..661e6183 100644 --- a/test/unit/tree/ellen_bintree_set_dhp.cpp +++ b/test/unit/tree/ellen_bintree_set_dhp.cpp @@ -52,14 +52,14 @@ namespace { { typedef cc::EllenBinTreeSet< gc_type, key_type, int_item > set_type; - cds::gc::dhp::GarbageCollector::Construct( 16, set_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( set_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::hp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } }; diff --git a/test/unit/tree/intrusive_ellenbintree_dhp.cpp b/test/unit/tree/intrusive_ellenbintree_dhp.cpp index ae577c0b..808c4e52 100644 --- a/test/unit/tree/intrusive_ellenbintree_dhp.cpp +++ b/test/unit/tree/intrusive_ellenbintree_dhp.cpp @@ -52,14 +52,14 @@ namespace { { typedef ci::EllenBinTree< gc_type, key_type, base_item_type > tree_type; - cds::gc::dhp::GarbageCollector::Construct( 16, tree_type::c_nHazardPtrCount ); + cds::gc::dhp::smr::construct( tree_type::c_nHazardPtrCount ); cds::threading::Manager::attachThread(); } void TearDown() { cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); + cds::gc::dhp::smr::destruct(); } struct generic_traits: public ci::ellen_bintree::traits -- 2.34.1
Max number of guarded (hazard) pointers per threadlimited (specifies in GC object ctor)limited (specifies in SMR object ctor) unlimited (dynamically allocated when needed)