78 lines
1.8 KiB
C
78 lines
1.8 KiB
C
#include <string.h>
|
|
typedef struct {
|
|
unsigned int size;
|
|
unsigned int current;
|
|
unsigned char data[1];
|
|
} heapPart;
|
|
typedef struct {
|
|
heapPart *primary;
|
|
heapPart *secondary;
|
|
unsigned int size;
|
|
unsigned int current;
|
|
} heap;
|
|
|
|
void scan(heap *h) {
|
|
heapPart *part = h->primary;
|
|
unsigned int i;
|
|
for (i = 0; i < h->current; i++) {
|
|
unsigned int j;
|
|
for (j = 0; j < part->current; j++) {
|
|
void *p = *(void **) (part->data + j);
|
|
if (p >= part->data && p < part->data + part->size) {
|
|
*(void **) (part->data + j) = h->secondary + h->current;
|
|
memcpy(h->secondary + h->current, p, sizeof(void *));
|
|
h->current++;
|
|
}
|
|
}
|
|
part++;
|
|
}
|
|
}
|
|
|
|
void collect(heap *h) {
|
|
scan(h);
|
|
heapPart *tmp = h->primary;
|
|
h->primary = h->secondary;
|
|
h->secondary = tmp;
|
|
h->current = 0;
|
|
}
|
|
|
|
void *alloc(heap *h, unsigned int size) {
|
|
if (h->current == h->size) {
|
|
collect(h);
|
|
}
|
|
heapPart *part = h->primary + h->current;
|
|
if (part->current + size > part->size) {
|
|
collect(h);
|
|
part = h->primary + h->current;
|
|
}
|
|
void *p = part->data + part->current;
|
|
part->current += size;
|
|
return p;
|
|
}
|
|
|
|
void *reallocate(heap *h, void *p, unsigned int size) {
|
|
if (p == NULL) {
|
|
return alloc(h, size);
|
|
}
|
|
heapPart *part = h->primary;
|
|
unsigned int i;
|
|
for (i = 0; i < h->current; i++) {
|
|
if (p >= part->data && p < part->data + part->size) {
|
|
break;
|
|
}
|
|
part++;
|
|
}
|
|
if (i == h->current) {
|
|
return NULL;
|
|
}
|
|
if (size <= part->size) {
|
|
return p;
|
|
}
|
|
void *newP = alloc(h, size);
|
|
if (newP == NULL) {
|
|
return NULL;
|
|
}
|
|
memcpy(newP, p, part->size);
|
|
return newP;
|
|
}
|