3131#include " pool_disjoint.h"
3232#include " umf.h"
3333#include " utils_common.h"
34+ #include " utils_concurrency.h"
3435#include " utils_log.h"
3536#include " utils_math.h"
3637#include " utils_sanitizers.h"
3738
38- #include " utils_concurrency .h"
39+ #include " critnib/critnib .h"
3940
4041// TODO remove
4142#ifdef __cplusplus
@@ -108,7 +109,7 @@ typedef struct MemoryProviderError {
108109class DisjointPool ::AllocImpl {
109110 // It's important for the map to be destroyed last after buckets and their
110111 // slabs This is because slab's destructor removes the object from the map.
111- std::unordered_multimap< void *, slab_t *> KnownSlabs;
112+ critnib *known_slabs; // ( void *, slab_t *)
112113
113114 // prev std::shared_timed_mutex - ok?
114115 utils_mutex_t known_slabs_map_lock;
@@ -139,6 +140,7 @@ class DisjointPool::AllocImpl {
139140 VALGRIND_DO_CREATE_MEMPOOL (this , 0 , 0 );
140141
141142 utils_mutex_init (&known_slabs_map_lock);
143+ known_slabs = critnib_new ();
142144
143145 // Generate buckets sized such as: 64, 96, 128, 192, ..., CutOff.
144146 // Powers of 2 and the value halfway between the powers of 2.
@@ -190,6 +192,8 @@ class DisjointPool::AllocImpl {
190192
191193 VALGRIND_DO_DESTROY_MEMPOOL (this );
192194
195+ critnib_delete (known_slabs);
196+
193197 utils_mutex_destroy_not_free (&known_slabs_map_lock);
194198 }
195199
@@ -201,9 +205,7 @@ class DisjointPool::AllocImpl {
201205
202206 utils_mutex_t *getKnownSlabsMapLock () { return &known_slabs_map_lock; }
203207
204- std::unordered_multimap<void *, slab_t *> &getKnownSlabs () {
205- return KnownSlabs;
206- }
208+ critnib *getKnownSlabs () { return known_slabs; }
207209
208210 size_t SlabMinSize () { return params.SlabMinSize ; };
209211
@@ -438,38 +440,41 @@ umf_result_t DisjointPool::AllocImpl::deallocate(void *Ptr, bool &ToPool) {
438440 utils_mutex_lock (getKnownSlabsMapLock ());
439441
440442 ToPool = false ;
441- auto Slabs = getKnownSlabs ().equal_range (SlabPtr);
442- if (Slabs.first == Slabs.second ) {
443+
444+ slab_t *slab = (slab_t *)critnib_get (known_slabs, (uintptr_t )SlabPtr);
445+ // auto Slabs = getKnownSlabs().equal_range(SlabPtr);
446+ if (slab == NULL ) {
443447 utils_mutex_unlock (getKnownSlabsMapLock ());
444448 umf_result_t ret = memoryProviderFree (getMemHandle (), Ptr);
445449 return ret;
446450 }
447451
448- for (auto It = Slabs.first ; It != Slabs.second ; ++It) {
449- // The slab object won't be deleted until it's removed from the map which is
450- // protected by the lock, so it's safe to access it here.
451- auto &Slab = It->second ;
452- if (Ptr >= slab_get (Slab) && Ptr < slab_get_end (Slab)) {
453- // Unlock the map before freeing the chunk, it may be locked on write
454- // there
455- utils_mutex_unlock (getKnownSlabsMapLock ());
456- bucket_t *bucket = slab_get_bucket (Slab);
457-
458- if (getParams ().PoolTrace > 1 ) {
459- bucket_count_free (bucket);
460- }
461-
462- VALGRIND_DO_MEMPOOL_FREE (this , Ptr);
463- annotate_memory_inaccessible (Ptr, bucket_get_size (bucket));
464- if (bucket_get_size (bucket) <= bucket_chunk_cut_off (bucket)) {
465- bucket_free_chunk (bucket, Ptr, Slab, &ToPool);
466- } else {
467- bucket_free_slab (bucket, Slab, &ToPool);
468- }
469-
470- return UMF_RESULT_SUCCESS;
452+ // TODO - no multimap
453+ // for (auto It = Slabs.first; It != Slabs.second; ++It) {
454+
455+ // The slab object won't be deleted until it's removed from the map which is
456+ // protected by the lock, so it's safe to access it here.
457+ if (Ptr >= slab_get (slab) && Ptr < slab_get_end (slab)) {
458+ // Unlock the map before freeing the chunk, it may be locked on write
459+ // there
460+ utils_mutex_unlock (getKnownSlabsMapLock ());
461+ bucket_t *bucket = slab_get_bucket (slab);
462+
463+ if (getParams ().PoolTrace > 1 ) {
464+ bucket_count_free (bucket);
465+ }
466+
467+ VALGRIND_DO_MEMPOOL_FREE (this , Ptr);
468+ annotate_memory_inaccessible (Ptr, bucket_get_size (bucket));
469+ if (bucket_get_size (bucket) <= bucket_chunk_cut_off (bucket)) {
470+ bucket_free_chunk (bucket, Ptr, slab, &ToPool);
471+ } else {
472+ bucket_free_slab (bucket, slab, &ToPool);
471473 }
474+
475+ return UMF_RESULT_SUCCESS;
472476 }
477+ // } // for multimap
473478
474479 utils_mutex_unlock (getKnownSlabsMapLock ());
475480 // There is a rare case when we have a pointer from system allocation next
@@ -634,10 +639,9 @@ umf_memory_provider_handle_t bucket_get_mem_handle(bucket_t *bucket) {
634639 return t->getMemHandle ();
635640}
636641
637- std::unordered_multimap<void *, slab_t *> *
638- bucket_get_known_slabs (bucket_t *bucket) {
642+ critnib *bucket_get_known_slabs (bucket_t *bucket) {
639643 auto t = (DisjointPool::AllocImpl *)bucket->OwnAllocCtx ;
640- return & t->getKnownSlabs ();
644+ return t->getKnownSlabs ();
641645}
642646
643647utils_mutex_t *bucket_get_known_slabs_map_lock (bucket_t *bucket) {
@@ -647,35 +651,33 @@ utils_mutex_t *bucket_get_known_slabs_map_lock(bucket_t *bucket) {
647651
648652void slab_reg_by_addr (void *addr, slab_t *slab) {
649653 bucket_t *bucket = slab_get_bucket (slab);
650- auto Lock = bucket_get_known_slabs_map_lock (bucket);
651- auto Map = bucket_get_known_slabs (bucket);
654+ utils_mutex_t *lock = bucket_get_known_slabs_map_lock (bucket);
655+ critnib *slabs = bucket_get_known_slabs (bucket);
656+
657+ utils_mutex_lock (lock);
652658
653- utils_mutex_lock (Lock);
654- Map->insert ({addr, slab});
655- utils_mutex_unlock (Lock);
659+ // TODO multimap
660+ assert (critnib_get (slabs, (uintptr_t )addr) == NULL );
661+ critnib_insert (slabs, (uintptr_t )addr, slab, 0 );
662+
663+ utils_mutex_unlock (lock);
656664}
657665
658666void slab_unreg_by_addr (void *addr, slab_t *slab) {
659667 bucket_t *bucket = slab_get_bucket (slab);
660- auto Lock = bucket_get_known_slabs_map_lock (bucket);
661- auto Map = bucket_get_known_slabs (bucket);
662-
663- utils_mutex_lock (Lock);
668+ utils_mutex_t *lock = bucket_get_known_slabs_map_lock (bucket);
669+ critnib *slabs = bucket_get_known_slabs (bucket);
664670
665- auto Slabs = Map->equal_range (addr);
666- // At least the must get the current slab from the map.
667- assert (Slabs.first != Slabs.second && " Slab is not found" );
671+ utils_mutex_lock (lock);
668672
669- for (auto It = Slabs.first ; It != Slabs.second ; ++It) {
670- if (It->second == slab) {
671- Map->erase (It);
672- utils_mutex_unlock (Lock);
673- return ;
674- }
675- }
673+ // debug only
674+ // assume single-value per key
675+ slab_t *known_slab = (slab_t *)critnib_get (slabs, (uintptr_t )addr);
676+ assert (known_slab != NULL && " Slab is not found" );
677+ assert (slab == known_slab);
678+ critnib_remove (slabs, (uintptr_t )addr);
676679
677- assert (false && " Slab is not found" );
678- utils_mutex_unlock (Lock);
680+ utils_mutex_unlock (lock);
679681}
680682
681683#ifdef __cplusplus
0 commit comments