diff --git a/include/boost/unordered/detail/foa/concurrent_table.hpp b/include/boost/unordered/detail/foa/concurrent_table.hpp index f3f136e2..e61b8fc9 100644 --- a/include/boost/unordered/detail/foa/concurrent_table.hpp +++ b/include/boost/unordered/detail/foa/concurrent_table.hpp @@ -156,13 +156,13 @@ struct atomic_integral std::atomic n; }; +/* Group-level concurrency protection. It provides a rw mutex plus an + * atomic insertion counter for optimistic insertion (see + * unprotected_norehash_emplace_or_visit). + */ + struct group_access { - struct dummy_group_access_type - { - boost::uint32_t storage[2]={0,0}; - }; - using mutex_type=rw_spinlock; using shared_lock_guard=shared_lock; using exclusive_lock_guard=lock_guard; @@ -174,31 +174,25 @@ struct group_access private: mutex_type m; - insert_counter_type cnt; -}; - -template -struct concurrent_group:Group,group_access -{ - struct dummy_group_type - { - typename Group::dummy_group_type group_storage; - group_access::dummy_group_access_type access_storage; - }; + insert_counter_type cnt=0; }; template group_access* dummy_group_accesses() { - /* TODO: describe + /* Default group_access array to provide to empty containers without + * incurring dynamic allocation. Mutexes won't actually ever be used, + * (no successful reduced hash match) and insertion counters won't ever + * be incremented (insertions won't succeed as capacity()==0). */ - static group_access::dummy_group_access_type - storage[Size]={typename group_access::dummy_group_access_type(),}; + static group_access accesses[Size]; - return reinterpret_cast(storage); + return accesses; } +/* subclasses table_arrays to add an additional group_access array */ + template struct concurrent_table_arrays:table_arrays { @@ -225,7 +219,7 @@ struct concurrent_table_arrays:table_arrays access_traits::allocate(aal,arrays.groups_size_mask+1)); for(std::size_t i=0;i template using concurrent_table_core_impl=table_core< - TypePolicy, - -#if defined(BOOST_UNORDERED_EMBEDDED_GROUP_ACCESS) - concurrent_group>, - table_arrays, -#else - group15, - concurrent_table_arrays, -#endif - + TypePolicy,group15,concurrent_table_arrays, std::atomic,Hash,Pred,Allocator>; #include @@ -701,16 +686,9 @@ private: using shared_lock_guard=shared_lock; using exclusive_lock_guard=lock_guard; using exclusive_bilock_guard=scoped_bilock; - -#if defined(BOOST_UNORDERED_EMBEDDED_GROUP_ACCESS) - using group_shared_lock_guard=typename group_type::shared_lock_guard; - using group_exclusive_lock_guard=typename group_type::exclusive_lock_guard; - using group_insert_counter_type=typename group_type::insert_counter_type; -#else using group_shared_lock_guard=typename group_access::shared_lock_guard; using group_exclusive_lock_guard=typename group_access::exclusive_lock_guard; using group_insert_counter_type=typename group_access::insert_counter_type; -#endif concurrent_table(const concurrent_table& x,exclusive_lock_guard): super{x}{} @@ -741,38 +719,6 @@ private: return {x.mutexes,y.mutexes}; } -#if defined(BOOST_UNORDERED_EMBEDDED_GROUP_ACCESS) - inline group_shared_lock_guard shared_access(std::size_t pos)const - { - return this->arrays.groups[pos].shared_access(); - } - - inline group_exclusive_lock_guard exclusive_access(std::size_t pos)const - { - return this->arrays.groups[pos].exclusive_access(); - } - - inline group_insert_counter_type& insert_counter(std::size_t pos)const - { - return this->arrays.groups[pos].insert_counter(); - } -#else - inline group_shared_lock_guard shared_access(std::size_t pos)const - { - return this->arrays.group_accesses[pos].shared_access(); - } - - inline group_exclusive_lock_guard exclusive_access(std::size_t pos)const - { - return this->arrays.group_accesses[pos].exclusive_access(); - } - - inline group_insert_counter_type& insert_counter(std::size_t pos)const - { - return this->arrays.group_accesses[pos].insert_counter(); - } -#endif - /* Tag-dispatched shared/exclusive group access */ using group_shared=std::false_type; @@ -780,13 +726,18 @@ private: inline group_shared_lock_guard access(group_shared,std::size_t pos)const { - return shared_access(pos); + return this->arrays.group_accesses[pos].shared_access(); } inline group_exclusive_lock_guard access( group_exclusive,std::size_t pos)const { - return exclusive_access(pos); + return this->arrays.group_accesses[pos].exclusive_access(); + } + + inline group_insert_counter_type& insert_counter(std::size_t pos)const + { + return this->arrays.group_accesses[pos].insert_counter(); } /* Const casts value_type& according to the level of group access for diff --git a/include/boost/unordered/detail/foa/core.hpp b/include/boost/unordered/detail/foa/core.hpp index 79d8313d..f672d0c3 100644 --- a/include/boost/unordered/detail/foa/core.hpp +++ b/include/boost/unordered/detail/foa/core.hpp @@ -937,15 +937,10 @@ struct table_arrays reinterpret_cast(p))%sizeof(group_type); arrays.groups=reinterpret_cast(p); - for (std::size_t i=0;i