|
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