9 static inline ABTI_mem_pool_page *
12 return (ABTI_mem_pool_page *)(((
char *)lifo_elem) -
13 offsetof(ABTI_mem_pool_page, lifo_elem));
16 static inline ABTI_mem_pool_header *
20 ABTI_mem_pool_header *)(((
char *)lifo_elem) -
21 (offsetof(ABTI_mem_pool_header, bucket_info) +
22 offsetof(ABTI_mem_pool_header_bucket_info,
33 size -= ((uintptr_t)mprotect_addr) - ((uintptr_t)addr);
40 ABTI_mem_pool_header *bucket)
43 const int num_headers_per_bucket = p_global_pool->num_headers_per_bucket;
45 ABTD_spinlock_acquire(&p_global_pool->partial_bucket_lock);
46 if (!p_global_pool->partial_bucket) {
47 p_global_pool->partial_bucket = bucket;
49 int num_headers_in_partial_bucket =
50 p_global_pool->partial_bucket->bucket_info.num_headers;
51 int num_headers_in_bucket = bucket->bucket_info.num_headers;
52 if (num_headers_in_partial_bucket + num_headers_in_bucket <
53 num_headers_per_bucket) {
56 ABTI_mem_pool_header *partial_bucket_tail =
57 p_global_pool->partial_bucket;
58 for (i = 1; i < num_headers_in_partial_bucket; i++) {
59 partial_bucket_tail = partial_bucket_tail->p_next;
61 partial_bucket_tail->p_next = bucket;
62 p_global_pool->partial_bucket->bucket_info.num_headers =
63 num_headers_in_partial_bucket + num_headers_in_bucket;
66 ABTI_mem_pool_header *partial_bucket_header =
67 p_global_pool->partial_bucket;
68 for (i = 1; i < num_headers_per_bucket - num_headers_in_bucket;
70 partial_bucket_header = partial_bucket_header->p_next;
72 ABTI_mem_pool_header *new_partial_bucket = NULL;
73 if (num_headers_in_partial_bucket + num_headers_in_bucket !=
74 num_headers_per_bucket) {
75 new_partial_bucket = partial_bucket_header->p_next;
76 new_partial_bucket->bucket_info.num_headers =
77 num_headers_per_bucket -
78 (num_headers_in_partial_bucket + num_headers_in_bucket);
80 partial_bucket_header->p_next = bucket;
81 ABTI_mem_pool_return_bucket(p_global_pool,
82 p_global_pool->partial_bucket);
83 p_global_pool->partial_bucket = new_partial_bucket;
86 ABTD_spinlock_release(&p_global_pool->partial_bucket_lock);
89 void ABTI_mem_pool_init_global_pool(
90 ABTI_mem_pool_global_pool *p_global_pool,
size_t num_headers_per_bucket,
91 size_t header_size,
size_t header_offset,
size_t page_size,
93 uint32_t num_lp_type_requests,
size_t alignment_hint,
94 ABTI_mem_pool_global_pool_mprotect_config *p_mprotect_config)
96 p_global_pool->num_headers_per_bucket = num_headers_per_bucket;
97 ABTI_ASSERT(header_offset +
sizeof(ABTI_mem_pool_header) <= header_size);
98 p_global_pool->header_size = header_size;
99 p_global_pool->header_offset = header_offset;
100 p_global_pool->page_size = page_size;
101 if (p_mprotect_config) {
102 memcpy(&p_global_pool->mprotect_config, p_mprotect_config,
103 sizeof(ABTI_mem_pool_global_pool_mprotect_config));
105 p_global_pool->mprotect_config.enabled =
ABT_FALSE;
109 ABTI_ASSERT(num_lp_type_requests <=
110 sizeof(p_global_pool->lp_type_requests) /
112 p_global_pool->num_lp_type_requests = num_lp_type_requests;
113 memcpy(p_global_pool->lp_type_requests, lp_type_requests,
116 if (p_global_pool->mprotect_config.enabled) {
118 for (i = 0; i < num_lp_type_requests; i++) {
119 if (p_global_pool->lp_type_requests[i] !=
121 p_global_pool->lp_type_requests[idx++] =
122 p_global_pool->lp_type_requests[i];
128 p_global_pool->num_lp_type_requests = 1;
130 p_global_pool->num_lp_type_requests = idx;
133 p_global_pool->alignment_hint = alignment_hint;
135 ABTI_sync_lifo_init(&p_global_pool->mem_page_lifo);
136 ABTD_atomic_relaxed_store_ptr(&p_global_pool->p_mem_page_empty, NULL);
137 ABTI_sync_lifo_init(&p_global_pool->bucket_lifo);
138 ABTD_spinlock_clear(&p_global_pool->partial_bucket_lock);
139 p_global_pool->partial_bucket = NULL;
142 void ABTI_mem_pool_destroy_global_pool(ABTI_mem_pool_global_pool *p_global_pool)
147 ABTI_mem_pool_page *p_page;
148 ABTI_sync_lifo_element *p_page_lifo_elem;
149 while ((p_page_lifo_elem =
150 ABTI_sync_lifo_pop_unsafe(&p_global_pool->mem_page_lifo))) {
152 if (p_global_pool->mprotect_config.enabled) {
156 p_global_pool->mprotect_config.alignment,
164 p_page = (ABTI_mem_pool_page *)ABTD_atomic_relaxed_load_ptr(
165 &p_global_pool->p_mem_page_empty);
167 ABTI_mem_pool_page *p_next = p_page->p_next_empty_page;
168 if (p_global_pool->mprotect_config.enabled) {
172 p_global_pool->mprotect_config.alignment,
181 ABTI_sync_lifo_destroy(&p_global_pool->bucket_lifo);
182 ABTI_sync_lifo_destroy(&p_global_pool->mem_page_lifo);
186 ABTI_mem_pool_init_local_pool(ABTI_mem_pool_local_pool *p_local_pool,
187 ABTI_mem_pool_global_pool *p_global_pool)
189 p_local_pool->p_global_pool = p_global_pool;
190 p_local_pool->num_headers_per_bucket =
191 p_global_pool->num_headers_per_bucket;
195 ABTI_mem_pool_take_bucket(p_global_pool, &p_local_pool->buckets[0]);
196 ABTI_CHECK_ERROR(abt_errno);
197 p_local_pool->bucket_index = 0;
201 void ABTI_mem_pool_destroy_local_pool(ABTI_mem_pool_local_pool *p_local_pool)
204 int bucket_index = p_local_pool->bucket_index;
206 for (i = 0; i < bucket_index; i++) {
207 ABTI_mem_pool_return_bucket(p_local_pool->p_global_pool,
208 p_local_pool->buckets[i]);
210 const size_t num_headers_per_bucket = p_local_pool->num_headers_per_bucket;
211 ABTI_mem_pool_header *cur_bucket = p_local_pool->buckets[bucket_index];
212 if (cur_bucket->bucket_info.num_headers == num_headers_per_bucket) {
214 ABTI_mem_pool_return_bucket(p_local_pool->p_global_pool,
215 p_local_pool->buckets[bucket_index]);
222 ABTI_mem_pool_take_bucket(ABTI_mem_pool_global_pool *p_global_pool,
223 ABTI_mem_pool_header **p_bucket)
226 ABTI_sync_lifo_element *p_popped_bucket_lifo_elem =
227 ABTI_sync_lifo_pop(&p_global_pool->bucket_lifo);
228 const int num_headers_per_bucket = p_global_pool->num_headers_per_bucket;
231 ABTI_mem_pool_header *popped_bucket =
233 popped_bucket->bucket_info.num_headers = num_headers_per_bucket;
234 *p_bucket = popped_bucket;
238 const size_t header_size = p_global_pool->header_size;
239 int num_headers = 0, i;
240 ABTI_mem_pool_header *p_head = NULL;
242 ABTI_mem_pool_page *p_page;
243 ABTI_sync_lifo_element *p_page_lifo_elem;
246 if ((p_page_lifo_elem =
247 ABTI_sync_lifo_pop(&p_global_pool->mem_page_lifo))) {
252 const size_t page_size = p_global_pool->page_size;
257 p_global_pool->alignment_hint,
258 p_global_pool->lp_type_requests,
259 p_global_pool->num_lp_type_requests,
260 &lp_type, &p_alloc_mem);
261 if (ABTI_IS_ERROR_CHECK_ENABLED && abt_errno !=
ABT_SUCCESS) {
263 if (num_headers != 0) {
265 p_head->bucket_info.num_headers = num_headers;
271 (ABTI_mem_pool_page *)(((
char *)p_alloc_mem) + page_size -
272 sizeof(ABTI_mem_pool_page));
273 p_page->mem = p_alloc_mem;
274 p_page->page_size = page_size;
275 p_page->lp_type = lp_type;
276 p_page->p_mem_extra = p_alloc_mem;
277 p_page->mem_extra_size = page_size -
sizeof(ABTI_mem_pool_page);
280 int num_provided = p_page->mem_extra_size / header_size;
281 int num_required = num_headers_per_bucket - num_headers;
282 if (num_required < num_provided)
283 num_provided = num_required;
284 ABTI_ASSERT(num_provided != 0);
286 void *p_mem_extra = p_page->p_mem_extra;
287 p_page->p_mem_extra =
288 (
void *)(((
char *)p_mem_extra) + header_size * num_provided);
289 p_page->mem_extra_size -= header_size * num_provided;
292 if (p_page->mem_extra_size >= header_size) {
295 ABTI_sync_lifo_push(&p_global_pool->mem_page_lifo,
302 void *p_cur_mem_page;
304 p_cur_mem_page = ABTD_atomic_acquire_load_ptr(
305 &p_global_pool->p_mem_page_empty);
306 p_page->p_next_empty_page =
307 (ABTI_mem_pool_page *)p_cur_mem_page;
308 }
while (!ABTD_atomic_bool_cas_weak_ptr(&p_global_pool
314 size_t header_offset = p_global_pool->header_offset;
315 ABTI_mem_pool_header *p_local_tail =
316 (ABTI_mem_pool_header *)(((
char *)p_mem_extra) + header_offset);
317 p_local_tail->p_next = p_head;
318 ABTI_mem_pool_header *p_prev = p_local_tail;
319 if (!p_global_pool->mprotect_config.enabled) {
321 for (i = 1; i < num_provided; i++) {
322 ABTI_mem_pool_header *p_cur =
323 (ABTI_mem_pool_header *)(((
char *)p_prev) +
325 p_cur->p_next = p_prev;
331 p_global_pool->mprotect_config.check_error;
332 const size_t protect_offset =
333 p_global_pool->mprotect_config.offset;
334 const size_t protect_page_size =
335 p_global_pool->mprotect_config.page_size;
336 const size_t protect_alignment =
337 p_global_pool->mprotect_config.alignment;
342 protect_page_size, protect_alignment,
347 for (i = 1; i < num_provided; i++) {
348 ABTI_mem_pool_header *p_cur =
349 (ABTI_mem_pool_header *)(((
char *)p_prev) +
351 p_cur->p_next = p_prev;
355 header_offset + protect_offset),
356 protect_page_size, protect_alignment,
364 num_headers += num_provided;
365 if (num_headers == num_headers_per_bucket) {
366 p_head->bucket_info.num_headers = num_headers_per_bucket;
374 void ABTI_mem_pool_return_bucket(ABTI_mem_pool_global_pool *p_global_pool,
375 ABTI_mem_pool_header *bucket)
378 ABTI_sync_lifo_push(&p_global_pool->bucket_lifo,
379 &bucket->bucket_info.lifo_elem);