mirror of
https://github.com/fish-shell/fish-shell
synced 2024-09-21 15:01:53 +00:00
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:
parent
530bbfc9ac
commit
585191310b
9 changed files with 125 additions and 40 deletions
|
@ -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
4
exec.c
|
@ -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
78
halloc.c
Normal 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
18
halloc.h
Normal 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
6
io.c
|
@ -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
4
io.h
|
@ -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.
|
||||
|
|
27
parser.c
27
parser.c
|
@ -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
21
proc.c
|
@ -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
4
proc.h
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in a new issue