File indexing completed on 2025-01-18 09:51:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef BOOST_REGEX_V4_MEM_BLOCK_CACHE_HPP
0019 #define BOOST_REGEX_V4_MEM_BLOCK_CACHE_HPP
0020
0021 #include <new>
0022 #ifdef BOOST_HAS_THREADS
0023 #include <boost/regex/pending/static_mutex.hpp>
0024 #endif
0025
0026 #ifdef BOOST_HAS_ABI_HEADERS
0027 # include BOOST_ABI_PREFIX
0028 #endif
0029
0030 #ifndef BOOST_NO_CXX11_HDR_ATOMIC
0031 #include <atomic>
0032 #if ATOMIC_POINTER_LOCK_FREE == 2
0033 #define BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE
0034 #define BOOST_REGEX_ATOMIC_POINTER std::atomic
0035 #endif
0036 #endif
0037
0038 namespace boost{
0039 namespace BOOST_REGEX_DETAIL_NS{
0040
0041 #ifdef BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE
0042 struct mem_block_cache
0043 {
0044 std::atomic<void*> cache[BOOST_REGEX_MAX_CACHE_BLOCKS];
0045
0046 ~mem_block_cache()
0047 {
0048 for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {
0049 if (cache[i].load()) ::operator delete(cache[i].load());
0050 }
0051 }
0052 void* get()
0053 {
0054 for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {
0055 void* p = cache[i].load();
0056 if (p != NULL) {
0057 if (cache[i].compare_exchange_strong(p, NULL)) return p;
0058 }
0059 }
0060 return ::operator new(BOOST_REGEX_BLOCKSIZE);
0061 }
0062 void put(void* ptr)
0063 {
0064 for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {
0065 void* p = cache[i].load();
0066 if (p == NULL) {
0067 if (cache[i].compare_exchange_strong(p, ptr)) return;
0068 }
0069 }
0070 ::operator delete(ptr);
0071 }
0072
0073 static mem_block_cache& instance()
0074 {
0075 static mem_block_cache block_cache = { { {nullptr} } };
0076 return block_cache;
0077 }
0078 };
0079
0080
0081 #else
0082
0083
0084 struct mem_block_node
0085 {
0086 mem_block_node* next;
0087 };
0088
0089 struct mem_block_cache
0090 {
0091
0092 mem_block_node* next;
0093 unsigned cached_blocks;
0094 #ifdef BOOST_HAS_THREADS
0095 boost::static_mutex mut;
0096 #endif
0097
0098 ~mem_block_cache()
0099 {
0100 while(next)
0101 {
0102 mem_block_node* old = next;
0103 next = next->next;
0104 ::operator delete(old);
0105 }
0106 }
0107 void* get()
0108 {
0109 #ifdef BOOST_HAS_THREADS
0110 boost::static_mutex::scoped_lock g(mut);
0111 #endif
0112 if(next)
0113 {
0114 mem_block_node* result = next;
0115 next = next->next;
0116 --cached_blocks;
0117 return result;
0118 }
0119 return ::operator new(BOOST_REGEX_BLOCKSIZE);
0120 }
0121 void put(void* p)
0122 {
0123 #ifdef BOOST_HAS_THREADS
0124 boost::static_mutex::scoped_lock g(mut);
0125 #endif
0126 if(cached_blocks >= BOOST_REGEX_MAX_CACHE_BLOCKS)
0127 {
0128 ::operator delete(p);
0129 }
0130 else
0131 {
0132 mem_block_node* old = static_cast<mem_block_node*>(p);
0133 old->next = next;
0134 next = old;
0135 ++cached_blocks;
0136 }
0137 }
0138 static mem_block_cache& instance()
0139 {
0140 #ifdef BOOST_HAS_THREADS
0141 static mem_block_cache block_cache = { 0, 0, BOOST_STATIC_MUTEX_INIT, };
0142 #else
0143 static mem_block_cache block_cache = { 0, 0, };
0144 #endif
0145 return block_cache;
0146 }
0147 };
0148 #endif
0149
0150 #if BOOST_REGEX_MAX_CACHE_BLOCKS == 0
0151
0152 inline void* BOOST_REGEX_CALL get_mem_block()
0153 {
0154 return ::operator new(BOOST_REGEX_BLOCKSIZE);
0155 }
0156
0157 inline void BOOST_REGEX_CALL put_mem_block(void* p)
0158 {
0159 ::operator delete(p);
0160 }
0161
0162 #else
0163
0164 inline void* BOOST_REGEX_CALL get_mem_block()
0165 {
0166 return mem_block_cache::instance().get();
0167 }
0168
0169 inline void BOOST_REGEX_CALL put_mem_block(void* p)
0170 {
0171 mem_block_cache::instance().put(p);
0172 }
0173
0174 #endif
0175 }
0176 }
0177
0178 #ifdef BOOST_HAS_ABI_HEADERS
0179 # include BOOST_ABI_SUFFIX
0180 #endif
0181
0182 #endif
0183