summaryrefslogtreecommitdiff
path: root/upb/env.c
diff options
context:
space:
mode:
Diffstat (limited to 'upb/env.c')
-rw-r--r--upb/env.c273
1 files changed, 0 insertions, 273 deletions
diff --git a/upb/env.c b/upb/env.c
deleted file mode 100644
index 973472e..0000000
--- a/upb/env.c
+++ /dev/null
@@ -1,273 +0,0 @@
-
-#include "upb/env.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-typedef struct cleanup_ent {
- upb_cleanup_func *cleanup;
- void *ud;
- struct cleanup_ent *next;
-} cleanup_ent;
-
-static void *seeded_alloc(void *ud, void *ptr, size_t oldsize, size_t size);
-
-/* Default allocator **********************************************************/
-
-/* Just use realloc, keeping all allocated blocks in a linked list to destroy at
- * the end. */
-
-typedef struct mem_block {
- /* List is doubly-linked, because in cases where realloc() moves an existing
- * block, we need to be able to remove the old pointer from the list
- * efficiently. */
- struct mem_block *prev, *next;
-#ifndef NDEBUG
- size_t size; /* Doesn't include mem_block structure. */
-#endif
-} mem_block;
-
-typedef struct {
- mem_block *head;
-} default_alloc_ud;
-
-static void *default_alloc(void *_ud, void *ptr, size_t oldsize, size_t size) {
- default_alloc_ud *ud = _ud;
- mem_block *from, *block;
- void *ret;
- UPB_UNUSED(oldsize);
-
- from = ptr ? (void*)((char*)ptr - sizeof(mem_block)) : NULL;
-
-#ifndef NDEBUG
- if (from) {
- assert(oldsize <= from->size);
- }
-#endif
-
- /* TODO(haberman): we probably need to provide even better alignment here,
- * like 16-byte alignment of the returned data pointer. */
- block = realloc(from, size + sizeof(mem_block));
- if (!block) return NULL;
- ret = (char*)block + sizeof(*block);
-
-#ifndef NDEBUG
- block->size = size;
-#endif
-
- if (from) {
- if (block != from) {
- /* The block was moved, so pointers in next and prev blocks must be
- * updated to its new location. */
- if (block->next) block->next->prev = block;
- if (block->prev) block->prev->next = block;
- if (ud->head == from) ud->head = block;
- }
- } else {
- /* Insert at head of linked list. */
- block->prev = NULL;
- block->next = ud->head;
- if (block->next) block->next->prev = block;
- ud->head = block;
- }
-
- return ret;
-}
-
-static void default_alloc_cleanup(void *_ud) {
- default_alloc_ud *ud = _ud;
- mem_block *block = ud->head;
-
- while (block) {
- void *to_free = block;
- block = block->next;
- free(to_free);
- }
-}
-
-
-/* Standard error functions ***************************************************/
-
-static bool default_err(void *ud, const upb_status *status) {
- UPB_UNUSED(ud);
- UPB_UNUSED(status);
- return false;
-}
-
-static bool write_err_to(void *ud, const upb_status *status) {
- upb_status *copy_to = ud;
- upb_status_copy(copy_to, status);
- return false;
-}
-
-
-/* upb_env ********************************************************************/
-
-void upb_env_init(upb_env *e) {
- default_alloc_ud *ud = (default_alloc_ud*)&e->default_alloc_ud;
- e->ok_ = true;
- e->bytes_allocated = 0;
- e->cleanup_head = NULL;
-
- ud->head = NULL;
-
- /* Set default functions. */
- upb_env_setallocfunc(e, default_alloc, ud);
- upb_env_seterrorfunc(e, default_err, NULL);
-}
-
-void upb_env_uninit(upb_env *e) {
- cleanup_ent *ent = e->cleanup_head;
-
- while (ent) {
- ent->cleanup(ent->ud);
- ent = ent->next;
- }
-
- /* Must do this after running cleanup functions, because this will delete
- the memory we store our cleanup entries in! */
- if (e->alloc == default_alloc) {
- default_alloc_cleanup(e->alloc_ud);
- }
-}
-
-UPB_FORCEINLINE void upb_env_setallocfunc(upb_env *e, upb_alloc_func *alloc,
- void *ud) {
- e->alloc = alloc;
- e->alloc_ud = ud;
-}
-
-UPB_FORCEINLINE void upb_env_seterrorfunc(upb_env *e, upb_error_func *func,
- void *ud) {
- e->err = func;
- e->err_ud = ud;
-}
-
-void upb_env_reporterrorsto(upb_env *e, upb_status *status) {
- e->err = write_err_to;
- e->err_ud = status;
-}
-
-bool upb_env_ok(const upb_env *e) {
- return e->ok_;
-}
-
-bool upb_env_reporterror(upb_env *e, const upb_status *status) {
- e->ok_ = false;
- return e->err(e->err_ud, status);
-}
-
-bool upb_env_addcleanup(upb_env *e, upb_cleanup_func *func, void *ud) {
- cleanup_ent *ent = upb_env_malloc(e, sizeof(cleanup_ent));
- if (!ent) return false;
-
- ent->cleanup = func;
- ent->ud = ud;
- ent->next = e->cleanup_head;
- e->cleanup_head = ent;
-
- return true;
-}
-
-void *upb_env_malloc(upb_env *e, size_t size) {
- e->bytes_allocated += size;
- if (e->alloc == seeded_alloc) {
- /* This is equivalent to the next branch, but allows inlining for a
- * measurable perf benefit. */
- return seeded_alloc(e->alloc_ud, NULL, 0, size);
- } else {
- return e->alloc(e->alloc_ud, NULL, 0, size);
- }
-}
-
-void *upb_env_realloc(upb_env *e, void *ptr, size_t oldsize, size_t size) {
- char *ret;
- assert(oldsize <= size);
- ret = e->alloc(e->alloc_ud, ptr, oldsize, size);
-
-#ifndef NDEBUG
- /* Overwrite non-preserved memory to ensure callers are passing the oldsize
- * that they truly require. */
- memset(ret + oldsize, 0xff, size - oldsize);
-#endif
-
- return ret;
-}
-
-size_t upb_env_bytesallocated(const upb_env *e) {
- return e->bytes_allocated;
-}
-
-
-/* upb_seededalloc ************************************************************/
-
-/* Be conservative and choose 16 in case anyone is using SSE. */
-static const size_t maxalign = 16;
-
-static size_t align_up(size_t size) {
- return ((size + maxalign - 1) / maxalign) * maxalign;
-}
-
-UPB_FORCEINLINE static void *seeded_alloc(void *ud, void *ptr, size_t oldsize,
- size_t size) {
- upb_seededalloc *a = ud;
-
- size = align_up(size);
-
- assert(a->mem_limit >= a->mem_ptr);
-
- if (oldsize == 0 && size <= (size_t)(a->mem_limit - a->mem_ptr)) {
- /* Fast path: we can satisfy from the initial allocation. */
- void *ret = a->mem_ptr;
- a->mem_ptr += size;
- return ret;
- } else {
- char *chptr = ptr;
- /* Slow path: fallback to other allocator. */
- a->need_cleanup = true;
- /* Is `ptr` part of the user-provided initial block? Don't pass it to the
- * default allocator if so; otherwise, it may try to realloc() the block. */
- if (chptr >= a->mem_base && chptr < a->mem_limit) {
- void *ret;
- assert(chptr + oldsize <= a->mem_limit);
- ret = a->alloc(a->alloc_ud, NULL, 0, size);
- if (ret) memcpy(ret, ptr, oldsize);
- return ret;
- } else {
- return a->alloc(a->alloc_ud, ptr, oldsize, size);
- }
- }
-}
-
-void upb_seededalloc_init(upb_seededalloc *a, void *mem, size_t len) {
- default_alloc_ud *ud = (default_alloc_ud*)&a->default_alloc_ud;
- a->mem_base = mem;
- a->mem_ptr = mem;
- a->mem_limit = (char*)mem + len;
- a->need_cleanup = false;
- a->returned_allocfunc = false;
-
- ud->head = NULL;
-
- upb_seededalloc_setfallbackalloc(a, default_alloc, ud);
-}
-
-void upb_seededalloc_uninit(upb_seededalloc *a) {
- if (a->alloc == default_alloc && a->need_cleanup) {
- default_alloc_cleanup(a->alloc_ud);
- }
-}
-
-UPB_FORCEINLINE void upb_seededalloc_setfallbackalloc(upb_seededalloc *a,
- upb_alloc_func *alloc,
- void *ud) {
- assert(!a->returned_allocfunc);
- a->alloc = alloc;
- a->alloc_ud = ud;
-}
-
-upb_alloc_func *upb_seededalloc_getallocfunc(upb_seededalloc *a) {
- a->returned_allocfunc = true;
- return seeded_alloc;
-}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback