ape/malloc: make malloc and free threadsafe for python

This commit is contained in:
cinap_lenrek 2013-03-11 00:55:26 +01:00
parent 48b0c10681
commit d526ee0750

View file

@ -1,6 +1,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <lock.h>
typedef unsigned int uint; typedef unsigned int uint;
enum enum
@ -24,6 +26,7 @@ typedef struct Arena Arena;
struct Arena struct Arena
{ {
Bucket *btab[MAX2SIZE]; Bucket *btab[MAX2SIZE];
Lock;
}; };
static Arena arena; static Arena arena;
@ -47,16 +50,19 @@ malloc(size_t size)
return nil; return nil;
good: good:
/* Allocate off this list */ /* Allocate off this list */
lock(&arena);
bp = arena.btab[pow]; bp = arena.btab[pow];
if(bp) { if(bp) {
arena.btab[pow] = bp->next; arena.btab[pow] = bp->next;
unlock(&arena);
if(bp->magic != 0) if(bp->magic != 0)
abort(); abort();
bp->magic = MAGIC; bp->magic = MAGIC;
return bp->data; return bp->data;
} }
size = sizeof(Bucket)+(1<<pow); size = sizeof(Bucket)+(1<<pow);
size += 7; size += 7;
size &= ~7; size &= ~7;
@ -64,8 +70,10 @@ good:
if(pow < CUTOFF) { if(pow < CUTOFF) {
n = (CUTOFF-pow)+2; n = (CUTOFF-pow)+2;
bp = sbrk(size*n); bp = sbrk(size*n);
if((int)bp < 0) if((int)bp < 0){
unlock(&arena);
return nil; return nil;
}
next = (uint)bp+size; next = (uint)bp+size;
nbp = (Bucket*)next; nbp = (Bucket*)next;
@ -80,9 +88,12 @@ good:
} }
else { else {
bp = sbrk(size); bp = sbrk(size);
if((int)bp < 0) if((int)bp < 0){
unlock(&arena);
return nil; return nil;
}
} }
unlock(&arena);
bp->size = pow; bp->size = pow;
bp->magic = MAGIC; bp->magic = MAGIC;
@ -106,8 +117,10 @@ free(void *ptr)
bp->magic = 0; bp->magic = 0;
l = &arena.btab[bp->size]; l = &arena.btab[bp->size];
lock(&arena);
bp->next = *l; bp->next = *l;
*l = bp; *l = bp;
unlock(&arena);
} }
void* void*