aboutsummaryrefslogtreecommitdiff
path: root/src/common/libkogata/slab_alloc.c
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2017-05-31 11:23:59 +0200
committerAlex Auvolat <alex@adnab.me>2017-05-31 11:23:59 +0200
commit6990cc1b54e6fd0a1a3ae71edb65ea53db3bd9a1 (patch)
treee5cd9f38a7fa62cd7e20055633d8e2e2902156ff /src/common/libkogata/slab_alloc.c
parentb74a9f0c4b73bc3b98ec6c4345d9aaf4b6279f7a (diff)
downloadkogata-6990cc1b54e6fd0a1a3ae71edb65ea53db3bd9a1.tar.gz
kogata-6990cc1b54e6fd0a1a3ae71edb65ea53db3bd9a1.zip
Make memory allocator a bit faster ?
Diffstat (limited to 'src/common/libkogata/slab_alloc.c')
-rw-r--r--src/common/libkogata/slab_alloc.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/common/libkogata/slab_alloc.c b/src/common/libkogata/slab_alloc.c
index 2f6cef1..729bdc3 100644
--- a/src/common/libkogata/slab_alloc.c
+++ b/src/common/libkogata/slab_alloc.c
@@ -251,7 +251,7 @@ void slab_free(mem_allocator_t* a, void* addr) {
r->n_free_objs++;
if (r->n_free_objs == region_size / a->types[i].obj_size) {
- // region is completely unused, free it.
+ // region is completely unused, free it if we have two that are unused.
if (a->slabs[i].first_cache == r) {
a->slabs[i].first_cache = r->next_cache;
} else {
@@ -262,8 +262,22 @@ void slab_free(mem_allocator_t* a, void* addr) {
}
}
}
- a->free_fun(r->region_addr);
- add_free_descriptor(a, (descriptor_t*)r);
+
+ cache_t *last_cache = a->slabs[i].first_cache;
+ while (last_cache && last_cache->next_cache) last_cache = last_cache->next_cache;
+
+ if (last_cache == 0) {
+ ASSERT(a->slabs[i].first_cache == 0);
+ a->slabs[i].first_cache = r;
+ r->next_cache = 0;
+ } else if (last_cache->n_free_objs == region_size / a->types[i].obj_size) {
+ a->free_fun(r->region_addr);
+ add_free_descriptor(a, (descriptor_t*)r);
+ } else {
+ ASSERT(last_cache->next_cache == 0);
+ last_cache->next_cache = r;
+ r->next_cache = 0;
+ }
}
return;
}