|
8 | 8 | #include <assert.h> |
9 | 9 | #include <ctype.h> |
10 | 10 | #include <errno.h> |
| 11 | +#include <inttypes.h> |
11 | 12 | #include <stdlib.h> |
12 | 13 | #include <string.h> |
13 | 14 |
|
|
20 | 21 | #include "provider/provider_tracking.h" |
21 | 22 | #include "uthash/utlist.h" |
22 | 23 | #include "utils_common.h" |
| 24 | +#include "utils_concurrency.h" |
23 | 25 | #include "utils_log.h" |
24 | 26 | #include "utils_math.h" |
25 | 27 |
|
|
34 | 36 | // Forward declarations |
35 | 37 | static void bucket_update_stats(bucket_t *bucket, int in_use, int in_pool); |
36 | 38 | static bool bucket_can_pool(bucket_t *bucket); |
37 | | -static void bucket_decrement_pool(bucket_t *bucket); |
38 | 39 | static slab_list_item_t *bucket_get_avail_slab(bucket_t *bucket, |
39 | 40 | bool *from_pool); |
40 | 41 |
|
@@ -316,6 +317,7 @@ static void bucket_free_chunk(bucket_t *bucket, void *ptr, slab_t *slab, |
316 | 317 | assert(slab_it->val != NULL); |
317 | 318 | pool_unregister_slab(bucket->pool, slab_it->val); |
318 | 319 | DL_DELETE(bucket->available_slabs, slab_it); |
| 320 | + assert(bucket->available_slabs_num > 0); |
319 | 321 | bucket->available_slabs_num--; |
320 | 322 | destroy_slab(slab_it->val); |
321 | 323 | } |
@@ -381,10 +383,20 @@ static slab_list_item_t *bucket_get_avail_slab(bucket_t *bucket, |
381 | 383 | // Allocation from existing slab is treated as from pool for statistics. |
382 | 384 | *from_pool = true; |
383 | 385 | if (slab->num_chunks_allocated == 0) { |
| 386 | + assert(bucket->chunked_slabs_in_pool > 0); |
| 387 | +#ifndef NDEBUG |
| 388 | + uint64_t total_size_check; |
| 389 | + utils_atomic_load_acquire_u64(&bucket->shared_limits->total_size, |
| 390 | + &total_size_check); |
| 391 | + assert(total_size_check >= bucket_slab_alloc_size(bucket)); |
| 392 | +#endif |
384 | 393 | // If this was an empty slab, it was in the pool. |
385 | 394 | // Now it is no longer in the pool, so update count. |
386 | 395 | --bucket->chunked_slabs_in_pool; |
387 | | - bucket_decrement_pool(bucket); |
| 396 | + uint64_t size_to_add = bucket_slab_alloc_size(bucket); |
| 397 | + utils_fetch_and_sub_u64(&bucket->shared_limits->total_size, |
| 398 | + size_to_add); |
| 399 | + bucket_update_stats(bucket, 1, -1); |
388 | 400 | } |
389 | 401 | } |
390 | 402 |
|
@@ -420,36 +432,27 @@ static void bucket_update_stats(bucket_t *bucket, int in_use, int in_pool) { |
420 | 432 | in_pool * bucket_slab_alloc_size(bucket); |
421 | 433 | } |
422 | 434 |
|
423 | | -static void bucket_decrement_pool(bucket_t *bucket) { |
424 | | - bucket_update_stats(bucket, 1, -1); |
425 | | - utils_fetch_and_add64(&bucket->shared_limits->total_size, |
426 | | - -(long long)bucket_slab_alloc_size(bucket)); |
427 | | -} |
428 | | - |
429 | 435 | static bool bucket_can_pool(bucket_t *bucket) { |
430 | 436 | size_t new_free_slabs_in_bucket; |
431 | 437 |
|
432 | 438 | new_free_slabs_in_bucket = bucket->chunked_slabs_in_pool + 1; |
433 | 439 |
|
434 | 440 | // we keep at most params.capacity slabs in the pool |
435 | 441 | if (bucket_max_pooled_slabs(bucket) >= new_free_slabs_in_bucket) { |
436 | | - size_t pool_size = 0; |
437 | | - utils_atomic_load_acquire(&bucket->shared_limits->total_size, |
438 | | - &pool_size); |
439 | | - while (true) { |
440 | | - size_t new_pool_size = pool_size + bucket_slab_alloc_size(bucket); |
441 | | - |
442 | | - if (bucket->shared_limits->max_size < new_pool_size) { |
443 | | - break; |
444 | | - } |
445 | | - |
446 | | - if (utils_compare_exchange(&bucket->shared_limits->total_size, |
447 | | - &pool_size, &new_pool_size)) { |
448 | | - ++bucket->chunked_slabs_in_pool; |
449 | | - |
450 | | - bucket_update_stats(bucket, -1, 1); |
451 | | - return true; |
452 | | - } |
| 442 | + |
| 443 | + uint64_t size_to_add = bucket_slab_alloc_size(bucket); |
| 444 | + size_t previous_size = utils_fetch_and_add_u64( |
| 445 | + &bucket->shared_limits->total_size, size_to_add); |
| 446 | + |
| 447 | + if (previous_size + size_to_add <= bucket->shared_limits->max_size) { |
| 448 | + ++bucket->chunked_slabs_in_pool; |
| 449 | + bucket_update_stats(bucket, -1, 1); |
| 450 | + return true; |
| 451 | + } else { |
| 452 | + uint64_t old = utils_fetch_and_sub_u64( |
| 453 | + &bucket->shared_limits->total_size, size_to_add); |
| 454 | + (void)old; |
| 455 | + assert(old >= size_to_add); |
453 | 456 | } |
454 | 457 | } |
455 | 458 |
|
@@ -523,7 +526,7 @@ static void disjoint_pool_print_stats(disjoint_pool_t *pool) { |
523 | 526 | utils_mutex_unlock(&bucket->bucket_lock); |
524 | 527 | } |
525 | 528 |
|
526 | | - LOG_DEBUG("current pool size: %zu", |
| 529 | + LOG_DEBUG("current pool size: %" PRIu64, |
527 | 530 | disjoint_pool_get_limits(pool)->total_size); |
528 | 531 | LOG_DEBUG("suggested setting=;%c%s:%zu,%zu,64K", (char)tolower(name[0]), |
529 | 532 | (name + 1), high_bucket_size, high_peak_slabs_in_use); |
@@ -864,11 +867,12 @@ umf_result_t disjoint_pool_free(void *pool, void *ptr) { |
864 | 867 |
|
865 | 868 | if (disjoint_pool->params.pool_trace > 2) { |
866 | 869 | const char *name = disjoint_pool->params.name; |
867 | | - LOG_DEBUG("freed %s %p to %s, current total pool size: %zu, current " |
| 870 | + LOG_DEBUG("freed %s %p to %s, current total pool size: %llu, current " |
868 | 871 | "pool size for %s: %zu", |
869 | 872 | name, ptr, (to_pool ? "pool" : "provider"), |
870 | | - disjoint_pool_get_limits(disjoint_pool)->total_size, name, |
871 | | - disjoint_pool->params.cur_pool_size); |
| 873 | + (unsigned long long)disjoint_pool_get_limits(disjoint_pool) |
| 874 | + ->total_size, |
| 875 | + name, disjoint_pool->params.cur_pool_size); |
872 | 876 | } |
873 | 877 |
|
874 | 878 | return UMF_RESULT_SUCCESS; |
@@ -920,7 +924,8 @@ umf_memory_pool_ops_t *umfDisjointPoolOps(void) { |
920 | 924 |
|
921 | 925 | umf_disjoint_pool_shared_limits_t * |
922 | 926 | umfDisjointPoolSharedLimitsCreate(size_t max_size) { |
923 | | - umf_disjoint_pool_shared_limits_t *ptr = umf_ba_global_alloc(sizeof(*ptr)); |
| 927 | + umf_disjoint_pool_shared_limits_t *ptr = |
| 928 | + umf_ba_global_aligned_alloc(sizeof(*ptr), 8); |
924 | 929 | if (ptr == NULL) { |
925 | 930 | LOG_ERR("cannot allocate memory for disjoint pool shared limits"); |
926 | 931 | return NULL; |
|
0 commit comments