HP and DHP SMR totally refactored
[libcds.git] / cds / gc / details / hp_alloc.h
diff --git a/cds/gc/details/hp_alloc.h b/cds/gc/details/hp_alloc.h
deleted file mode 100644 (file)
index 978a342..0000000
+++ /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 <cds/algo/atomic.h>
-#include <cds/details/allocator.h>
-#include <cds/gc/details/hp_type.h>
-#include <string.h> // 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 <class Allocator> friend class hp_allocator;
-
-        public:
-            typedef hazard_pointer hazard_ptr;///< Hazard pointer type
-
-        private:
-            typedef atomics::atomic<hazard_ptr> 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 <typename T>
-            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 <typename T>
-            void set( T * p, atomics::memory_order order = atomics::memory_order_release ) CDS_NOEXCEPT
-            {
-                m_hp.store( reinterpret_cast<hazard_ptr>(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 <size_t Count>
-        class hp_array
-        {
-            template <class Allocator> 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 Allocator = CDS_DEFAULT_ALLOCATOR >
-        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 Count>
-            size_t alloc( hp_array<Count>& 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 <size_t Count>
-            void free( hp_array<Count> 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