buddy memory allocator
This commit is contained in:
parent
b33335c921
commit
9136d6000d
2
asmBuild
2
asmBuild
@ -1,2 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
clang -std=c11 -Wall -Wno-microsoft-anon-tag -fms-extensions -O3 -masm=intel -S src/main.c
|
|
||||||
2
build
2
build
@ -1,2 +1,2 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
clang -std=c11 -O3 -Wall -Wno-microsoft-anon-tag -fms-extensions -o BQN -lm src/main.c
|
clang -std=gnu11 -O3 -Wall -Wno-microsoft-anon-tag -fms-extensions -o BQN -lm src/main.c
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
clang -DDEBUG -std=c11 -g -Wall -Wno-microsoft-anon-tag -fms-extensions -o BQN -lm src/main.c
|
clang -DDEBUG -std=gnu11 -g -Wall -Wno-microsoft-anon-tag -fms-extensions -o BQN -lm src/main.c
|
||||||
|
|||||||
36
src/h.h
36
src/h.h
@ -116,10 +116,13 @@ typedef struct Arr {
|
|||||||
} Arr;
|
} Arr;
|
||||||
|
|
||||||
// memory manager
|
// memory manager
|
||||||
B mm_alloc (usz sz, u8 type, u64 tag);
|
|
||||||
void* mm_allocN(usz sz, u8 type);
|
void* mm_allocN(usz sz, u8 type);
|
||||||
void mm_free(Value* x);
|
void mm_free(Value* x);
|
||||||
void mm_visit(B x);
|
void mm_visit(B x);
|
||||||
|
B mm_alloc(usz sz, u8 type, u64 tag) {
|
||||||
|
assert(tag>1LL<<16 || tag==0); // make sure it's `ftag`ged :|
|
||||||
|
return b((u64)mm_allocN(sz,type) | tag);
|
||||||
|
}
|
||||||
|
|
||||||
// some primitive actions
|
// some primitive actions
|
||||||
void dec(B x);
|
void dec(B x);
|
||||||
@ -474,3 +477,34 @@ void arr_print(B x) {
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ALLOC_STAT
|
||||||
|
u64* ctr_a = 0;
|
||||||
|
u64* ctr_f = 0;
|
||||||
|
u64 actrc = 21000;
|
||||||
|
u64 talloc = 0;
|
||||||
|
u32** actrs;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void onAlloc(usz sz, u8 type) {
|
||||||
|
#ifdef ALLOC_STAT
|
||||||
|
if (!actrs) {
|
||||||
|
actrs = malloc(sizeof(u32*)*actrc);
|
||||||
|
ctr_a = calloc(Type_MAX, sizeof(u64));
|
||||||
|
ctr_f = calloc(Type_MAX, sizeof(u64));
|
||||||
|
for (i32 i = 0; i < actrc; i++) actrs[i] = calloc(Type_MAX, sizeof(u32));
|
||||||
|
}
|
||||||
|
assert(type<Type_MAX);
|
||||||
|
actrs[(sz+3)/4>=actrc? actrc-1 : (sz+3)/4][type]++;
|
||||||
|
ctr_a[type]++;
|
||||||
|
talloc+= sz;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void onFree(Value* x) {
|
||||||
|
#ifdef ALLOC_STAT
|
||||||
|
ctr_f[x->type]++;
|
||||||
|
#endif
|
||||||
|
#ifdef DEBUG
|
||||||
|
x->refc = 0x61616161;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@ -8,7 +8,7 @@
|
|||||||
#define FAKE_RUNTIME false
|
#define FAKE_RUNTIME false
|
||||||
|
|
||||||
#include "h.h"
|
#include "h.h"
|
||||||
#include "mm.c"
|
#include "mm_buddy.c"
|
||||||
#include "harr.c"
|
#include "harr.c"
|
||||||
#include "i32arr.c"
|
#include "i32arr.c"
|
||||||
#include "utf.c"
|
#include "utf.c"
|
||||||
|
|||||||
52
src/mm.c
52
src/mm.c
@ -1,52 +0,0 @@
|
|||||||
#include "h.h"
|
|
||||||
#include<stdlib.h>
|
|
||||||
|
|
||||||
#ifdef ALLOC_STAT
|
|
||||||
u64* ctr_a = 0;
|
|
||||||
u64* ctr_f = 0;
|
|
||||||
u64 actrc = 21000;
|
|
||||||
u64 talloc = 0;
|
|
||||||
u32** actrs;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void* aalloc(usz sz) { // actual allocate
|
|
||||||
void* p = malloc(sz);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
void mm_free(Value* x) {
|
|
||||||
#ifdef ALLOC_STAT
|
|
||||||
ctr_f[x->type]++;
|
|
||||||
x->refc = 0x61616161;
|
|
||||||
#endif
|
|
||||||
free(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void* mm_allocN(usz sz, u8 type) {
|
|
||||||
Value* x = aalloc(sz);
|
|
||||||
#ifdef ALLOC_STAT
|
|
||||||
if (!actrs) {
|
|
||||||
actrs = malloc(sizeof(u32*)*actrc);
|
|
||||||
ctr_a = calloc(Type_MAX, sizeof(u64));
|
|
||||||
ctr_f = calloc(Type_MAX, sizeof(u64));
|
|
||||||
for (i32 i = 0; i < actrc; i++) actrs[i] = calloc(Type_MAX, sizeof(u32));
|
|
||||||
}
|
|
||||||
assert(type<Type_MAX);
|
|
||||||
actrs[(sz+3)/4>=actrc? actrc-1 : (sz+3)/4][type]++;
|
|
||||||
ctr_a[type]++;
|
|
||||||
talloc+= sz;
|
|
||||||
#endif
|
|
||||||
#ifdef DEBUG
|
|
||||||
memset(x, 'a', sz);
|
|
||||||
#endif
|
|
||||||
x->flags = x->extra = x->mmInfo = x->type = 0;
|
|
||||||
x->refc = 1;
|
|
||||||
x->type = type;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
B mm_alloc(usz sz, u8 type, u64 tag) {
|
|
||||||
assert(tag>1LL<<16); // make sure it's `ftag`ged :|
|
|
||||||
return b((u64)mm_allocN(sz,type) | tag);
|
|
||||||
}
|
|
||||||
void mm_visit(B x) {
|
|
||||||
|
|
||||||
}
|
|
||||||
77
src/mm_buddy.c
Normal file
77
src/mm_buddy.c
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#include "h.h"
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
};
|
||||||
|
|
||||||
|
EmptyValue* buckets[64];
|
||||||
|
|
||||||
|
#define BSZ(x) (1ull<<(x))
|
||||||
|
|
||||||
|
EmptyValue* makeBucket(u8 bucket) { // next field of output 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (cb != bucket) {
|
||||||
|
cb--;
|
||||||
|
EmptyValue* b = (EmptyValue*) (((char*)c)+BSZ(cb));
|
||||||
|
b->type = t_empty;
|
||||||
|
b->mmInfo = cb;
|
||||||
|
b->next = 0; assert(buckets[cb]==0);
|
||||||
|
buckets[cb] = b;
|
||||||
|
}
|
||||||
|
c->mmInfo = bucket;
|
||||||
|
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 = 64-__builtin_clzl(sz-1ull); // inverse of BSZ
|
||||||
|
EmptyValue* x = buckets[bucket];
|
||||||
|
if (x==NULL) x = makeBucket(bucket);
|
||||||
|
else buckets[bucket] = x->next;
|
||||||
|
onAlloc(sz, type);
|
||||||
|
x->flags = x->extra = x->type = 0;
|
||||||
|
x->refc = 1;
|
||||||
|
x->type = type;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mm_visit(B x) {
|
||||||
|
|
||||||
|
}
|
||||||
19
src/mm_malloc.c
Normal file
19
src/mm_malloc.c
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include "h.h"
|
||||||
|
#include<stdlib.h>
|
||||||
|
|
||||||
|
void mm_free(Value* x) {
|
||||||
|
onFree(x);
|
||||||
|
free(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* mm_allocN(usz sz, u8 type) {
|
||||||
|
Value* x = malloc(sz);
|
||||||
|
onAlloc(sz, type);
|
||||||
|
x->flags = x->extra = x->mmInfo = x->type = 0;
|
||||||
|
x->refc = 1;
|
||||||
|
x->type = type;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
void mm_visit(B x) {
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user