## include/boost/regex/v5/mem_block_cache.hpp

100.0% Lines (29/29) 100.0% List of functions (8/8)
mem_block_cache.hpp
f(x) Functions (8)
Function Calls Lines Blocks
boost::re_detail_600::mem_block_cache::~mem_block_cache() :47 40x 100.0% 100.0% boost::re_detail_600::mem_block_cache::get() :53 1052311x 100.0% 100.0% boost::re_detail_600::mem_block_cache::put(void*) :63 1052311x 100.0% 100.0% boost::re_detail_600::mem_block_cache::instance() :74 2104622x 60.0% 100.0% boost::re_detail_600::get_mem_block() :150 716020x 100.0% 100.0% boost::re_detail_600::put_mem_block(void*) :155 716020x 100.0% 100.0% boost::re_detail_600::get_mem_block() :162 1052311x 100.0% 100.0% boost::re_detail_600::put_mem_block(void*) :167 1052311x 100.0% 100.0%

Line | TLA | Hits | Source Code
--- | --- | --- | ---
1 |  |  | /*
2 |  |  | * Copyright (c) 2002
3 |  |  | * John Maddock
4 |  |  | *
5 |  |  | * Use, modification and distribution are subject to the
6 |  |  | * Boost Software License, Version 1.0. (See accompanying file
7 |  |  | * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 |  |  | *
9 |  |  | */
10 |  |  |
11 |  |  | /*
12 |  |  | * LOCATION: see http://www.boost.org for most recent version.
13 |  |  | * FILE mem_block_cache.hpp
14 |  |  | * VERSION see <boost/version.hpp>
15 |  |  | * DESCRIPTION: memory block cache used by the non-recursive matcher.
16 |  |  | */
17 |  |  |
18 |  |  | #ifndef BOOST_REGEX_V5_MEM_BLOCK_CACHE_HPP
19 |  |  | #define BOOST_REGEX_V5_MEM_BLOCK_CACHE_HPP
20 |  |  |
21 |  |  | #include <boost/regex/config.hpp>
22 |  |  | #ifndef BOOST_REGEX_AS_MODULE
23 |  |  | #include <new>
24 |  |  | #ifdef BOOST_HAS_THREADS
25 |  |  | #include <mutex>
26 |  |  | #endif
27 |  |  |
28 |  |  | #ifndef BOOST_NO_CXX11_HDR_ATOMIC
29 |  |  | #include <atomic>
30 |  |  | #if ATOMIC_POINTER_LOCK_FREE == 2
31 |  |  | #define BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE
32 |  |  | #define BOOST_REGEX_ATOMIC_POINTER std::atomic
33 |  |  | #endif
34 |  |  | #endif
35 |  |  | #endif
36 |  |  |
37 |  |  |
38 |  |  | namespace boost{
39 |  |  | namespace BOOST_REGEX_DETAIL_NS{
40 |  |  |
41 |  |  | #if BOOST_REGEX_MAX_CACHE_BLOCKS != 0
42 |  |  | #ifdef BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE /* lock free implementation */
43 |  |  | struct mem_block_cache
44 |  |  | {
45 |  |  | std::atomic<void*> cache[BOOST_REGEX_MAX_CACHE_BLOCKS];
46 |  |  |
47 |  | 40x | ~mem_block_cache()
48 |  |  | {
49 |  | 680x | for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {
50 |  | 640x | if (cache[i].load()) ::operator delete(cache[i].load());
51 |  |  | }
52 |  | 40x | }
53 |  | 1052311x | void* get()
54 |  |  | {
55 |  | 1264867x | for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {
56 |  | 1255896x | void* p = cache[i].load();
57 |  | 1255896x | if (p != NULL) {
58 |  | 1045668x | if (cache[i].compare_exchange_strong(p, NULL)) return p;
59 |  |  | }
60 |  |  | }
61 |  | 8971x | return ::operator new(BOOST_REGEX_BLOCKSIZE);
62 |  |  | }
63 |  | 1052311x | void put(void* ptr)
64 |  |  | {
65 |  | 1263776x | for (size_t i = 0;i < BOOST_REGEX_MAX_CACHE_BLOCKS; ++i) {
66 |  | 1254890x | void* p = cache[i].load();
67 |  | 1254890x | if (p == NULL) {
68 |  | 1045779x | if (cache[i].compare_exchange_strong(p, ptr)) return;
69 |  |  | }
70 |  |  | }
71 |  | 8886x | ::operator delete(ptr);
72 |  |  | }
73 |  |  |
74 |  | 2104622x | static mem_block_cache& instance()
75 |  |  | {
76 |  | 2104622x | static mem_block_cache block_cache = { { {nullptr} } };
77 |  | 2104622x | return block_cache;
78 |  |  | }
79 |  |  | };
80 |  |  |
81 |  |  |
82 |  |  | #else /* lock-based implementation */
83 |  |  |
84 |  |  |
85 |  |  | struct mem_block_node
86 |  |  | {
87 |  |  | mem_block_node* next;
88 |  |  | };
89 |  |  |
90 |  |  | struct mem_block_cache
91 |  |  | {
92 |  |  | // this member has to be statically initialsed:
93 |  |  | mem_block_node* next { nullptr };
94 |  |  | unsigned cached_blocks { 0 };
95 |  |  | #ifdef BOOST_HAS_THREADS
96 |  |  | std::mutex mut;
97 |  |  | #endif
98 |  |  |
99 |  |  | ~mem_block_cache()
100 |  |  | {
101 |  |  | while(next)
102 |  |  | {
103 |  |  | mem_block_node* old = next;
104 |  |  | next = next->next;
105 |  |  | ::operator delete(old);
106 |  |  | }
107 |  |  | }
108 |  |  | void* get()
109 |  |  | {
110 |  |  | #ifdef BOOST_HAS_THREADS
111 |  |  | std::lock_guard<std::mutex> g(mut);
112 |  |  | #endif
113 |  |  | if(next)
114 |  |  | {
115 |  |  | mem_block_node* result = next;
116 |  |  | next = next->next;
117 |  |  | --cached_blocks;
118 |  |  | return result;
119 |  |  | }
120 |  |  | return ::operator new(BOOST_REGEX_BLOCKSIZE);
121 |  |  | }
122 |  |  | void put(void* p)
123 |  |  | {
124 |  |  | #ifdef BOOST_HAS_THREADS
125 |  |  | std::lock_guard<std::mutex> g(mut);
126 |  |  | #endif
127 |  |  | if(cached_blocks >= BOOST_REGEX_MAX_CACHE_BLOCKS)
128 |  |  | {
129 |  |  | ::operator delete(p);
130 |  |  | }
131 |  |  | else
132 |  |  | {
133 |  |  | mem_block_node* old = static_cast<mem_block_node*>(p);
134 |  |  | old->next = next;
135 |  |  | next = old;
136 |  |  | ++cached_blocks;
137 |  |  | }
138 |  |  | }
139 |  |  | static mem_block_cache& instance()
140 |  |  | {
141 |  |  | static mem_block_cache block_cache;
142 |  |  | return block_cache;
143 |  |  | }
144 |  |  | };
145 |  |  | #endif
146 |  |  | #endif
147 |  |  |
148 |  |  | #if BOOST_REGEX_MAX_CACHE_BLOCKS == 0
149 |  |  |
150 |  | 716020x | inline void* get_mem_block()
151 |  |  | {
152 |  | 716020x | return ::operator new(BOOST_REGEX_BLOCKSIZE);
153 |  |  | }
154 |  |  |
155 |  | 716020x | inline void put_mem_block(void* p)
156 |  |  | {
157 |  | 716020x | ::operator delete(p);
158 |  | 716020x | }
159 |  |  |
160 |  |  | #else
161 |  |  |
162 |  | 1052311x | inline void* get_mem_block()
163 |  |  | {
164 |  | 1052311x | return mem_block_cache::instance().get();
165 |  |  | }
166 |  |  |
167 |  | 1052311x | inline void put_mem_block(void* p)
168 |  |  | {
169 |  | 1052311x | mem_block_cache::instance().put(p);
170 |  | 1052311x | }
171 |  |  |
172 |  |  | #endif
173 |  |  | }
174 |  |  | } // namespace boost
175 |  |  |
176 |  |  | #endif
177 |  |  |
178 |  |  |