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 + -
显示快捷键?