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