Index: source/libvpx/third_party/nestegg/halloc/src/halloc.c |
=================================================================== |
--- source/libvpx/third_party/nestegg/halloc/src/halloc.c (revision 278778) |
+++ source/libvpx/third_party/nestegg/halloc/src/halloc.c (working copy) |
@@ -1,254 +0,0 @@ |
-/* |
- * Copyright (c) 2004i-2010 Alex Pankratov. All rights reserved. |
- * |
- * Hierarchical memory allocator, 1.2.1 |
- * http://swapped.cc/halloc |
- */ |
- |
-/* |
- * The program is distributed under terms of BSD license. |
- * You can obtain the copy of the license by visiting: |
- * |
- * http://www.opensource.org/licenses/bsd-license.php |
- */ |
- |
-#include <stdlib.h> /* realloc */ |
-#include <string.h> /* memset & co */ |
- |
-#include "third_party/nestegg/halloc/halloc.h" |
-#include "align.h" |
-#include "hlist.h" |
- |
-/* |
- * block control header |
- */ |
-typedef struct hblock |
-{ |
-#ifndef NDEBUG |
-#define HH_MAGIC 0x20040518L |
- long magic; |
-#endif |
- hlist_item_t siblings; /* 2 pointers */ |
- hlist_head_t children; /* 1 pointer */ |
- max_align_t data[1]; /* not allocated, see below */ |
- |
-} hblock_t; |
- |
-#define sizeof_hblock offsetof(hblock_t, data) |
- |
-/* |
- * |
- */ |
-realloc_t halloc_allocator = NULL; |
- |
-#define allocator halloc_allocator |
- |
-/* |
- * static methods |
- */ |
-static void _set_allocator(void); |
-static void * _realloc(void * ptr, size_t n); |
- |
-static int _relate(hblock_t * b, hblock_t * p); |
-static void _free_children(hblock_t * p); |
- |
-/* |
- * Core API |
- */ |
-void * halloc(void * ptr, size_t len) |
-{ |
- hblock_t * p; |
- |
- /* set up default allocator */ |
- if (! allocator) |
- { |
- _set_allocator(); |
- assert(allocator); |
- } |
- |
- /* calloc */ |
- if (! ptr) |
- { |
- if (! len) |
- return NULL; |
- |
- p = allocator(0, len + sizeof_hblock); |
- if (! p) |
- return NULL; |
-#ifndef NDEBUG |
- p->magic = HH_MAGIC; |
-#endif |
- hlist_init(&p->children); |
- hlist_init_item(&p->siblings); |
- |
- return p->data; |
- } |
- |
- p = structof(ptr, hblock_t, data); |
- assert(p->magic == HH_MAGIC); |
- |
- /* realloc */ |
- if (len) |
- { |
- p = allocator(p, len + sizeof_hblock); |
- if (! p) |
- return NULL; |
- |
- hlist_relink(&p->siblings); |
- hlist_relink_head(&p->children); |
- |
- return p->data; |
- } |
- |
- /* free */ |
- _free_children(p); |
- hlist_del(&p->siblings); |
- allocator(p, 0); |
- |
- return NULL; |
-} |
- |
-void hattach(void * block, void * parent) |
-{ |
- hblock_t * b, * p; |
- |
- if (! block) |
- { |
- assert(! parent); |
- return; |
- } |
- |
- /* detach */ |
- b = structof(block, hblock_t, data); |
- assert(b->magic == HH_MAGIC); |
- |
- hlist_del(&b->siblings); |
- |
- if (! parent) |
- return; |
- |
- /* attach */ |
- p = structof(parent, hblock_t, data); |
- assert(p->magic == HH_MAGIC); |
- |
- /* sanity checks */ |
- assert(b != p); /* trivial */ |
- assert(! _relate(p, b)); /* heavy ! */ |
- |
- hlist_add(&p->children, &b->siblings); |
-} |
- |
-/* |
- * malloc/free api |
- */ |
-void * h_malloc(size_t len) |
-{ |
- return halloc(0, len); |
-} |
- |
-void * h_calloc(size_t n, size_t len) |
-{ |
- void * ptr = halloc(0, len*=n); |
- return ptr ? memset(ptr, 0, len) : NULL; |
-} |
- |
-void * h_realloc(void * ptr, size_t len) |
-{ |
- return halloc(ptr, len); |
-} |
- |
-void h_free(void * ptr) |
-{ |
- halloc(ptr, 0); |
-} |
- |
-char * h_strdup(const char * str) |
-{ |
- size_t len = strlen(str); |
- char * ptr = halloc(0, len + 1); |
- return ptr ? (ptr[len] = 0, memcpy(ptr, str, len)) : NULL; |
-} |
- |
-/* |
- * static stuff |
- */ |
-static void _set_allocator(void) |
-{ |
- void * p; |
- assert(! allocator); |
- |
- /* |
- * the purpose of the test below is to check the behaviour |
- * of realloc(ptr, 0), which is defined in the standard |
- * as an implementation-specific. if it returns zero, |
- * then it's equivalent to free(). it can however return |
- * non-zero, in which case it cannot be used for freeing |
- * memory blocks and we'll need to supply our own version |
- * |
- * Thanks to Stan Tobias for pointing this tricky part out. |
- */ |
- allocator = realloc; |
- if (! (p = malloc(1))) |
- /* hmm */ |
- return; |
- |
- if ((p = realloc(p, 0))) |
- { |
- /* realloc cannot be used as free() */ |
- allocator = _realloc; |
- free(p); |
- } |
-} |
- |
-static void * _realloc(void * ptr, size_t n) |
-{ |
- /* |
- * free'ing realloc() |
- */ |
- if (n) |
- return realloc(ptr, n); |
- free(ptr); |
- return NULL; |
-} |
- |
-static int _relate(hblock_t * b, hblock_t * p) |
-{ |
- hlist_item_t * i; |
- |
- if (!b || !p) |
- return 0; |
- |
- /* |
- * since there is no 'parent' pointer, which would've allowed |
- * O(log(n)) upward traversal, the check must use O(n) downward |
- * iteration of the entire hierarchy; and this can be VERY SLOW |
- */ |
- hlist_for_each(i, &p->children) |
- { |
- hblock_t * q = structof(i, hblock_t, siblings); |
- if (q == b || _relate(b, q)) |
- return 1; |
- } |
- return 0; |
-} |
- |
-static void _free_children(hblock_t * p) |
-{ |
- hlist_item_t * i, * tmp; |
- |
-#ifndef NDEBUG |
- /* |
- * this catches loops in hierarchy with almost zero |
- * overhead (compared to _relate() running time) |
- */ |
- assert(p && p->magic == HH_MAGIC); |
- p->magic = 0; |
-#endif |
- hlist_for_each_safe(i, tmp, &p->children) |
- { |
- hblock_t * q = structof(i, hblock_t, siblings); |
- _free_children(q); |
- allocator(q, 0); |
- } |
-} |
- |