First checkin of transition to using a new hierarchical memory allocator, some of the memory associated with a job is covered

darcs-hash:20060206142502-ac50b-ba1c9a4f64ea0f44f65303a125f9ddae5bd31e2f.gz
This commit is contained in:
axel 2006-02-07 00:25:02 +10:00
parent 530bbfc9ac
commit 585191310b
9 changed files with 125 additions and 40 deletions

View file

@ -65,7 +65,8 @@ COMMON_OBJS := function.o builtin.o common.o complete.o env.o exec.o \
expand.o highlight.o history.o kill.o parser.o proc.o reader.o \
sanity.o tokenizer.o util.o wildcard.o wgetopt.o wutil.o input.o \
output.o intern.o env_universal.o env_universal_common.o \
input_common.o event.o signal.o io.o translate.o parse_util.o
input_common.o event.o signal.o io.o translate.o parse_util.o \
halloc.o
# builtin_help.h exists, but builtin_help.c is autogenerated
COMMON_OBJS_WITH_HEADER := builtin_help.o

4
exec.c
View file

@ -706,9 +706,9 @@ void exec( job_t *j )
if( block_io )
{
if( j->io )
j->io = io_add( io_duplicate(block_io), j->io );
j->io = io_add( io_duplicate( j, block_io), j->io );
else
j->io=io_duplicate(block_io);
j->io=io_duplicate( j, block_io);
}
j->io = io_add( j->io, &pipe_write );

78
halloc.c Normal file
View file

@ -0,0 +1,78 @@
/** \file halloc.c
A hierarchical memory allocation system
*/
#include "config.h"
#include <stdlib.h>
#include <unistd.h>
#include "util.h"
#include "common.h"
#include "halloc.h"
typedef struct halloc
{
array_list_t children;
long long data[0];
}
halloc_t;
static halloc_t *halloc_from_data( void *data )
{
return (halloc_t *)(data - sizeof( halloc_t ) );
}
void *halloc( void *context, size_t size )
{
halloc_t *res = (halloc_t *)calloc( 1, sizeof(halloc_t) + size );
if( !res )
return 0;
al_init( &res->children );
if( context )
{
halloc_t *parent = halloc_from_data( context );
al_push( &parent->children, &res->data );
}
return &res->data;
}
void halloc_free( void *context )
{
halloc_t *me;
if( !context )
return;
me = halloc_from_data( context );
al_foreach( &me->children, (void (*)(const void *))&halloc_free );
al_destroy( &me->children );
free(me);
}
wchar_t *halloc_wcsdup( void *context, const wchar_t *in )
{
size_t len=wcslen(in);
wchar_t *out = halloc( context, sizeof( wchar_t)*(len+1));
if( out == 0 )
{
die_mem();
}
memcpy( out, in, sizeof( wchar_t)*(len+1));
return out;
}
wchar_t *halloc_wcsndup( void *context, const wchar_t *in, int c )
{
wchar_t *res = halloc( context, sizeof(wchar_t)*(c+1) );
if( res == 0 )
{
die_mem();
}
wcsncpy( res, in, c );
res[c] = L'\0';
return res;
}

18
halloc.h Normal file
View file

@ -0,0 +1,18 @@
/** \file halloc.h
A hierarchical memory allocation system
*/
/**
Allocate new memory using specified parent memory context. If \c
context is null, a new root context is created.
*/
void *halloc( void *context, size_t size );
/**
Free memory context and all children. Only root contexts may be
freed explicitly.
*/
void halloc_free( void *context );
wchar_t *halloc_wcsdup( void *context, const wchar_t *str );
wchar_t *halloc_wcsndup( void *context, const wchar_t *in, int c );

6
io.c
View file

@ -175,14 +175,14 @@ io_data_t *io_remove( io_data_t *list, io_data_t *element )
return list;
}
io_data_t *io_duplicate( io_data_t *l )
io_data_t *io_duplicate( void *context, io_data_t *l )
{
io_data_t *res;
if( l == 0 )
return 0;
res = malloc( sizeof( io_data_t) );
res = halloc( context, sizeof( io_data_t) );
if( !res )
{
@ -191,7 +191,7 @@ io_data_t *io_duplicate( io_data_t *l )
}
memcpy( res, l, sizeof(io_data_t ));
res->next=io_duplicate( l->next );
res->next=io_duplicate( context, l->next );
return res;
}

4
io.h
View file

@ -62,9 +62,9 @@ io_data_t *io_add( io_data_t *first_chain, io_data_t *decond_chain );
io_data_t *io_remove( io_data_t *list, io_data_t *element );
/**
Make a copy of the specified chain of redirections
Make a copy of the specified chain of redirections. Uses halloc.
*/
io_data_t *io_duplicate( io_data_t *l );
io_data_t *io_duplicate( void *context, io_data_t *l );
/**
Return the last io redirection in ht e chain for the specified file descriptor.

View file

@ -38,6 +38,7 @@ The fish parser. Contains functions for parsing code.
#include "translate.h"
#include "intern.h"
#include "parse_util.h"
#include "halloc.h"
/**
Maximum number of block levels in code. This is not the same as
@ -1376,7 +1377,7 @@ static void parse_job_main_loop( process_t *p,
}
p->pipe_fd = wcstol( tok_last( tok ), 0, 10 );
p->argv = list_to_char_arr( args );
p->next = calloc( 1, sizeof( process_t ) );
p->next = halloc( j, sizeof( process_t ) );
if( p->next == 0 )
{
die_mem();
@ -1464,7 +1465,7 @@ static void parse_job_main_loop( process_t *p,
unmatched_wildcard = 1;
if( !unmatched )
{
unmatched = wcsdup(tok_last( tok ));
unmatched = halloc_wcsdup( j, tok_last( tok ));
unmatched_pos = tok_get_pos( tok );
}
@ -1518,7 +1519,7 @@ static void parse_job_main_loop( process_t *p,
break;
}
new_io = calloc( 1, sizeof(io_data_t) );
new_io = halloc( j, sizeof(io_data_t) );
if( !new_io )
die_mem();
@ -1531,7 +1532,10 @@ static void parse_job_main_loop( process_t *p,
{
case TOK_STRING:
{
target = expand_one( wcsdup( tok_last( tok ) ), 0);
wchar_t *tmp = expand_one( wcsdup( tok_last( tok ) ), 0);
target = halloc_wcsdup( j, tmp );
free( tmp );
if( target == 0 && error_code == 0 )
{
error( SYNTAX_ERROR,
@ -1602,14 +1606,13 @@ static void parse_job_main_loop( process_t *p,
tok_next(tok);
}
free(target);
}
break;
}
}
j->io = io_add( j->io, new_io );
}
break;
@ -1660,7 +1663,6 @@ static void parse_job_main_loop( process_t *p,
}
}
free( unmatched );
return;
}
@ -2221,8 +2223,7 @@ static void eval_job( tokenizer *tok )
}
}
j->first_process = calloc( 1, sizeof( process_t ) );
j->first_process = halloc( j, sizeof( process_t ) );
if( parse_job( j->first_process, j, tok ) &&
j->first_process->argv )
@ -2235,11 +2236,13 @@ static void eval_job( tokenizer *tok )
if( newline )
stop_pos = mini( stop_pos, newline - tok_string(tok) );
j->command = wcsndup( tok_string(tok)+start_pos,
stop_pos-start_pos );
j->command = halloc_wcsndup( j,
tok_string(tok)+start_pos,
stop_pos-start_pos );
}
else
j->command = wcsdup( L"" );
j->command = halloc_wcsdup( j,
L"" );
if( profile )
{

21
proc.c
View file

@ -119,8 +119,6 @@ static void free_process( process_t *p )
if( p==0 )
return;
free_process( p->next );
free( p->actual_cmd );
if( p->argv != 0 )
@ -131,7 +129,6 @@ static void free_process( process_t *p )
}
free(p->argv );
}
free( p );
}
/**
@ -176,21 +173,7 @@ void job_free( job_t * j )
/* Then free ourselves */
free_process( j->first_process);
if( j->command != 0 )
free( j->command );
for( io=j->io; io; io=ionext )
{
ionext = io->next;
// fwprintf( stderr, L"Kill redirect %d of type %d\n", ionext, io->io_mode );
if( io->io_mode == IO_FILE )
{
free( io->param1.filename );
}
free( io );
}
free( j );
halloc_free( j );
}
void proc_destroy()
@ -223,7 +206,7 @@ job_t *job_create()
while( job_get( free_id ) != 0 )
free_id++;
res = calloc( 1, sizeof(job_t) );
res = halloc( 0, sizeof(job_t) );
res->next = first_job;
res->job_id = free_id;
first_job = res;

4
proc.h
View file

@ -247,7 +247,9 @@ int proc_get_last_status();
void job_free( job_t* j );
/**
Create a new job
Create a new job. Job struct is allocated using halloc, so anything
that should be freed with the job can uset it as a halloc context
when allocating.
*/
job_t *job_create();