mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-03-26 14:01:44 +08:00
Be a bit more careful with memory alignemnt in halloc
darcs-hash:20060930121917-ac50b-6292696663684a38844b4c21360274b365e52969.gz
This commit is contained in:
parent
92df4a6d91
commit
421ebcc2d7
60
halloc.c
60
halloc.c
@ -24,9 +24,12 @@
|
|||||||
#define HALLOC_BLOCK_SIZE 128
|
#define HALLOC_BLOCK_SIZE 128
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Maximum size of trailing halloc space to refuse to discard
|
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 16
|
#define HALLOC_SCRAP_SIZE (4*sizeof(void *))
|
||||||
|
|
||||||
#ifdef HALLOC_DEBUG
|
#ifdef HALLOC_DEBUG
|
||||||
/**
|
/**
|
||||||
@ -71,24 +74,32 @@ typedef struct halloc
|
|||||||
/**
|
/**
|
||||||
Amount of free space in the scratch area
|
Amount of free space in the scratch area
|
||||||
*/
|
*/
|
||||||
size_t scratch_free;
|
ssize_t scratch_free;
|
||||||
#if __STDC_VERSION__ < 199901L
|
|
||||||
/**
|
|
||||||
The actual data. Made to be of type long long to make sure memory alignment is in order.
|
|
||||||
*/
|
|
||||||
long long data[1]; // Waste one byte on non-C99 compilers... :-(
|
|
||||||
#else
|
|
||||||
long long data[];
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
halloc_t;
|
halloc_t;
|
||||||
|
|
||||||
|
static void *align_ptr( void *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 (void *)long_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
Get the offset of the halloc structure before a data block
|
||||||
*/
|
*/
|
||||||
static halloc_t *halloc_from_data( void *data )
|
static halloc_t *halloc_from_data( void *data )
|
||||||
{
|
{
|
||||||
return (halloc_t *)(((char *)data) - sizeof( halloc_t ) );
|
return (halloc_t *)(((char *)data) - align_sz(sizeof( halloc_t ) ));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,7 +115,7 @@ static void late_free( void *data)
|
|||||||
statistics, like number of allocations and number of internal calls
|
statistics, like number of allocations and number of internal calls
|
||||||
to malloc.
|
to malloc.
|
||||||
*/
|
*/
|
||||||
static void woot()
|
static void halloc_report()
|
||||||
{
|
{
|
||||||
if( getpid() == pid )
|
if( getpid() == pid )
|
||||||
{
|
{
|
||||||
@ -115,25 +126,40 @@ static void woot()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void *halloc( void *context, size_t size )
|
void *halloc( void *context, size_t size )
|
||||||
{
|
{
|
||||||
halloc_t *me, *parent;
|
halloc_t *me, *parent;
|
||||||
if( context )
|
if( context )
|
||||||
{
|
{
|
||||||
void *res;
|
void *res;
|
||||||
|
void *aligned;
|
||||||
|
|
||||||
#ifdef HALLOC_DEBUG
|
#ifdef HALLOC_DEBUG
|
||||||
|
|
||||||
if( !child_count )
|
if( !child_count )
|
||||||
{
|
{
|
||||||
pid = getpid();
|
pid = getpid();
|
||||||
atexit( woot );
|
atexit( &halloc_report );
|
||||||
}
|
}
|
||||||
|
|
||||||
child_count++;
|
child_count++;
|
||||||
child_size += size;
|
child_size += size;
|
||||||
#endif
|
#endif
|
||||||
parent = halloc_from_data( context );
|
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 )
|
if( size <= parent->scratch_free )
|
||||||
{
|
{
|
||||||
res = parent->scratch;
|
res = parent->scratch;
|
||||||
@ -169,18 +195,18 @@ void *halloc( void *context, size_t size )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
me = (halloc_t *)calloc( 1, sizeof(halloc_t) + size + HALLOC_BLOCK_SIZE );
|
me = (halloc_t *)calloc( 1, align_sz(sizeof(halloc_t)) + align_sz(size) + HALLOC_BLOCK_SIZE );
|
||||||
|
|
||||||
if( !me )
|
if( !me )
|
||||||
return 0;
|
return 0;
|
||||||
#ifdef HALLOC_DEBUG
|
#ifdef HALLOC_DEBUG
|
||||||
parent_count++;
|
parent_count++;
|
||||||
#endif
|
#endif
|
||||||
me->scratch = ((char *)me) + sizeof(halloc_t) + size;
|
me->scratch = ((char *)me) + align_sz(sizeof(halloc_t)) + align_sz(size);
|
||||||
me->scratch_free = HALLOC_BLOCK_SIZE;
|
me->scratch_free = HALLOC_BLOCK_SIZE;
|
||||||
|
|
||||||
al_init( &me->children );
|
al_init( &me->children );
|
||||||
return &me->data;
|
return ((char *)me) + align_sz(sizeof(halloc_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user