6 #ifndef ABTI_MEM_POOL_H_INCLUDED
7 #define ABTI_MEM_POOL_H_INCLUDED
9 #define ABT_MEM_POOL_MAX_LOCAL_BUCKETS 2
10 #define ABT_MEM_POOL_NUM_RETURN_BUCKETS 1
11 #define ABT_MEM_POOL_NUM_TAKE_BUCKETS 1
13 typedef union ABTI_mem_pool_header_bucket_info {
15 ABTI_sync_lifo_element lifo_elem;
18 } ABTI_mem_pool_header_bucket_info;
20 typedef struct ABTI_mem_pool_header {
21 struct ABTI_mem_pool_header *p_next;
22 ABTI_mem_pool_header_bucket_info bucket_info;
23 } ABTI_mem_pool_header;
25 typedef struct ABTI_mem_pool_page {
26 ABTI_sync_lifo_element lifo_elem;
27 struct ABTI_mem_pool_page *p_next_empty_page;
32 size_t mem_extra_size;
35 typedef struct ABTI_mem_pool_global_pool_mprotect_config {
42 } ABTI_mem_pool_global_pool_mprotect_config;
58 typedef struct ABTI_mem_pool_global_pool {
62 size_t alignment_hint;
66 size_t num_headers_per_bucket;
72 ABTI_mem_pool_global_pool_mprotect_config mprotect_config;
74 ABTI_sync_lifo bucket_lifo;
76 ABTI_sync_lifo mem_page_lifo;
78 ABTD_atomic_ptr p_mem_page_empty;
83 ABTD_spinlock partial_bucket_lock;
84 ABTI_mem_pool_header *partial_bucket;
85 } ABTI_mem_pool_global_pool;
101 typedef struct ABTI_mem_pool_local_pool {
102 ABTI_mem_pool_global_pool *p_global_pool;
103 size_t num_headers_per_bucket;
108 } ABTI_mem_pool_local_pool;
110 void ABTI_mem_pool_init_global_pool(
111 ABTI_mem_pool_global_pool *p_global_pool,
size_t num_headers_per_bucket,
112 size_t header_size,
size_t header_offset,
size_t page_size,
114 uint32_t num_lp_type_requests,
size_t alignment_hint,
115 ABTI_mem_pool_global_pool_mprotect_config *p_mprotect_config);
116 void ABTI_mem_pool_destroy_global_pool(
117 ABTI_mem_pool_global_pool *p_global_pool);
119 ABTI_mem_pool_init_local_pool(ABTI_mem_pool_local_pool *p_local_pool,
120 ABTI_mem_pool_global_pool *p_global_pool);
121 void ABTI_mem_pool_destroy_local_pool(ABTI_mem_pool_local_pool *p_local_pool);
122 int ABTI_mem_pool_take_bucket(ABTI_mem_pool_global_pool *p_global_pool,
123 ABTI_mem_pool_header **p_bucket);
124 void ABTI_mem_pool_return_bucket(ABTI_mem_pool_global_pool *p_global_pool,
125 ABTI_mem_pool_header *bucket);
128 ABTI_mem_pool_alloc(ABTI_mem_pool_local_pool *p_local_pool,
void **p_mem)
130 size_t bucket_index = p_local_pool->bucket_index;
131 ABTI_mem_pool_header *cur_bucket = p_local_pool->buckets[bucket_index];
132 size_t num_headers_in_cur_bucket = cur_bucket->bucket_info.num_headers;
135 ABTI_ASSERT(num_headers_in_cur_bucket >= 1);
136 if (num_headers_in_cur_bucket == 1) {
138 if (bucket_index == 0) {
144 ABTI_mem_pool_take_bucket(p_local_pool->p_global_pool,
145 &p_local_pool->buckets[i]);
146 if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno !=
ABT_SUCCESS) {
148 #if ABT_MEM_POOL_NUM_TAKE_BUCKETS > 1
150 for (j = 0; j < i; j++) {
151 ABTI_mem_pool_return_bucket(p_local_pool->p_global_pool,
152 p_local_pool->buckets[j]);
160 p_local_pool->bucket_index = bucket_index - 1;
165 ABTI_mem_pool_header *p_next = cur_bucket->p_next;
166 p_next->bucket_info.num_headers = num_headers_in_cur_bucket - 1;
167 p_local_pool->buckets[bucket_index] = p_next;
170 *p_mem = (
void *)cur_bucket;
174 static inline void ABTI_mem_pool_free(ABTI_mem_pool_local_pool *p_local_pool,
178 size_t bucket_index = p_local_pool->bucket_index;
179 ABTI_mem_pool_header *p_freed_header = (ABTI_mem_pool_header *)mem;
180 ABTI_mem_pool_header *cur_bucket = p_local_pool->buckets[bucket_index];
181 if (cur_bucket->bucket_info.num_headers ==
182 p_local_pool->num_headers_per_bucket) {
188 ABTI_mem_pool_return_bucket(p_local_pool->p_global_pool,
189 p_local_pool->buckets[i]);
194 p_local_pool->buckets[i];
199 p_local_pool->bucket_index = bucket_index;
200 p_freed_header->p_next = NULL;
201 p_freed_header->bucket_info.num_headers = 1;
203 p_freed_header->p_next = cur_bucket;
204 p_freed_header->bucket_info.num_headers =
205 cur_bucket->bucket_info.num_headers + 1;
207 p_local_pool->buckets[bucket_index] = p_freed_header;