22
33#include < memory>
44#include < vector>
5- #include < cassert>
65#include < unordered_map>
76#include < stdexcept>
87
98namespace dsplib {
109
11- // ----------------------------------------------------------------------------------------
12- constexpr int MAX_POOLED_SIZE = (1L << 15 );
13- constexpr int SMALL_BLOCK_SIZE = 64 ;
14- constexpr int BLOCK_SIZE = 512 ;
15- constexpr int STORAGE_COUNT = MAX_POOLED_SIZE / BLOCK_SIZE + 1 ;
16- constexpr size_t MEMORY_ALLOCATION_LIMIT = 1024 * 1024 ; // 1 MB (TODO: set from options)
17- constexpr int NOT_POOLED_KEY = -1 ;
18-
1910// ----------------------------------------------------------------------------------------
2011class storage_t
2112{
@@ -39,10 +30,31 @@ class storage_t
3930};
4031
4132// ----------------------------------------------------------------------------------------
42- static thread_local std::vector<storage_t > _storage (STORAGE_COUNT);
43- static thread_local size_t _bytes_allocated{0 };
44- static thread_local std::unordered_map<void *, int > _alocate_map;
33+ // TODO: Move constants MAX_POOLED_SIZE, SMALL_BLOCK_SIZE, BLOCK_SIZE, MEMORY_ALLOCATION_LIMIT to config
34+ constexpr int MAX_POOLED_SIZE = (1L << 15 );
35+ constexpr int SMALL_BLOCK_SIZE = 64 ;
36+ constexpr int BLOCK_SIZE = 512 ;
37+ constexpr int STORAGE_COUNT = MAX_POOLED_SIZE / BLOCK_SIZE + 1 ;
38+ constexpr size_t MEMORY_ALLOCATION_LIMIT = 1024 * 1024 ; // 1 MB (TODO: set from options)
39+ constexpr int NOT_POOLED_KEY = -1 ;
40+
41+ // ----------------------------------------------------------------------------------------
42+ static std::vector<storage_t >& get_storage () {
43+ static std::vector<storage_t > _storage (STORAGE_COUNT);
44+ return _storage;
45+ }
4546
47+ static std::unordered_map<void *, int >& get_allocmap () {
48+ static std::unordered_map<void *, int > _alocate_map{};
49+ return _alocate_map;
50+ }
51+
52+ static size_t & allocated () {
53+ static size_t _bytes_allocated{0 };
54+ return _bytes_allocated;
55+ }
56+
57+ // ----------------------------------------------------------------------------------------
4658static int key_by_size (int size) {
4759 assert (size <= MAX_POOLED_SIZE);
4860 if (size <= SMALL_BLOCK_SIZE) {
@@ -67,7 +79,7 @@ void pool_init(std::vector<int> map) {
6779 bytes_needed += pool_size;
6880 }
6981
70- if ((bytes_needed + _bytes_allocated ) > MEMORY_ALLOCATION_LIMIT) {
82+ if ((bytes_needed + allocated () ) > MEMORY_ALLOCATION_LIMIT) {
7183 throw std::runtime_error (" Limit is exceeded. Memory has not been allocated." );
7284 }
7385
@@ -80,66 +92,77 @@ void pool_init(std::vector<int> map) {
8092
8193// ----------------------------------------------------------------------------------------
8294void pool_reset () {
83- for (int key = 0 ; key < _storage.size (); ++key) {
84- auto & pool = _storage[key];
95+ auto & storage = get_storage ();
96+ for (int key = 0 ; key < storage.size (); ++key) {
97+ auto & pool = storage[key];
8598 while (pool.size () > 0 ) {
8699 auto ptr = pool.pop ();
87100 free (ptr);
88- _bytes_allocated -= size_by_key (key);
101+ allocated () -= size_by_key (key);
89102 }
90103 }
91104}
92105
93106// ----------------------------------------------------------------------------------------
94107void * pool_alloc (size_t size) {
108+ auto & storage = get_storage ();
109+ auto & allocmap = get_allocmap ();
110+
95111 if (size > MAX_POOLED_SIZE) {
96112 auto ptr = malloc (size);
97- _alocate_map [ptr] = NOT_POOLED_KEY;
113+ allocmap [ptr] = NOT_POOLED_KEY;
98114 return ptr;
99115 }
100116
101117 const int key = key_by_size (size);
102- auto & pool = _storage [key];
118+ auto & pool = storage [key];
103119 const int cap = size_by_key (key);
104120
105121 // TODO: get first free object from pool (not equal size)
106- if ((pool.size () == 0 ) && (_bytes_allocated > MEMORY_ALLOCATION_LIMIT)) {
122+ if ((pool.size () == 0 ) && (allocated () > MEMORY_ALLOCATION_LIMIT)) {
107123 auto ptr = malloc (size);
108- _alocate_map [ptr] = NOT_POOLED_KEY;
124+ allocmap [ptr] = NOT_POOLED_KEY;
109125 return ptr;
110126 }
111127
112128 // add block to pool
113129 if (pool.size () == 0 ) {
114130 auto ptr = malloc (cap);
115131 pool.push (ptr);
116- _bytes_allocated += cap;
132+ allocated () += cap;
117133 }
118134
119135 auto ptr = pool.pop ();
120- _alocate_map [ptr] = key;
136+ allocmap [ptr] = key;
121137 return ptr;
122138}
123139
124140// ----------------------------------------------------------------------------------------
125141void pool_free (void * ptr) {
126- assert (_alocate_map.count (ptr) == 1 );
127- auto key = _alocate_map.at (ptr);
128- _alocate_map.erase (ptr);
142+ auto & storage = get_storage ();
143+ auto & allocmap = get_allocmap ();
144+
145+ assert (allocmap.count (ptr) == 1 );
146+
147+ auto key = allocmap.at (ptr);
148+ allocmap.erase (ptr);
129149 if (key == NOT_POOLED_KEY) {
130150 free (ptr);
131151 } else {
132- auto & pool = _storage [key];
152+ auto & pool = storage [key];
133153 pool.push (ptr);
134154 }
135155}
136156
137157std::vector<pool_info_t > pool_info () {
158+ auto & storage = get_storage ();
159+ auto & allocmap = get_allocmap ();
160+
138161 std::vector<pool_info_t > out;
139162
140163 // free blocks
141- for (int k = 0 ; k < _storage .size (); ++k) {
142- auto & pool = _storage [k];
164+ for (int k = 0 ; k < storage .size (); ++k) {
165+ auto & pool = storage [k];
143166 for (int i = 0 ; i < pool.size (); ++i) {
144167 auto pool_size = size_by_key (k);
145168 pool_info_t info = {false , pool_size};
@@ -148,7 +171,7 @@ std::vector<pool_info_t> pool_info() {
148171 }
149172
150173 // used blocks
151- for (auto it : _alocate_map ) {
174+ for (auto it : allocmap ) {
152175 auto key = it.second ;
153176 auto pool_size = size_by_key (key);
154177 pool_info_t info = {true , pool_size};
0 commit comments