aboutsummaryrefslogtreecommitdiffhomepage
path: root/halloc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'halloc.cpp')
-rw-r--r--halloc.cpp264
1 files changed, 0 insertions, 264 deletions
diff --git a/halloc.cpp b/halloc.cpp
deleted file mode 100644
index 2b4c78b4..00000000
--- a/halloc.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-/** \file halloc.c
-
- A hierarchical memory allocation system. Works just like talloc
- used in Samba, except that an arbitrary block allocated with
- malloc() can be registered to be freed by halloc_free.
-
-*/
-
-#include "config.h"
-
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "fallback.h"
-#include "util.h"
-
-#include "common.h"
-#include "halloc.h"
-
-/**
- Extra size to allocate whenever doing a halloc, in order to fill uyp smaller halloc calls
-*/
-#define HALLOC_BLOCK_SIZE 128
-
-/**
- Maximum size of trailing halloc space to refuse to discard. This is
- set to be larger on 64-bit platforms, since we don't want to get
- 'stuck' with an unusably small slice of memory, and what is
- unusably small often depends on pointer size.
-*/
-#define HALLOC_SCRAP_SIZE (4*sizeof(void *))
-
-#ifdef HALLOC_DEBUG
-/**
- Debug statistic parameter
-*/
-static int child_count=0;
-/**
- Debug statistic parameter
-*/
-static int child_size=0;
-/**
- Debug statistic parameter
-*/
-static int alloc_count =0;
-/**
- Debug statistic parameter
-*/
-static int alloc_spill = 0;
-/**
- Debug statistic parameter
-*/
-static pid_t pid=0;
-/**
- Debug statistic parameter
-*/
-static int parent_count=0;
-#endif
-
-/**
- The main datastructure for a main halloc context
-*/
-typedef struct halloc
-{
- /**
- List of all addresses and functions to call on them
- */
- array_list_t children;
- /**
- Memory scratch area used to fullfil smaller memory allocations
- */
- char *scratch;
- /**
- Amount of free space in the scratch area
- */
- ssize_t scratch_free;
-}
- halloc_t;
-
-/**
- Allign the specified pointer
- */
-static char *align_ptr( char *in )
-{
- unsigned long step = maxi(sizeof(double),sizeof(void *));
- unsigned long inc = step-1;
- unsigned long long_in = (long)in;
- unsigned long long_out = ((long_in+inc)/step)*step;
- return (char *)long_out;
-}
-
-/**
- Allign specifies size_t
- */
-static size_t align_sz( size_t in )
-{
- size_t step = maxi(sizeof(double),sizeof(void *));
- size_t inc = step-1;
- return ((in+inc)/step)*step;
-}
-
-/**
- Get the offset of the halloc structure before a data block
-*/
-static halloc_t *halloc_from_data( void *data )
-{
- return (halloc_t *)(((char *)data) - align_sz(sizeof( halloc_t ) ));
-}
-
-/**
- A function that does nothing
-*/
-static void late_free( void *data)
-{
-}
-
-#ifdef HALLOC_DEBUG
-/**
- Debug function, called at exit when in debug mode. Prints usage
- statistics, like number of allocations and number of internal calls
- to malloc.
-*/
-static void halloc_report()
-{
- if( getpid() == pid )
- {
- debug( 1, L"%d parents, %d children with average child size of %.2f bytes caused %d allocs, average spill of %.2f bytes",
- parent_count, child_count, (double)child_size/child_count,
- parent_count+alloc_count, (double)alloc_spill/(parent_count+alloc_count) );
- }
-}
-#endif
-
-
-void *halloc( void *context, size_t size )
-{
- halloc_t *me, *parent;
- if( context )
- {
- char *res;
- char *aligned;
-
-#ifdef HALLOC_DEBUG
-
- if( !child_count )
- {
- pid = getpid();
- atexit( &halloc_report );
- }
-
- child_count++;
- child_size += size;
-#endif
- parent = halloc_from_data( context );
-
- /*
- Align memory address
- */
- aligned = align_ptr( parent->scratch );
-
- parent->scratch_free -= (aligned-parent->scratch);
-
- if( parent->scratch_free < 0 )
- parent->scratch_free=0;
-
- parent->scratch = aligned;
-
- if( size <= parent->scratch_free )
- {
- res = parent->scratch;
- parent->scratch_free -= size;
- parent->scratch = ((char *)parent->scratch)+size;
- }
- else
- {
-
-#ifdef HALLOC_DEBUG
- alloc_count++;
-#endif
-
- if( parent->scratch_free < HALLOC_SCRAP_SIZE )
- {
-#ifdef HALLOC_DEBUG
- alloc_spill += parent->scratch_free;
-#endif
- res = (char *)calloc( 1, size + HALLOC_BLOCK_SIZE );
- if( !res )
- DIE_MEM();
- parent->scratch = (char *)res + size;
- parent->scratch_free = HALLOC_BLOCK_SIZE;
- }
- else
- {
- res = (char *)calloc( 1, size );
- if( !res )
- DIE_MEM();
- }
- al_push_func( &parent->children, (void (*)())&late_free );
- al_push( &parent->children, res );
-
- }
- return res;
-
- }
- else
- {
- me = (halloc_t *)calloc( 1, align_sz(sizeof(halloc_t)) + align_sz(size) + HALLOC_BLOCK_SIZE );
-
- if( !me )
- DIE_MEM();
-#ifdef HALLOC_DEBUG
- parent_count++;
-#endif
- me->scratch = ((char *)me) + align_sz(sizeof(halloc_t)) + align_sz(size);
- me->scratch_free = HALLOC_BLOCK_SIZE;
-
- al_init( &me->children );
- return ((char *)me) + align_sz(sizeof(halloc_t));
- }
-}
-
-void halloc_register_function( void *context, void (*func)(void *), void *data )
-{
- halloc_t *me;
- if( !context )
- return;
-
- me = halloc_from_data( context );
- al_push_func( &me->children, (void (*)())func );
- al_push( &me->children, data );
-}
-
-void halloc_free( void *context )
-{
- halloc_t *me;
- int i;
-
- if( !context )
- return;
-
-
- me = halloc_from_data( context );
-
-#ifdef HALLOC_DEBUG
- alloc_spill += me->scratch_free;
-#endif
- for( i=0; i<al_get_count(&me->children); i+=2 )
- {
- void (*func)(void *) = (void (*)(void *))al_get( &me->children, i );
- void * data = (void *)al_get( &me->children, i+1 );
- if( func != &late_free )
- func( data );
- }
- for( i=0; i<al_get_count(&me->children); i+=2 )
- {
- void (*func)(void *) = (void (*)(void *))al_get_func( &me->children, i );
- void * data = (void *)al_get( &me->children, i+1 );
- if( func == &late_free )
- free( data );
- }
- al_destroy( &me->children );
- free(me);
-}