From 9e1eae8e586065dd962f66eb2365535ed22d8091 Mon Sep 17 00:00:00 2001 From: dzaima Date: Mon, 5 Apr 2021 18:30:46 +0300 Subject: [PATCH] 2 buddy allocator --- src/h.h | 4 +-- src/main.c | 2 +- src/mm_2buddy.c | 56 ++++++++++++++++++++++++++++++++ src/mm_buddy.c | 72 +++++++----------------------------------- src/mm_buddyTemplate.c | 60 +++++++++++++++++++++++++++++++++++ 5 files changed, 130 insertions(+), 64 deletions(-) create mode 100644 src/mm_2buddy.c create mode 100644 src/mm_buddyTemplate.c diff --git a/src/h.h b/src/h.h index 31b2ccf0..20a490d9 100644 --- a/src/h.h +++ b/src/h.h @@ -487,7 +487,7 @@ u64 talloc = 0; u32** actrs; #endif -void onAlloc(usz sz, u8 type) { +static void onAlloc(usz sz, u8 type) { #ifdef ALLOC_STAT if (!actrs) { actrs = malloc(sizeof(u32*)*actrc); @@ -501,7 +501,7 @@ void onAlloc(usz sz, u8 type) { talloc+= sz; #endif } -void onFree(Value* x) { +static void onFree(Value* x) { #ifdef ALLOC_STAT ctr_f[x->type]++; #endif diff --git a/src/main.c b/src/main.c index 75d6f999..e9a3cf97 100644 --- a/src/main.c +++ b/src/main.c @@ -8,7 +8,7 @@ #define FAKE_RUNTIME false #include "h.h" -#include "mm_buddy.c" +#include "mm_2buddy.c" #include "harr.c" #include "fillarr.c" #include "i32arr.c" diff --git a/src/mm_2buddy.c b/src/mm_2buddy.c new file mode 100644 index 00000000..fdcc30da --- /dev/null +++ b/src/mm_2buddy.c @@ -0,0 +1,56 @@ +#include "h.h" +#include + +#ifndef MAP_NORESERVE + #define MAP_NORESERVE 0 // apparently needed for freebsd or something +#endif + +typedef struct EmptyValue EmptyValue; +struct EmptyValue { // needs set: mmInfo; type=t_empty; next; everything else can be garbage + struct Value; + EmptyValue* next; +}; + +#define BSZ(x) (1ull<<(x)) +#define BSZI(x) (64-__builtin_clzl((x)-1ull)) +#define MMI(x) x +#define buckets b1_buckets +#define mm_free b1_free +#define mm_makeEmpty b1_makeEmpty +#define mm_allocL b1_allocL +#include "mm_buddyTemplate.c" +#undef buckets +#undef mm_free +#undef mm_makeEmpty +#undef mm_allocL + +#define BSZ(x) ((1ull<<(x))*3) +#define BSZI(x) (64-__builtin_clzl((x/3)-1ull)) +#define MMI(x) ((x)|64) +#define buckets b3_buckets +#define mm_free b3_free +#define mm_makeEmpty b3_makeEmpty +#define mm_allocL b3_allocL +#include "mm_buddyTemplate.c" +#undef buckets +#undef mm_free +#undef mm_makeEmpty +#undef mm_allocL + +void* mm_allocN(usz sz, u8 type) { + assert(sz>12); + onAlloc(sz, type); + u8 b1 = 64-__builtin_clzl(sz-1ull); + if (sz*3 <= 1ull<<(b1+1)) return b3_allocL(b1-2, type); + return b1_allocL(b1, type); +} +void mm_free(Value* x) { + if (x->mmInfo&64) b3_free(x); + else b1_free(x); +} + +u64 mm_round(usz sz) { + u8 b1 = 64-__builtin_clzl(sz-1ull); + if (sz*3 <= 1ull<<(b1+1)) return (1ull<<(b1-2)) * 3; + return 1ull<next is garbage - u8 cb = bucket; - EmptyValue* c; - while (true) { - cb++; - if (buckets[cb]) { - c = buckets[cb]; - assert((c->mmInfo&63)==cb); - buckets[cb] = c->next; - break; - } - if (cb >= 20) { - c = mmap(NULL, BSZ(cb), PROT_READ|PROT_WRITE, MAP_NORESERVE|MAP_PRIVATE|MAP_ANON, -1, 0); - if (c==MAP_FAILED) { - printf("failed to allocate memory\n"); - exit(1); - } - c->type = t_empty; - c->mmInfo = cb; - c->next = 0; - break; - } - } - c->mmInfo = bucket; - while (cb != bucket) { - cb--; - EmptyValue* b = (EmptyValue*) (BSZ(cb) + (char*)c); - b->type = t_empty; - b->mmInfo = cb; - b->next = 0; assert(buckets[cb]==0); - buckets[cb] = b; - } - return c; -} - -void mm_free(Value* x) { - onFree(x); - EmptyValue* c = (EmptyValue*) x; - c->type = t_empty; - u8 b = c->mmInfo&63; - c->next = buckets[b]; - buckets[b] = c; -} - -void* mm_allocN(usz sz, u8 type) { - assert(sz>8); - u8 bucket = BSZI(sz); // inverse of BSZ - EmptyValue* x = buckets[bucket]; - if (x==NULL) x = makeEmpty(bucket); - else buckets[bucket] = x->next; - onAlloc(sz, type); - x->flags = x->extra = x->type = 0; - x->refc = 1; - x->type = type; - return x; -} +#define BSZI BSZI2 +#define MMI(x) x u64 mm_round(usz sz) { return BSZ(BSZI(sz)); @@ -80,3 +22,11 @@ u64 mm_round(usz sz) { void mm_visit(B x) { } + +#include "mm_buddyTemplate.c" + +void* mm_allocN(usz sz, u8 type) { + assert(sz>8); + onAlloc(sz, type); + return mm_allocL(BSZI2(sz), type); +} diff --git a/src/mm_buddyTemplate.c b/src/mm_buddyTemplate.c new file mode 100644 index 00000000..9515d675 --- /dev/null +++ b/src/mm_buddyTemplate.c @@ -0,0 +1,60 @@ +EmptyValue* buckets[64]; + +static EmptyValue* mm_makeEmpty(u8 bucket) { // result->next is garbage + u8 cb = bucket; + EmptyValue* c; + while (true) { + cb++; + if (buckets[cb]) { + c = buckets[cb]; + assert((c->mmInfo&63)==cb); + buckets[cb] = c->next; + break; + } + if (cb >= 20) { + u64 sz = BSZ(cb); + c = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_NORESERVE|MAP_PRIVATE|MAP_ANON, -1, 0); + if (c==MAP_FAILED) { + printf("failed to allocate memory\n"); + exit(1); + } + c->type = t_empty; + c->mmInfo = cb; + c->next = 0; + break; + } + } + c->mmInfo = MMI(bucket); + while (cb != bucket) { + cb--; + EmptyValue* b = (EmptyValue*) (BSZ(cb) + (char*)c); + b->type = t_empty; + b->mmInfo = MMI(cb); + b->next = 0; assert(buckets[cb]==0); + buckets[cb] = b; + } + return c; +} + +void mm_free(Value* x) { + onFree(x); + EmptyValue* c = (EmptyValue*) x; + c->type = t_empty; + u8 b = c->mmInfo&63; + c->next = buckets[b]; + buckets[b] = c; +} + +void* mm_allocL(u8 bucket, u8 type) { + EmptyValue* x = buckets[bucket]; + if (x==NULL) x = mm_makeEmpty(bucket); + else buckets[bucket] = x->next; + x->flags = x->extra = x->type = 0; + x->refc = 1; + x->type = type; + return x; +} + +#undef BSZ +#undef BSZI +#undef MMI