@@ -361,6 +361,140 @@ TEST_F(test, disjointPoolName) {
361361 umfDisjointPoolParamsDestroy (params);
362362}
363363
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+
364498INSTANTIATE_TEST_SUITE_P (disjointPoolTests, umfPoolTest,
365499 ::testing::Values (poolCreateExtParams{
366500 umfDisjointPoolOps (), defaultDisjointPoolConfig,
0 commit comments