diff --git a/include/boost/regex/v4/mem_block_cache.hpp b/include/boost/regex/v4/mem_block_cache.hpp index dc5491506..50af421ea 100644 --- a/include/boost/regex/v4/mem_block_cache.hpp +++ b/include/boost/regex/v4/mem_block_cache.hpp @@ -27,9 +27,54 @@ # include BOOST_ABI_PREFIX #endif +#ifndef BOOST_NO_CXX11_HDR_ATOMIC + #include + #if ATOMIC_POINTER_LOCK_FREE == 2 + #define BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE + #define BOOST_REGEX_ATOMIC_POINTER std::atomic + #endif +#endif + namespace boost{ namespace BOOST_REGEX_DETAIL_NS{ +#ifdef BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE /* lock free implementation */ +struct mem_block_cache +{ + std::atomic cache[BOOST_REGEX_MAX_CACHE_BLOCKS]; + + ~mem_block_cache() + { + for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) { + if (cache[i].load()) ::operator delete(cache[i].load()); + } + } + void* get() + { + for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) { + void* p = cache[i].load(); + if (p != NULL) { + if (cache[i].compare_exchange_strong(p, NULL)) return p; + } + } + return ::operator new(BOOST_REGEX_BLOCKSIZE); + } + void put(void* ptr) + { + for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) { + void* p = cache[i].load(); + if (p == NULL) { + if (cache[i].compare_exchange_strong(p, ptr)) return; + } + } + ::operator delete(ptr); + } +}; + + +#else /* lock-based implementation */ + + struct mem_block_node { mem_block_node* next; @@ -85,6 +130,7 @@ struct mem_block_cache } } }; +#endif extern mem_block_cache block_cache; diff --git a/src/regex.cpp b/src/regex.cpp index 03057aac9..e9e976274 100644 --- a/src/regex.cpp +++ b/src/regex.cpp @@ -191,7 +191,9 @@ BOOST_REGEX_DECL void BOOST_REGEX_CALL put_mem_block(void* p) #else -#ifdef BOOST_HAS_THREADS +#if defined(BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE) +mem_block_cache block_cache = { { {nullptr} } } ; +#elif defined(BOOST_HAS_THREADS) mem_block_cache block_cache = { 0, 0, BOOST_STATIC_MUTEX_INIT, }; #else mem_block_cache block_cache = { 0, 0, };