add nestegg and halloc from http://github.com/kinetiknz/nestegg.git
This commit is contained in:
parent
0c7bdbcf54
commit
6b297cd037
9 changed files with 2790 additions and 0 deletions
14
src/halloc/Makefile
Normal file
14
src/halloc/Makefile
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
CFLAGS = -I. -ansi -Wall -pedantic
|
||||
|
||||
LIBNAME = libhalloc.a
|
||||
OBJS = src/halloc.o
|
||||
|
||||
$(LIBNAME): $(OBJS)
|
||||
ar rcs $(LIBNAME) $(OBJS)
|
||||
|
||||
install: $(LIBNAME)
|
||||
cp halloc.h /usr/include
|
||||
cp $(LIBNAME) /usr/lib
|
||||
|
||||
clean:
|
||||
rm -f $(LIBNAME) $(OBJS)
|
||||
45
src/halloc/README
Normal file
45
src/halloc/README
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
halloc 1.2.1
|
||||
============
|
||||
|
||||
Hierarchical memory heap interface - an extension to standard
|
||||
malloc/free interface that simplifies tasks of memory disposal
|
||||
when allocated structures exhibit hierarchical properties.
|
||||
|
||||
http://swapped.cc/halloc
|
||||
=
|
||||
To build libhalloc.a with GNU tools run
|
||||
make
|
||||
|
||||
To install in /usr/include and /usr/lib
|
||||
make install
|
||||
|
||||
To cleanup the build files
|
||||
make clean
|
||||
=
|
||||
halloc-1.2.1
|
||||
* fixed a double-free bug in _set_allocator() as per
|
||||
Matthew Gregan comments
|
||||
|
||||
* switched to using NULL instead of 0 where applicable
|
||||
|
||||
halloc-1.2.0
|
||||
* added missing <string.h> include to halloc.c
|
||||
|
||||
* improved standard compliance thanks to the feedback
|
||||
received from Stan Tobias. Two things were fixed -
|
||||
|
||||
- hblock_t structure no longer uses zero-sized 'data'
|
||||
array, which happened to be common, but non-standard
|
||||
extension;
|
||||
|
||||
- secondly, added the code to test the behaviour of
|
||||
realloc(ptr, 0). Standard allows it NOT to act as
|
||||
free(), in which case halloc will use its own version
|
||||
of allocator calling free() when neccessary.
|
||||
|
||||
halloc-1.1.0
|
||||
* initial public release (rewrite of hhmalloc library)
|
||||
|
||||
=============================================================================
|
||||
Copyright (c) 2004-2010, Alex Pankratov (ap@swapped.cc). All rights reserved.
|
||||
|
||||
43
src/halloc/halloc.h
Normal file
43
src/halloc/halloc.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2004-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
|
||||
*/
|
||||
|
||||
#ifndef _LIBP_HALLOC_H_
|
||||
#define _LIBP_HALLOC_H_
|
||||
|
||||
#include <stddef.h> /* size_t */
|
||||
|
||||
/*
|
||||
* Core API
|
||||
*/
|
||||
void * halloc (void * block, size_t len);
|
||||
void hattach(void * block, void * parent);
|
||||
|
||||
/*
|
||||
* standard malloc/free api
|
||||
*/
|
||||
void * h_malloc (size_t len);
|
||||
void * h_calloc (size_t n, size_t len);
|
||||
void * h_realloc(void * p, size_t len);
|
||||
void h_free (void * p);
|
||||
char * h_strdup (const char * str);
|
||||
|
||||
/*
|
||||
* the underlying allocator
|
||||
*/
|
||||
typedef void * (* realloc_t)(void * ptr, size_t len);
|
||||
|
||||
extern realloc_t halloc_allocator;
|
||||
|
||||
#endif
|
||||
|
||||
36
src/halloc/src/align.h
Normal file
36
src/halloc/src/align.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2004-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
|
||||
*/
|
||||
|
||||
#ifndef _LIBP_ALIGN_H_
|
||||
#define _LIBP_ALIGN_H_
|
||||
|
||||
/*
|
||||
* a type with the most strict alignment requirements
|
||||
*/
|
||||
union max_align
|
||||
{
|
||||
char c;
|
||||
short s;
|
||||
long l;
|
||||
int i;
|
||||
float f;
|
||||
double d;
|
||||
void * v;
|
||||
void (*q)(void);
|
||||
};
|
||||
|
||||
typedef union max_align max_align_t;
|
||||
|
||||
#endif
|
||||
|
||||
254
src/halloc/src/halloc.c
Normal file
254
src/halloc/src/halloc.c
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* 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 "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);
|
||||
}
|
||||
}
|
||||
|
||||
136
src/halloc/src/hlist.h
Normal file
136
src/halloc/src/hlist.h
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2004-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
|
||||
*/
|
||||
|
||||
#ifndef _LIBP_HLIST_H_
|
||||
#define _LIBP_HLIST_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include "macros.h" /* static_inline */
|
||||
|
||||
/*
|
||||
* weak double-linked list w/ tail sentinel
|
||||
*/
|
||||
typedef struct hlist_head hlist_head_t;
|
||||
typedef struct hlist_item hlist_item_t;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
struct hlist_head
|
||||
{
|
||||
hlist_item_t * next;
|
||||
};
|
||||
|
||||
struct hlist_item
|
||||
{
|
||||
hlist_item_t * next;
|
||||
hlist_item_t ** prev;
|
||||
};
|
||||
|
||||
/*
|
||||
* shared tail sentinel
|
||||
*/
|
||||
struct hlist_item hlist_null;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
#define __hlist_init(h) { &hlist_null }
|
||||
#define __hlist_init_item(i) { &hlist_null, &(i).next }
|
||||
|
||||
static_inline void hlist_init(hlist_head_t * h);
|
||||
static_inline void hlist_init_item(hlist_item_t * i);
|
||||
|
||||
/* static_inline void hlist_purge(hlist_head_t * h); */
|
||||
|
||||
/* static_inline bool_t hlist_empty(const hlist_head_t * h); */
|
||||
|
||||
/* static_inline hlist_item_t * hlist_head(const hlist_head_t * h); */
|
||||
|
||||
/* static_inline hlist_item_t * hlist_next(const hlist_item_t * i); */
|
||||
/* static_inline hlist_item_t * hlist_prev(const hlist_item_t * i,
|
||||
const hlist_head_t * h); */
|
||||
|
||||
static_inline void hlist_add(hlist_head_t * h, hlist_item_t * i);
|
||||
|
||||
/* static_inline void hlist_add_prev(hlist_item_t * l, hlist_item_t * i); */
|
||||
/* static_inline void hlist_add_next(hlist_item_t * l, hlist_item_t * i); */
|
||||
|
||||
static_inline void hlist_del(hlist_item_t * i);
|
||||
|
||||
static_inline void hlist_relink(hlist_item_t * i);
|
||||
static_inline void hlist_relink_head(hlist_head_t * h);
|
||||
|
||||
#define hlist_for_each(i, h) \
|
||||
for (i = (h)->next; i != &hlist_null; i = i->next)
|
||||
|
||||
#define hlist_for_each_safe(i, tmp, h) \
|
||||
for (i = (h)->next, tmp = i->next; \
|
||||
i!= &hlist_null; \
|
||||
i = tmp, tmp = i->next)
|
||||
|
||||
/*
|
||||
* static
|
||||
*/
|
||||
static_inline void hlist_init(hlist_head_t * h)
|
||||
{
|
||||
assert(h);
|
||||
h->next = &hlist_null;
|
||||
}
|
||||
|
||||
static_inline void hlist_init_item(hlist_item_t * i)
|
||||
{
|
||||
assert(i);
|
||||
i->prev = &i->next;
|
||||
i->next = &hlist_null;
|
||||
}
|
||||
|
||||
static_inline void hlist_add(hlist_head_t * h, hlist_item_t * i)
|
||||
{
|
||||
hlist_item_t * next;
|
||||
assert(h && i);
|
||||
|
||||
next = i->next = h->next;
|
||||
next->prev = &i->next;
|
||||
h->next = i;
|
||||
i->prev = &h->next;
|
||||
}
|
||||
|
||||
static_inline void hlist_del(hlist_item_t * i)
|
||||
{
|
||||
hlist_item_t * next;
|
||||
assert(i);
|
||||
|
||||
next = i->next;
|
||||
next->prev = i->prev;
|
||||
*i->prev = next;
|
||||
|
||||
hlist_init_item(i);
|
||||
}
|
||||
|
||||
static_inline void hlist_relink(hlist_item_t * i)
|
||||
{
|
||||
assert(i);
|
||||
*i->prev = i;
|
||||
i->next->prev = &i->next;
|
||||
}
|
||||
|
||||
static_inline void hlist_relink_head(hlist_head_t * h)
|
||||
{
|
||||
assert(h);
|
||||
h->next->prev = &h->next;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
36
src/halloc/src/macros.h
Normal file
36
src/halloc/src/macros.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2004-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
|
||||
*/
|
||||
|
||||
#ifndef _LIBP_MACROS_H_
|
||||
#define _LIBP_MACROS_H_
|
||||
|
||||
#include <stddef.h> /* offsetof */
|
||||
|
||||
/*
|
||||
restore pointer to the structure by a pointer to its field
|
||||
*/
|
||||
#define structof(p,t,f) ((t*)(- offsetof(t,f) + (char*)(p)))
|
||||
|
||||
/*
|
||||
* redefine for the target compiler
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#define static_inline static __inline
|
||||
#else
|
||||
#define static_inline static __inline__
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue