Add arena_realloc_tail()
This commit is contained in:
@@ -6,12 +6,14 @@
|
|||||||
|
|
||||||
typedef struct arena {
|
typedef struct arena {
|
||||||
void *begin,
|
void *begin,
|
||||||
*next;
|
*next,
|
||||||
|
*prev;
|
||||||
size_t cap;
|
size_t cap;
|
||||||
} __attribute__((aligned(sizeof(void*)))) arena_t;
|
} __attribute__((aligned(sizeof(void*)))) arena_t;
|
||||||
|
|
||||||
arena_t* arena_new();
|
arena_t* arena_new();
|
||||||
void arena_reset(arena_t* a);
|
void arena_reset(arena_t* a);
|
||||||
void* arena_alloc(arena_t* a, size_t len);
|
void* arena_alloc(arena_t* a, size_t len);
|
||||||
|
void* arena_realloc_tail(arena_t* a, size_t len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
36
src/arena.c
36
src/arena.c
@@ -23,13 +23,13 @@ struct arena* arena_new()
|
|||||||
|
|
||||||
arena_t* a = (arena_t*)p;
|
arena_t* a = (arena_t*)p;
|
||||||
|
|
||||||
*a = (arena_t) {
|
void* beg = p + sizeof(struct arena);
|
||||||
.begin = p + sizeof(struct arena),
|
a->begin = beg;
|
||||||
.next = p + sizeof(struct arena),
|
a->next = beg;
|
||||||
.cap = size - sizeof(struct arena)
|
a->prev = beg;
|
||||||
};
|
a->cap = size - sizeof(struct arena);
|
||||||
|
|
||||||
return (arena_t*)a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -38,6 +38,7 @@ struct arena* arena_new()
|
|||||||
void arena_reset(struct arena* a)
|
void arena_reset(struct arena* a)
|
||||||
{
|
{
|
||||||
a->next = a->begin;
|
a->next = a->begin;
|
||||||
|
a->prev = a->begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -46,12 +47,31 @@ void arena_reset(struct arena* a)
|
|||||||
void* arena_alloc(struct arena* a, size_t len)
|
void* arena_alloc(struct arena* a, size_t len)
|
||||||
{
|
{
|
||||||
void* p = a->next;
|
void* p = a->next;
|
||||||
a->next = (byte*)(a->next) + len;
|
|
||||||
|
|
||||||
if ((byte*)(a->next) > (byte*)(a->begin) + a->cap) {
|
if ((byte*)p + len > (byte*)(a->begin) + a->cap) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a->next = (byte*)(a->next) + len;
|
||||||
|
a->prev = p;
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reallocate last block in arena
|
||||||
|
*/
|
||||||
|
void* arena_realloc_tail(struct arena* a, size_t len)
|
||||||
|
{
|
||||||
|
void* p = a->prev;
|
||||||
|
|
||||||
|
if ((byte*)p + len > (byte*)(a->begin) + a->cap) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
a->next = (byte*)p + len;
|
||||||
|
|
||||||
|
return a->prev;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user