carve.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 968 行 · 第 1/2 页
C
968 行
if( block_index <= block_count ) {
break;
}
newBlk( cv );
++block_count;
}
DbgAssert( cv->blk_count == block_count );
for( block = cv->blk_list; block != NULL; block = block->next ) {
if( block_index == block_count ) {
return( &(block->data[ block_offset ]) );
}
--block_count;
}
_FatalAbort( "unable to find carve memory block" );
return( NULL );
}
void CarveWalkAllFree( carve_t cv, void (*rtn)( void * ) )
/********************************************************/
{
free_t *check;
restoreFromZapped( cv );
check = cv->free_list;
#ifndef NDEBUG
// transfer over to another list since these free blocks may be modified
cv->free_list = NULL;
cv->zapped_free_list = check;
#endif
for( ; check != NULL; check = check->next_free ) {
#ifndef NDEBUG
free_t *check_next = check->next_free;
(*rtn)( check );
if( check->next_free != check_next ) {
// restore to prevent possible memory faults
check->next_free = check_next;
_FatalAbort( "carve walk free routine destroyed links" );
}
#else
(*rtn)( check );
#endif
}
}
#ifndef NDEBUG
void CarveVerifyFreeElement( carve_t cv, void *elm )
/**************************************************/
{
free_t *check;
for( check = cv->free_list; check != NULL; check = check->next_free ) {
if( elm == check ) {
return;
}
}
for( check = cv->zapped_free_list; check != NULL; check = check->next_free ) {
if( elm == check ) {
return;
}
}
_FatalAbort( "element looks free but isn't" );
}
#endif
void CarveWalkAll( carve_t cv, void (*rtn)( void *, carve_walk_base * ), carve_walk_base *data )
/**********************************************************************************************/
{
blk_t *block;
char *compare;
char *start;
size_t esize;
unsigned block_index;
unsigned block_offset;
esize = cv->elm_size;
block_index = cv->blk_count;
for( block = cv->blk_list; block != NULL; block = block->next ) {
start = block->data;
block_offset = cv->blk_top;
compare = start + block_offset;
do {
compare -= esize;
block_offset -= esize;
data->index = MK_INDEX( block_index, block_offset );
(*rtn)( compare, data );
} while( compare != start );
--block_index;
}
}
void CarveMapOptimize( carve_t cv, cv_index last_valid_index )
/************************************************************/
{
blk_t *block;
blk_t **init;
size_t nmaps;
unsigned mindex;
if( last_valid_index == CARVE_NULL_INDEX ) {
return;
}
// make sure there are enough blocks allocated
CarveMapIndex( cv, (void *) last_valid_index );
nmaps = GET_BLOCK( last_valid_index );
init = _MemoryAllocate( nmaps * sizeof( blk_t * ) );
cv->blk_map = init;
#ifndef NDEBUG
if( nmaps != cv->blk_count ) {
_FatalAbort( "incorrect block calculation" );
}
DbgZapMem( init, 0xff, nmaps * sizeof( blk_t * ) );
#endif
mindex = nmaps - 1;
for( block = cv->blk_list; block != NULL; block = block->next ) {
init[ mindex ] = block;
--mindex;
}
}
void CarveMapUnoptimize( carve_t cv )
/***********************************/
{
_MemoryFreePtr( &(cv->blk_map) );
}
cv_index CarveLastValidIndex( carve_t cv )
/****************************************/
{
if( cv->blk_count == 0 ) {
return( CARVE_NULL_INDEX );
}
return( MK_INDEX( cv->blk_count, cv->blk_top - cv->elm_size ) );
}
void *CarveInitElement( cvinit_t *data, cv_index index )
/******************************************************/
{
blk_t *block;
free_t *check;
free_t **head;
unsigned want_block;
unsigned curr_block;
char *init_elm;
DbgAssert( data->cv->blk_map != NULL );
block = data->block;
want_block = GET_BLOCK( index );
curr_block = data->bindex;
if( want_block != curr_block ) {
DbgAssert( want_block <= curr_block );
while( want_block != curr_block ) {
block = block->next;
--curr_block;
}
data->block = block;
data->bindex = curr_block;
}
init_elm = &(block->data[ GET_OFFSET( index ) ]);
head = data->head;
check = *head;
for(;;) {
DbgAssert( check != NULL );
if( check == (free_t *)init_elm ) {
*head = check->next_free;
data->head = head;
DbgZapMem( init_elm, 0x19, data->cv->elm_size );
return( init_elm );
}
head = &(check->next_free);
check = *head;
}
}
void CarveInitStart( carve_t cv, cvinit_t *data )
/***********************************************/
{
data->block = cv->blk_list;
data->bindex = cv->blk_count;
data->head = &(cv->free_list);
data->cv = cv;
}
#if 0 && ! defined(NDEBUG)
carve_t carveMASTER;
carve_t carveSLAVE1;
carve_t carveSLAVE2;
typedef struct master MASTER;
typedef struct slave1 SLAVE1;
typedef struct slave2 SLAVE2;
struct master {
MASTER *next;
SLAVE1 *ring1;
SLAVE2 *ring2;
MASTER *test;
unsigned free : 1;
};
struct slave1 {
SLAVE1 *next;
SLAVE2 *sister;
MASTER *master;
unsigned free : 1;
};
struct slave2 {
SLAVE2 *next;
SLAVE1 *brother;
MASTER *master;
unsigned free : 1;
};
MASTER *masterList;
unsigned waste;
SLAVE1 *waste1;
SLAVE2 *waste2;
SLAVE1 *newSLAVE1()
{
SLAVE1 *s1;
s1 = CarveAlloc( carveSLAVE1 );
++waste;
if( !( waste & 3 ) ) {
s1->next = waste1;
waste1 = s1;
s1 = CarveAlloc( carveSLAVE1 );
}
return( s1 );
}
SLAVE2 *newSLAVE2()
{
SLAVE2 *s2;
s2 = CarveAlloc( carveSLAVE2 );
++waste;
if( !( waste & 3 ) ) {
s2->next = waste2;
waste2 = s2;
s2 = CarveAlloc( carveSLAVE2 );
}
return( s2 );
}
void dumpMess()
{
MASTER *m;
SLAVE1 *s1;
SLAVE2 *s2;
printf( "masterList:\n" );
RingIterBeg( masterList, m ) {
printf( "m: %p next: %p ring1: %p ring2: %p test: %p\n", m, m->next, m->ring1, m->ring2, m->test );
RingIterBeg( m->ring1, s1 ) {
printf( " 1: %p next: %p sibling: %p master: %p\n", s1, s1->next, s1->sister, s1->master );
} RingIterEnd( s1 )
RingIterBeg( m->ring2, s2 ) {
printf( " 2: %p next: %p sibling: %p master: %p\n", s2, s2->next, s2->brother, s2->master );
} RingIterEnd( s2 )
} RingIterEnd( m )
printf( "---\n" );
}
void createMess()
{
int i,j;
MASTER *m;
SLAVE1 *s1;
SLAVE2 *s2;
carveMASTER = CarveCreate( sizeof( MASTER ), 1 );
carveSLAVE1 = CarveCreate( sizeof( SLAVE1 ), 2 );
carveSLAVE2 = CarveCreate( sizeof( SLAVE2 ), 31 );
for( i = 0; i < 5; ++i ) {
m = CarveAlloc( carveMASTER );
RingAppend( &masterList, m );
m->free = FALSE;
m->ring1 = NULL;
m->ring2 = NULL;
if( i & 1 ) {
m->test = NULL;
} else {
m->test = m;
}
for( j = 0; j < 5; ++j ) {
s1 = newSLAVE1();
s2 = newSLAVE2();
RingAppend( &m->ring1, s1 );
RingPush( &m->ring2, s2 );
s1->free = FALSE;
s2->free = FALSE;
s1->master = m;
s2->master = m;
s1->sister = s2->next;
s2->brother = s1->next;
}
}
while( waste1 ) {
s1 = waste1;
waste1 = s1->next;
CarveFree( carveSLAVE1, s1 );
}
while( waste2 ) {
s2 = waste2;
waste2 = s2->next;
CarveFree( carveSLAVE2, s2 );
}
}
void markFreeMaster( void *p )
{
MASTER *m = p;
m->free = TRUE;
}
void markFreeSlave1( void *p )
{
SLAVE1 *s = p;
s->free = TRUE;
}
void markFreeSlave2( void *p )
{
SLAVE2 *s = p;
s->free = TRUE;
}
void saveMaster( void *e, carve_walk_base *d )
{
MASTER *m = e;
if( m->free ) {
return;
}
m->next = CarveGetIndex( carveMASTER, m->next );
m->ring1 = CarveGetIndex( carveSLAVE1, m->ring1 );
m->ring2 = CarveGetIndex( carveSLAVE2, m->ring2 );
m->test = CarveGetIndex( carveMASTER, m->test );
PCHWriteCVIndex( d->index );
PCHWrite( m, sizeof( *m ) );
}
void saveSlave1( void *e, carve_walk_base *d )
{
SLAVE1 *s = e;
if( s->free ) {
return;
}
s->next = CarveGetIndex( carveSLAVE1, s->next );
s->sister = CarveGetIndex( carveSLAVE2, s->sister );
s->master = CarveGetIndex( carveMASTER, s->master );
PCHWriteCVIndex( d->index );
PCHWrite( s, sizeof( *s ) );
}
void saveSlave2( void *e, carve_walk_base *d )
{
SLAVE2 *s = e;
if( s->free ) {
return;
}
s->next = CarveGetIndex( carveSLAVE2, s->next );
s->brother = CarveGetIndex( carveSLAVE1, s->brother );
s->master = CarveGetIndex( carveMASTER, s->master );
PCHWriteCVIndex( d->index );
PCHWrite( s, sizeof( *s ) );
}
pch_status PCHWriteTest( void )
{
void *mlist;
unsigned terminator = CARVE_NULL_INDEX;
auto carve_walk_base dm;
auto carve_walk_base d1;
auto carve_walk_base d2;
CarveWalkAllFree( carveMASTER, markFreeMaster );
CarveWalkAllFree( carveSLAVE1, markFreeSlave1 );
CarveWalkAllFree( carveSLAVE2, markFreeSlave2 );
mlist = CarveGetIndex( carveMASTER, masterList );
PCHWrite( &mlist, sizeof( mlist ) );
CarveWalkAll( carveMASTER, saveMaster, &dm );
PCHWriteCVIndex( terminator );
CarveWalkAll( carveSLAVE1, saveSlave1, &d1 );
PCHWriteCVIndex( terminator );
CarveWalkAll( carveSLAVE2, saveSlave2, &d2 );
PCHWriteCVIndex( terminator );
return( PCHCB_OK );
}
pch_status PCHReadTest( void )
{
MASTER *m;
SLAVE1 *s1;
SLAVE2 *s2;
cv_index mi;
auto cvinit_t data;
PCHRead( &masterList, sizeof( masterList ) );
masterList = CarveMapIndex( carveMASTER, masterList );
CarveInitStart( carveMASTER, &data );
for(;;) {
mi = PCHReadCVIndex();
if( mi == CARVE_NULL_INDEX ) break;
m = CarveInitElement( &data, mi );
PCHRead( m, sizeof( *m ) );
m->next = CarveMapIndex( carveMASTER, m->next );
m->ring1 = CarveMapIndex( carveSLAVE1, m->ring1 );
m->ring2 = CarveMapIndex( carveSLAVE2, m->ring2 );
m->test = CarveMapIndex( carveMASTER, m->test );
}
CarveInitStart( carveSLAVE1, &data );
for(;;) {
mi = PCHReadCVIndex();
if( mi == CARVE_NULL_INDEX ) break;
s1 = CarveInitElement( &data, mi );
PCHRead( s1, sizeof( *s1 ) );
s1->next = CarveMapIndex( carveSLAVE1, s1->next );
s1->master = CarveMapIndex( carveMASTER, s1->master );
s1->sister = CarveMapIndex( carveSLAVE2, s1->sister );
}
CarveInitStart( carveSLAVE2, &data );
for(;;) {
mi = PCHReadCVIndex();
if( mi == CARVE_NULL_INDEX ) break;
s2 = CarveInitElement( &data, mi );
PCHRead( s2, sizeof( *s2 ) );
s2->next = CarveMapIndex( carveSLAVE2, s2->next );
s2->master = CarveMapIndex( carveMASTER, s2->master );
s2->brother = CarveMapIndex( carveSLAVE1, s2->brother );
}
dumpMess();
return( PCHCB_OK );
}
pch_status PCHInitTest( boolean writing )
{
cv_index nm, ns1, ns2;
if( writing ) {
createMess();
dumpMess();
nm = CarveLastValidIndex( carveMASTER );
ns1 = CarveLastValidIndex( carveSLAVE1 );
ns2 = CarveLastValidIndex( carveSLAVE2 );
PCHWrite( &nm, sizeof( nm ) );
PCHWrite( &ns1, sizeof( ns1 ) );
PCHWrite( &ns2, sizeof( ns2 ) );
} else {
createMess();
carveMASTER = CarveRestart( carveMASTER );
carveSLAVE1 = CarveRestart( carveSLAVE1 );
carveSLAVE2 = CarveRestart( carveSLAVE2 );
PCHRead( &nm, sizeof( nm ) );
PCHRead( &ns1, sizeof( ns1 ) );
PCHRead( &ns2, sizeof( ns2 ) );
CarveMapOptimize( carveMASTER, nm );
CarveMapOptimize( carveSLAVE1, ns1 );
CarveMapOptimize( carveSLAVE2, ns2 );
}
return( PCHCB_OK );
}
pch_status PCHFiniTest( boolean writing )
{
if( ! writing ) {
CarveMapUnoptimize( carveMASTER );
CarveMapUnoptimize( carveSLAVE1 );
CarveMapUnoptimize( carveSLAVE2 );
}
return( PCHCB_OK );
}
#endif // NDEBUG
#endif // CARVEPCH
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?