#include #include #include #include #include "ucore/salloc.h" typedef struct Chunk Chunk; struct Chunk { Chunk *next; size_t firstfree; //index to the first free byte in this chunk union data { //for alignment long long ll; void *p; double d; size_t sz; int i; char data[1]; } data; }; struct SAlloc { size_t chunksz; //data size of each chunk Chunk *first; //head of the chunk list Chunk *current; }; static Chunk * add_chunk(SAlloc *p) { Chunk *newchunk; newchunk = malloc(sizeof *newchunk + p->chunksz - (sizeof *newchunk - offsetof(Chunk, data.data))); if (newchunk == NULL) return NULL; if (p->current != NULL) p->current->next = newchunk; newchunk->next = NULL; newchunk->firstfree = 0; return newchunk; } static Chunk * next_chunk(SAlloc *p) { Chunk *newchunk; if (p->current->next) { newchunk = p->current->next; newchunk->firstfree = 0; } else newchunk = add_chunk(p); if (newchunk) p->current = newchunk; return newchunk; } SAlloc * uc_new_salloc(size_t chunksz) { SAlloc *p; Chunk *first; p = malloc(sizeof *p); if (p == NULL) return NULL; p->chunksz = chunksz; p->current = NULL; if ((first = add_chunk(p)) == NULL) { free(p); return NULL; } p->first = p->current = first; return p; } void uc_reset_salloc(SAlloc *p) { Chunk *tmp; for(tmp = p->first; tmp; tmp = tmp->next) tmp->firstfree = 0; p->current = p->first; } void * uc_s_alloc(SAlloc *p,size_t sz) { Chunk *chunk; void *newmem; chunk = p->current; if (chunk->firstfree + sz > p->chunksz) { if (sz > p->chunksz) return NULL; chunk = next_chunk(p); if (chunk == NULL) return NULL; } newmem = &chunk->data.data[chunk->firstfree]; chunk->firstfree += sz; return newmem; } void * uc_s_allocz(SAlloc *p,size_t sz) { void *newmem = uc_s_alloc(p, sz); if (newmem != NULL) memset(newmem, 0, sz); return newmem; } static void free_chunks(Chunk *chunk) { Chunk *next; for (next = NULL; chunk != NULL; chunk = next) { next = chunk->next; free(chunk); } } void uc_free_salloc(SAlloc *p) { free_chunks(p->first); free(p); }