never return if h_arena_malloc fails, call errx() or longjmp()
This commit is contained in:
parent
d5e79aa4cb
commit
9ef70f2f2d
2 changed files with 26 additions and 10 deletions
|
|
@ -18,6 +18,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
#include "hammer.h"
|
#include "hammer.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
@ -42,6 +43,8 @@ struct HArena_ {
|
||||||
size_t block_size;
|
size_t block_size;
|
||||||
size_t used;
|
size_t used;
|
||||||
size_t wasted;
|
size_t wasted;
|
||||||
|
|
||||||
|
jmp_buf *except;
|
||||||
};
|
};
|
||||||
|
|
||||||
HArena *h_new_arena(HAllocator* mm__, size_t block_size) {
|
HArena *h_new_arena(HAllocator* mm__, size_t block_size) {
|
||||||
|
|
@ -62,9 +65,26 @@ HArena *h_new_arena(HAllocator* mm__, size_t block_size) {
|
||||||
ret->used = 0;
|
ret->used = 0;
|
||||||
ret->mm__ = mm__;
|
ret->mm__ = mm__;
|
||||||
ret->wasted = sizeof(struct arena_link) + sizeof(struct HArena_) + block_size;
|
ret->wasted = sizeof(struct arena_link) + sizeof(struct HArena_) + block_size;
|
||||||
|
ret->except = NULL;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void h_arena_set_except(HArena *arena, jmp_buf *except)
|
||||||
|
{
|
||||||
|
arena->except = except;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *alloc_block(HArena *arena, size_t size)
|
||||||
|
{
|
||||||
|
void *block = arena->mm__->alloc(arena->mm__, size);
|
||||||
|
if (!block) {
|
||||||
|
if (arena->except)
|
||||||
|
longjmp(*arena->except, 1);
|
||||||
|
h_platform_errx(1, "memory allocation failed (%uB requested)\n", (unsigned int)size);
|
||||||
|
}
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
void* h_arena_malloc(HArena *arena, size_t size) {
|
void* h_arena_malloc(HArena *arena, size_t size) {
|
||||||
if (size <= arena->head->free) {
|
if (size <= arena->head->free) {
|
||||||
// fast path..
|
// fast path..
|
||||||
|
|
@ -79,22 +99,16 @@ void* h_arena_malloc(HArena *arena, size_t size) {
|
||||||
// This involves some annoying casting...
|
// This involves some annoying casting...
|
||||||
arena->used += size;
|
arena->used += size;
|
||||||
arena->wasted += sizeof(struct arena_link*);
|
arena->wasted += sizeof(struct arena_link*);
|
||||||
void* link = arena->mm__->alloc(arena->mm__, size + sizeof(struct arena_link*));
|
void* link = alloc_block(arena, size + sizeof(struct arena_link*));
|
||||||
if (!link) {
|
assert(link != NULL);
|
||||||
// TODO: error-reporting -- let user know that arena link couldn't be allocated
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
memset(link, 0, size + sizeof(struct arena_link*));
|
memset(link, 0, size + sizeof(struct arena_link*));
|
||||||
*(struct arena_link**)link = arena->head->next;
|
*(struct arena_link**)link = arena->head->next;
|
||||||
arena->head->next = (struct arena_link*)link;
|
arena->head->next = (struct arena_link*)link;
|
||||||
return (void*)(((uint8_t*)link) + sizeof(struct arena_link*));
|
return (void*)(((uint8_t*)link) + sizeof(struct arena_link*));
|
||||||
} else {
|
} else {
|
||||||
// we just need to allocate an ordinary new block.
|
// we just need to allocate an ordinary new block.
|
||||||
struct arena_link *link = (struct arena_link*)arena->mm__->alloc(arena->mm__, sizeof(struct arena_link) + arena->block_size);
|
struct arena_link *link = alloc_block(arena, sizeof(struct arena_link) + arena->block_size);
|
||||||
if (!link) {
|
assert(link != NULL);
|
||||||
// TODO: error-reporting -- let user know that arena link couldn't be allocated
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
memset(link, 0, sizeof(struct arena_link) + arena->block_size);
|
memset(link, 0, sizeof(struct arena_link) + arena->block_size);
|
||||||
link->free = arena->block_size - size;
|
link->free = arena->block_size - size;
|
||||||
link->used = size;
|
link->used = size;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
#ifndef HAMMER_ALLOCATOR__H__
|
#ifndef HAMMER_ALLOCATOR__H__
|
||||||
#define HAMMER_ALLOCATOR__H__
|
#define HAMMER_ALLOCATOR__H__
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
@ -51,6 +52,7 @@ HArena *h_new_arena(HAllocator* allocator, size_t block_size); // pass 0 for def
|
||||||
void* h_arena_malloc(HArena *arena, size_t count) ATTR_MALLOC(2);
|
void* h_arena_malloc(HArena *arena, size_t count) ATTR_MALLOC(2);
|
||||||
void h_arena_free(HArena *arena, void* ptr); // For future expansion, with alternate memory managers.
|
void h_arena_free(HArena *arena, void* ptr); // For future expansion, with alternate memory managers.
|
||||||
void h_delete_arena(HArena *arena);
|
void h_delete_arena(HArena *arena);
|
||||||
|
void h_arena_set_except(HArena *arena, jmp_buf *except);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t used;
|
size_t used;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue