@@ -356,6 +356,140 @@ 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 size_t free_counter = 0 ;
374+ static size_t 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 (
409+ last_requested_size,
410+ DefaultSlabMinSize); // First allocated size should be at least the slab min size
411+ ret = umfPoolFree (pool, ptr);
412+ ASSERT_EQ (ret, UMF_RESULT_SUCCESS);
413+ ASSERT_EQ (free_counter, expected_free_counter);
414+
415+ // Test allocation and deallocation with a different size
416+ expected_free_counter = 1 ;
417+ ptr =
418+ umfPoolMalloc (pool, DefaultMaxPoolableSize + 1 ); // Fallback to provider
419+ ASSERT_EQ (last_requested_size, DefaultMaxPoolableSize + 1 );
420+ ASSERT_NE (ptr, nullptr );
421+ ret = umfPoolFree (pool, ptr);
422+ ASSERT_EQ (ret, UMF_RESULT_SUCCESS);
423+ ASSERT_EQ (free_counter, expected_free_counter);
424+
425+ // Cleaning up
426+ umfPoolDestroy (pool);
427+ umfDisjointPoolParamsDestroy (params);
428+ expected_free_counter = 2 ;
429+ ASSERT_EQ (free_counter, expected_free_counter);
430+ }
431+
432+ TEST_F (test, disjointPoolDefaultCapacity) {
433+ // Disjoint pool defaults
434+ static constexpr size_t DefaultSlabMinSize = 64 * 1024 ; // 64K
435+ static constexpr size_t DefaultCapacity = 4 ;
436+
437+ static size_t free_counter = 0 ;
438+ static size_t last_requested_size = 0 ;
439+
440+ struct memory_provider : public umf_test ::provider_base_t {
441+ umf_result_t alloc (size_t size, size_t alignment, void **ptr) noexcept {
442+ *ptr = umf_ba_global_aligned_alloc (size, alignment);
443+ last_requested_size = size;
444+ return UMF_RESULT_SUCCESS;
445+ }
446+ umf_result_t free (void *ptr, [[maybe_unused]] size_t size) noexcept {
447+ // do the actual free only when we expect the success
448+ umf_ba_global_free (ptr);
449+ free_counter++;
450+ return UMF_RESULT_SUCCESS;
451+ }
452+ };
453+ umf_memory_provider_ops_t provider_ops =
454+ umf_test::providerMakeCOps<memory_provider, void >();
455+ auto providerUnique =
456+ wrapProviderUnique (createProviderChecked (&provider_ops, nullptr ));
457+ umf_memory_provider_handle_t provider_handle = providerUnique.get ();
458+ umf_disjoint_pool_params_handle_t params = nullptr ;
459+ umf_result_t ret = umfDisjointPoolParamsCreate (¶ms);
460+ ASSERT_EQ (ret, UMF_RESULT_SUCCESS);
461+
462+ umf_memory_pool_handle_t pool = nullptr ;
463+ ret = umfPoolCreate (umfDisjointPoolOps (), provider_handle, params,
464+ UMF_POOL_CREATE_FLAG_NONE, &pool);
465+ ASSERT_EQ (ret, UMF_RESULT_SUCCESS);
466+
467+ // Test capacity
468+ void *ptrs[DefaultCapacity + 1 ];
469+ for (size_t i = 0 ; i < DefaultCapacity + 1 ; ++i) {
470+ ptrs[i] =
471+ umfPoolMalloc (pool, DefaultSlabMinSize - 1 ); // Should use pool
472+ ASSERT_NE (ptrs[i], nullptr );
473+ ASSERT_EQ (last_requested_size, DefaultSlabMinSize);
474+ }
475+
476+ size_t i;
477+ for (i = 0 ; i < DefaultCapacity + 1 ; ++i) {
478+ ret = umfPoolFree (pool, ptrs[i]);
479+ ASSERT_EQ (ret, UMF_RESULT_SUCCESS);
480+ }
481+ ASSERT_EQ (
482+ free_counter,
483+ i - DefaultCapacity); // only the last allocation exceeds the capacity
484+
485+ // Cleaning up
486+ umfPoolDestroy (pool);
487+ umfDisjointPoolParamsDestroy (params);
488+ ASSERT_EQ (free_counter,
489+ DefaultCapacity +
490+ 1 ); // +1 for the last allocation that exceeded the capacity
491+ }
492+
359493INSTANTIATE_TEST_SUITE_P (disjointPoolTests, umfPoolTest,
360494 ::testing::Values (poolCreateExtParams{
361495 umfDisjointPoolOps (), defaultDisjointPoolConfig,
0 commit comments