@@ -361,6 +361,140 @@ TEST_F(test, disjointPoolName) {
361
361
umfDisjointPoolParamsDestroy (params);
362
362
}
363
363
364
+ TEST_F (test, disjointPoolDefaultParams) {
365
+ // Disjoint pool defaults
366
+ static constexpr size_t DefaultSlabMinSize = 64 * 1024 ; // 64K
367
+ static constexpr size_t DefaultMaxPoolableSize = 2 * 1024 * 1024 ; // 2MB
368
+
369
+ umf_disjoint_pool_params_handle_t params = nullptr ;
370
+ umf_memory_pool_handle_t pool = nullptr ;
371
+ umf_memory_provider_handle_t provider_handle = nullptr ;
372
+
373
+ // Create disjoint pool parameters with default settings
374
+ umf_result_t res = umfDisjointPoolParamsCreate (¶ms);
375
+ EXPECT_EQ (res, UMF_RESULT_SUCCESS);
376
+
377
+ size_t expected_free_counter = 0 ;
378
+ static size_t free_counter = 0 ;
379
+ static size_t last_requested_size = 0 ;
380
+ struct memory_provider : public umf_test ::provider_base_t {
381
+ umf_result_t alloc (size_t size, size_t alignment, void **ptr) noexcept {
382
+ *ptr = umf_ba_global_aligned_alloc (size, alignment);
383
+ last_requested_size = size;
384
+ return UMF_RESULT_SUCCESS;
385
+ }
386
+
387
+ umf_result_t free (void *ptr, [[maybe_unused]] size_t size) noexcept {
388
+ // do the actual free only when we expect the success
389
+ umf_ba_global_free (ptr);
390
+ free_counter++;
391
+ return UMF_RESULT_SUCCESS;
392
+ }
393
+ };
394
+
395
+ umf_memory_provider_ops_t provider_ops =
396
+ umf_test::providerMakeCOps<memory_provider, void >();
397
+
398
+ auto providerUnique =
399
+ wrapProviderUnique (createProviderChecked (&provider_ops, nullptr ));
400
+ provider_handle = providerUnique.get ();
401
+
402
+ res = umfDisjointPoolParamsSetTrace (params, 3 );
403
+ ASSERT_EQ (res, UMF_RESULT_SUCCESS);
404
+
405
+ umf_result_t ret = umfPoolCreate (umfDisjointPoolOps (), provider_handle,
406
+ params, UMF_POOL_CREATE_FLAG_NONE, &pool);
407
+ ASSERT_EQ (ret, UMF_RESULT_SUCCESS);
408
+
409
+ // Test allocation and deallocation
410
+ // This will use the default disjoint pool parameters
411
+ void *ptr = umfPoolMalloc (pool, DefaultSlabMinSize - 1 ); // Should use pool
412
+ ASSERT_NE (ptr, nullptr );
413
+ ASSERT_EQ (
414
+ last_requested_size,
415
+ DefaultSlabMinSize); // First allocated size should be at least the slab min size
416
+ ret = umfPoolFree (pool, ptr);
417
+ ASSERT_EQ (ret, UMF_RESULT_SUCCESS);
418
+ ASSERT_EQ (free_counter, expected_free_counter);
419
+
420
+ // Test allocation and deallocation with a different size
421
+ expected_free_counter = 1 ;
422
+ ptr =
423
+ umfPoolMalloc (pool, DefaultMaxPoolableSize + 1 ); // Fallback to provider
424
+ ASSERT_EQ (last_requested_size, DefaultMaxPoolableSize + 1 );
425
+ ASSERT_NE (ptr, nullptr );
426
+ ret = umfPoolFree (pool, ptr);
427
+ ASSERT_EQ (ret, UMF_RESULT_SUCCESS);
428
+ ASSERT_EQ (free_counter, expected_free_counter);
429
+
430
+ // Cleaning up
431
+ umfPoolDestroy (pool);
432
+ umfDisjointPoolParamsDestroy (params);
433
+ expected_free_counter = 2 ;
434
+ ASSERT_EQ (free_counter, expected_free_counter);
435
+ }
436
+
437
+ TEST_F (test, disjointPoolDefaultCapacity) {
438
+ // Disjoint pool defaults
439
+ static constexpr size_t DefaultSlabMinSize = 64 * 1024 ; // 64K
440
+ static constexpr size_t DefaultCapacity = 4 ;
441
+
442
+ static size_t free_counter = 0 ;
443
+ static size_t last_requested_size = 0 ;
444
+
445
+ struct memory_provider : public umf_test ::provider_base_t {
446
+ umf_result_t alloc (size_t size, size_t alignment, void **ptr) noexcept {
447
+ *ptr = umf_ba_global_aligned_alloc (size, alignment);
448
+ last_requested_size = size;
449
+ return UMF_RESULT_SUCCESS;
450
+ }
451
+ umf_result_t free (void *ptr, [[maybe_unused]] size_t size) noexcept {
452
+ // do the actual free only when we expect the success
453
+ umf_ba_global_free (ptr);
454
+ free_counter++;
455
+ return UMF_RESULT_SUCCESS;
456
+ }
457
+ };
458
+ umf_memory_provider_ops_t provider_ops =
459
+ umf_test::providerMakeCOps<memory_provider, void >();
460
+ auto providerUnique =
461
+ wrapProviderUnique (createProviderChecked (&provider_ops, nullptr ));
462
+ umf_memory_provider_handle_t provider_handle = providerUnique.get ();
463
+ umf_disjoint_pool_params_handle_t params = nullptr ;
464
+ umf_result_t ret = umfDisjointPoolParamsCreate (¶ms);
465
+ ASSERT_EQ (ret, UMF_RESULT_SUCCESS);
466
+
467
+ umf_memory_pool_handle_t pool = nullptr ;
468
+ ret = umfPoolCreate (umfDisjointPoolOps (), provider_handle, params,
469
+ UMF_POOL_CREATE_FLAG_NONE, &pool);
470
+ ASSERT_EQ (ret, UMF_RESULT_SUCCESS);
471
+
472
+ // Test capacity
473
+ void *ptrs[DefaultCapacity + 1 ];
474
+ for (size_t i = 0 ; i < DefaultCapacity + 1 ; ++i) {
475
+ ptrs[i] =
476
+ umfPoolMalloc (pool, DefaultSlabMinSize - 1 ); // Should use pool
477
+ ASSERT_NE (ptrs[i], nullptr );
478
+ ASSERT_EQ (last_requested_size, DefaultSlabMinSize);
479
+ }
480
+
481
+ size_t i;
482
+ for (i = 0 ; i < DefaultCapacity + 1 ; ++i) {
483
+ ret = umfPoolFree (pool, ptrs[i]);
484
+ ASSERT_EQ (ret, UMF_RESULT_SUCCESS);
485
+ }
486
+ ASSERT_EQ (
487
+ free_counter,
488
+ i - DefaultCapacity); // only the last allocation exceeds the capacity
489
+
490
+ // Cleaning up
491
+ umfPoolDestroy (pool);
492
+ umfDisjointPoolParamsDestroy (params);
493
+ ASSERT_EQ (free_counter,
494
+ DefaultCapacity +
495
+ 1 ); // +1 for the last allocation that exceeded the capacity
496
+ }
497
+
364
498
INSTANTIATE_TEST_SUITE_P (disjointPoolTests, umfPoolTest,
365
499
::testing::Values (poolCreateExtParams{
366
500
umfDisjointPoolOps (), defaultDisjointPoolConfig,
0 commit comments