/*
Copyright (c) 2007-2013, John Ryland
*/
// malloc implementation
int index(int size)
{
int b = 0;
if (!size)
return 0;
size--;
while (size) {
size >>= 1;
b++;
}
return b;
}
unsigned *free_lists[32] = {0,0,...};
void *malloc(int size)
{
int free_list_idx = index(size + 4);
size = 1 << free_list_idx;
unsigned *mem = free_lists[free_list_idx];
if (!mem) {
int next_free_index = free_list_idx;
while (!mem && next_free_index != 32) {
mem = free_lists[next_free_index];
next_free_index++;
}
if (!mem) {
// mem = ... // need mem from OS
} else {
free_lists[next_free_index] = (unsigned *)*mem;
next_free_index--;
}
while (next_free_index >= 3) {
size = 1 << next_free_index;
mem[size >> 2] = 0;
free_lists[next_free_index] = &mem[size >> 2];
next_free_index--;
}
mem = free_lists[free_list_idx];
}
free_lists[free_list_idx] = (unsigned *)*mem;
*mem = free_list_idx;
return (void *)(mem + 1);
}
void free(void *mem)
{
unsigned *m = mem;
m = m - 1;
unsigned index = *m;
*m = (unsigned)free_lists[index];
free_lists[index] = m;
}
// ref counting
// Not very efficient atomic
#define ATOMIC(x) \
{\
init_mutex();\
x\
done_mutex();\
}
#define COPY(p,q) \
if (q) \
ATOMIC(++(q->refcount);) \
if (p) { \
size_t new_count; \
ATOMIC(new_count = --(p->refcount);) \
if (!new_count) \
free(p); \
} \
p = q;