Skip to content

Commit ded4a20

Browse files
committed
use critnib
1 parent 3b06aee commit ded4a20

File tree

2 files changed

+58
-55
lines changed

2 files changed

+58
-55
lines changed

src/pool/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ if(UMF_BUILD_LIBUMF_POOL_DISJOINT)
1414
add_umf_library(
1515
NAME disjoint_pool
1616
TYPE STATIC
17-
SRCS pool_disjoint.cpp pool_disjoint.c ${POOL_EXTRA_SRCS}
17+
SRCS pool_disjoint.cpp pool_disjoint.c
18+
../critnib/critnib.c ${POOL_EXTRA_SRCS}
1819
LIBS ${POOL_EXTRA_LIBS})
1920

2021
target_compile_definitions(disjoint_pool

src/pool/pool_disjoint.cpp

Lines changed: 56 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@
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 {
108109
class 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

643647
utils_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

648652
void 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

658666
void 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

Comments
 (0)