commit
cfef13b436
7 changed files with 95 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
*.o
|
||||||
|
*~
|
||||||
2
config.mk
Normal file
2
config.mk
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
CFLAGS := $(shell pkg-config --cflags glib-2.0)
|
||||||
|
LDFLAGS := $(shell pkg-config --libs glib-2.0)
|
||||||
6
lib/Makefile
Normal file
6
lib/Makefile
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
include ../config.mk
|
||||||
|
|
||||||
|
all: allocator.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
gcc $(CFLAGS) -c -o $@ $^
|
||||||
73
lib/allocator.c
Normal file
73
lib/allocator.c
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
#include <glib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "allocator.h"
|
||||||
|
|
||||||
|
struct arena_link {
|
||||||
|
// TODO:
|
||||||
|
// For efficiency, we should probably allocate the arena links in
|
||||||
|
// their own slice, and link to a block directly. That can be
|
||||||
|
// implemented later, though, with no change in interface.
|
||||||
|
struct arena_link *next; // It is crucial that this be the first item; so that
|
||||||
|
// any arena link can be casted to struct arena_link**.
|
||||||
|
|
||||||
|
size_t free;
|
||||||
|
size_t used;
|
||||||
|
uint8_t rest[];
|
||||||
|
} ;
|
||||||
|
|
||||||
|
struct arena {
|
||||||
|
struct arena_link *head;
|
||||||
|
size_t block_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
arena_t new_arena(size_t block_size) {
|
||||||
|
struct arena *ret = g_new(struct arena, 1);
|
||||||
|
struct arena_link *link = (struct arena_link*)g_malloc0(sizeof(struct arena_link) + block_size);
|
||||||
|
link->free = block_size;
|
||||||
|
link->used = 0;
|
||||||
|
link->next = NULL;
|
||||||
|
ret->head = link;
|
||||||
|
ret->block_size = 0;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* arena_malloc(arena_t arena, size_t size) {
|
||||||
|
if (size <= arena->head->free) {
|
||||||
|
// fast path..
|
||||||
|
void* ret = arena->head->rest + arena->head->used;
|
||||||
|
arena->head->used += size;
|
||||||
|
arena->head->free -= size;
|
||||||
|
return ret;
|
||||||
|
} else if (size > arena->block_size) {
|
||||||
|
// We need a new, dedicated block for it, because it won't fit in a standard sized one.
|
||||||
|
// This involves some annoying casting...
|
||||||
|
void* link = g_malloc(size + sizeof(struct arena_link*));
|
||||||
|
*(struct arena_link**)link = arena->head->next;
|
||||||
|
arena->head->next = (struct arena_link*)link;
|
||||||
|
return (void*)((uint8_t*)link + sizeof(struct arena_link*));
|
||||||
|
} else {
|
||||||
|
// we just need to allocate an ordinary new block.
|
||||||
|
struct arena_link *link = (struct arena_link*)g_malloc0(sizeof(struct arena_link) + arena->block_size);
|
||||||
|
link->free = arena->block_size - size;
|
||||||
|
link->used = size;
|
||||||
|
link->next = arena->head;
|
||||||
|
arena->head = link;
|
||||||
|
return link->rest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_arena(arena_t arena) {
|
||||||
|
struct arena_link *link = arena->head;
|
||||||
|
while (link) {
|
||||||
|
struct arena_link *next = link->next;
|
||||||
|
// Even in the case of a special block, without the full arena
|
||||||
|
// header, this is correct, because the next pointer is the first
|
||||||
|
// in the structure.
|
||||||
|
g_free(link);
|
||||||
|
link = next;
|
||||||
|
}
|
||||||
|
g_free(arena);
|
||||||
|
}
|
||||||
12
lib/allocator.h
Normal file
12
lib/allocator.h
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef LIB_ALLOCATOR__H__
|
||||||
|
#define LIB_ALLOCATOR__H__
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
typedef struct arena* arena_t; // hidden implementation
|
||||||
|
|
||||||
|
arena_t new_arena(size_t block_size); // pass 0 for default...
|
||||||
|
void* arena_malloc(arena_t arena, size_t count); // TODO: needs the malloc attribute
|
||||||
|
void delete_arena(arena_t arena);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // #ifndef LIB_ALLOCATOR__H__
|
||||||
Loading…
Add table
Add a link
Reference in a new issue