@@ -316,6 +316,140 @@ struct disjoint_pool : public pool_interface<Provider> {
316316 return " disjoint_pool<" + Provider::name () + " >" ;
317317 }
318318};
319+ template <typename Provider>
320+ struct disjoint_pool_stack : public disjoint_pool <Provider> {
321+ using base = disjoint_pool<Provider>;
322+
323+ std::vector<umf_memory_provider_handle_t > providers;
324+ std::vector<umf_memory_pool_handle_t > pools;
325+ std::vector<void *> pool_ptrs;
326+
327+ static constexpr size_t firstPoolSize = 2ull * 1024 * 1024 * 1024 ; // 2GB
328+ static constexpr size_t levels = 7 ;
329+
330+ void SetUp (::benchmark::State &state) {
331+ base::provider.SetUp (state);
332+ if (state.thread_index () != 0 ) {
333+ return ;
334+ }
335+
336+ providers.push_back (base::provider.provider );
337+ base::provider.provider = NULL ;
338+
339+ auto params = base::getParams (state);
340+ umf_memory_pool_handle_t rootPool = nullptr ;
341+ auto umf_result = umfPoolCreate (base::getOps (state), providers[0 ],
342+ params.get (), 0 , &rootPool);
343+ if (umf_result != UMF_RESULT_SUCCESS) {
344+ state.SkipWithError (" umfPoolCreate() failed" );
345+ return ;
346+ }
347+
348+ pools.push_back (rootPool); // root pool
349+
350+ umf_fixed_memory_provider_params_handle_t params_fixed;
351+ umf_result = umfFixedMemoryProviderParamsCreate (
352+ ¶ms_fixed, (void *)0x1 , 0x1 ); // dummy
353+
354+ size_t poolSize = firstPoolSize;
355+ size_t level_start = 0 ;
356+ size_t level_pools = 1 ;
357+
358+ for (size_t level = 1 ; level < levels; ++level) {
359+ poolSize /=
360+ 3 ; // split each pools for 3 parts - two for children, and third from other allocations from this pool
361+ size_t new_level_pools = level_pools * 2 ;
362+
363+ for (size_t parent_idx = 0 ; parent_idx < level_pools;
364+ ++parent_idx) {
365+ umf_memory_pool_handle_t parent_pool =
366+ pools[level_start + parent_idx];
367+
368+ for (int child = 0 ; child < 2 ; ++child) {
369+ void *ptr = umfPoolMalloc (parent_pool, poolSize);
370+ if (!ptr) {
371+ state.SkipWithError (" umfPoolMalloc() failed" );
372+ return ;
373+ }
374+ pool_ptrs.push_back (ptr);
375+
376+ umf_result = umfFixedMemoryProviderParamsSetMemory (
377+ params_fixed, ptr, poolSize);
378+ umf_memory_provider_handle_t provider;
379+ umf_result = umfMemoryProviderCreate (
380+ umfFixedMemoryProviderOps (), params_fixed, &provider);
381+ if (umf_result != UMF_RESULT_SUCCESS) {
382+ state.SkipWithError (" umfMemoryProviderCreate() failed" );
383+ return ;
384+ }
385+ providers.push_back (provider);
386+
387+ umf_memory_pool_handle_t newPool;
388+ umf_result = umfPoolCreate (base::getOps (state), provider,
389+ params.get (), 0 , &newPool);
390+ if (umf_result != UMF_RESULT_SUCCESS) {
391+ state.SkipWithError (" umfPoolCreate() failed" );
392+ return ;
393+ }
394+
395+ pools.push_back (newPool);
396+ }
397+ }
398+
399+ level_start += level_pools;
400+ level_pools = new_level_pools;
401+ }
402+
403+ umfFixedMemoryProviderParamsDestroy (params_fixed);
404+ }
405+
406+ void TearDown (::benchmark::State &state) {
407+ if (state.thread_index () != 0 ) {
408+ return ;
409+ }
410+
411+ size_t pool_index = pools.size ();
412+ size_t provider_index = providers.size ();
413+ size_t ptr_index = pool_ptrs.size ();
414+
415+ // Go from last level to first (excluding level 0, root)
416+ for (int level = levels - 1 ; level > 0 ; --level) {
417+ size_t level_pools = 1ull << level; // 2^level pools
418+
419+ // Destroy pools
420+ for (size_t i = 0 ; i < level_pools; ++i) {
421+ --pool_index;
422+ umfPoolDestroy (pools[pool_index]);
423+ }
424+
425+ // Destroy providers and free pointers
426+ for (size_t i = 0 ; i < level_pools; ++i) {
427+ --provider_index;
428+ umfMemoryProviderDestroy (providers[provider_index]);
429+
430+ --ptr_index;
431+ void *ptr = pool_ptrs[ptr_index];
432+ if (ptr) {
433+ umfFree (ptr);
434+ }
435+ }
436+ }
437+
438+ // Root pool and provider
439+ umfPoolDestroy (pools[0 ]);
440+ umfMemoryProviderDestroy (providers[0 ]);
441+
442+ pools.clear ();
443+ providers.clear ();
444+ pool_ptrs.clear ();
445+
446+ base::TearDown (state);
447+ }
448+
449+ static std::string name () {
450+ return " disjoint_pool_stacked<" + Provider::name () + " >" ;
451+ }
452+ };
319453
320454#ifdef UMF_POOL_JEMALLOC_ENABLED
321455template <typename Provider>
0 commit comments