getsamps.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 522 行 · 第 1/2 页

C
522
字号
    map_count = curr_image->map_count + new_count;
    map = curr_image->map_data;
    if( map == NULL ) {
        map = ProfAlloc( map_count * sizeof(*map) );
    } else {
        map = ProfRealloc( map, map_count * sizeof(*map) );
    }
    for( i = 0, j = curr_image->map_count; i < new_count; ++i, ++j ) {
        map[j].map.mach.segment    = data->map.data[i].map.segment;
        map[j].map.mach.offset     = data->map.data[i].map.offset;
        map[j].actual.mach.segment = data->map.data[i].actual.segment;
        map[j].actual.mach.offset  = data->map.data[i].actual.offset;
        map[j].length              = 0xffff; //NYI: get from executable....
    }
    curr_image->map_count = map_count;
    curr_image->map_data = map;
}



STATIC void procRemapBlock( clicks_t tick, uint_16 total_len,
                                             samp_data *data )
/************************************************************/
{
    remap_data      *new_remap;
    int             count;
    int             index;

    index = 0;
    total_len -= offsetof( samp_block, d.remap );
    count = total_len / sizeof( remapping );
    while( count-- > 0 ) {
        new_remap = ProfCAlloc( sizeof(remap_data) );
        if( CurrSIOData->remaps == NULL ) {
            new_remap->next = new_remap;
        } else {
            new_remap->next = CurrSIOData->remaps->next;
            CurrSIOData->remaps->next = new_remap;
        }
        CurrSIOData->remaps = new_remap;
        new_remap->tick = tick;
        new_remap->section = data->remap.data[index].section;
        new_remap->segment = data->remap.data[index].segment;
        index++;
    }
}



STATIC bint procSampleBlock( clicks_t tick, uint_16 total_len,
                                              samp_data *data )
/*************************************************************/
{
    thread_id   thread;
    unsigned    data_index;
    unsigned    index;
    unsigned    index2;
    unsigned    count;
    unsigned    buckets;
    clicks_t    end_tick;
    ldiv_t      div_result;
    thread_data *thd;
    thread_data **owner;
    address     *samp;

    thread = data->sample.thread_id;
    total_len -= offsetof( samp_block, d.sample );
    count = total_len / sizeof( samp_address );
    CurrSIOData->total_samples += count;
    end_tick = tick + count;
    owner = &CurrSIOData->samples;
    for( ;; ) {
        thd = *owner;
        if( thd == NULL ) {
            thd = ProfAlloc( sizeof( *thd ) );
            *owner = thd;
            thd->next = NULL;
            thd->thread = thread;
            thd->start_time = tick;
            thd->end_time = end_tick;
            buckets = RAW_BUCKET_IDX( count ) + 1;
            thd->raw_bucket = ProfAlloc( buckets * sizeof( *thd->raw_bucket ) );
            for( index = 0; index < buckets; ++index ) {
                thd->raw_bucket[index] = ProfCAlloc( MAX_RAW_BUCKET_SIZE );
            }
            break;

        }
        if( thd->thread == thread ) break;
        owner = &thd->next;
    }
    if( end_tick > thd->end_time ) {
        index = RAW_BUCKET_IDX( thd->end_time - thd->start_time ) + 1;
        buckets = RAW_BUCKET_IDX( end_tick - thd->start_time ) + 1;
        if( buckets > index ) {
            thd->raw_bucket = ProfRealloc( thd->raw_bucket, buckets * sizeof( *thd->raw_bucket ) );
            for( ; index < buckets; ++index ) {
                thd->raw_bucket[index] = ProfCAlloc( MAX_RAW_BUCKET_SIZE );
            }
        }
        thd->end_time = end_tick;
    }


    div_result = ldiv( tick - thd->start_time, MAX_RAW_BUCKET_INDEX );
    index = div_result.quot;
    index2 = div_result.rem;
    data_index = 0;
    while( count > 0 ) {
        samp = &thd->raw_bucket[index][index2];
        samp->mach.segment = data->sample.sample[data_index].segment;
        samp->mach.offset  = data->sample.sample[data_index].offset;
        if( ++index2 >= MAX_RAW_BUCKET_INDEX ) {
            index2 = 0;
            ++index;
        }
        ++data_index;
        --count;
    }
    return( B_TRUE );
}



STATIC bint readSampleFile( void )
/********************************/
{
    file_handle             fh;
    uint_16                 size;
    void                    *buff;
    int                     buff_len;
    off_t                   start_position;
    bint                    main_exe;
    samp_block_prefix       prefix;
    samp_block_prefix       *next_prefix;

/* we can add error checking for things like */
/**/
/*    - number of samples match the info # of samples */
/*    - main exe load if there is an overlay table */
/**/
    fh = CurrSIOData->fh;
    start_position = lseek( fh, CurrSIOData->header.sample_start, SEEK_SET );
    if( start_position == (off_t) -1 ) {
        ErrorMsg( LIT( Smp_File_IO_Err ), CurrSIOData->samp_file_name );
        return( B_FALSE );
    }
    if( read( fh, &prefix, SIZE_PREFIX ) != SIZE_PREFIX ) {
        ErrorMsg( LIT( Smp_File_IO_Err ), CurrSIOData->samp_file_name );
        return( B_FALSE );
    }
    buff = ProfAlloc( SIZE_DATA );
    buff_len = SIZE_DATA;
    main_exe = B_FALSE;
    while( prefix.kind != SAMP_LAST ) {
        size = prefix.length;
        if( buff_len < size ) {
            buff = ProfRealloc( buff, size );
            buff_len = size;
        }
        /* reads data & next prefix */
        if( BigRead( fh, buff, size ) != size ) {
            ErrorMsg( LIT( Smp_File_IO_Err ), CurrSIOData->samp_file_name );
            ProfFree( buff );
            return( B_FALSE );
        }
        next_prefix = (void *)( ((char *) buff) + ( size - SIZE_PREFIX ));

        /* if we're reading a sample record from a callgraph sample */
        /* file, the next record should contain callgraph information */
        /* which we will also want stored in memory for processing */
        /* 16-jul-92 CMS */

//        if( CallGraph && prefix.kind == SAMP_SAMPLES &&
//                         next_prefix->kind == SAMP_CALLGRAPH ) {
//            size = next_prefix->length;
//            /* reads callgraph data & next prefix   */
//            if( BigRead( fh, next_prefix, size ) != size ) {
//                errorIO();
//                ProfFree( buff );
//                ErrorMsg( LIT( Smp_File_IO_Err ), CurrSIOData->samp_file_name );
//                return( B_FALSE );
//            }
//            next_prefix = (void *)( ((char *) next_prefix) + ( size - SIZE_PREFIX ));
//        }

        switch( prefix.kind ) {
        case SAMP_INFO:
            procInfoBlock( prefix.tick, buff );
            break;
        case SAMP_SAMPLES:
            if( !procSampleBlock( prefix.tick, prefix.length, buff ) ) {
                return( B_FALSE );
            }
            break;
        case SAMP_MARK:
            procMarkBlock( prefix.tick, buff );
            break;
        case SAMP_OVL_LOAD:
            procOverlayBlock( prefix.tick, buff );
            break;
        case SAMP_ADDR_MAP:
            procAddrBlock( prefix.length, buff );
            break;
        case SAMP_MAIN_LOAD:
            main_exe = B_TRUE;
            /* fall through */
        case SAMP_CODE_LOAD:
            procImageBlock( buff, main_exe );
            main_exe = B_FALSE;
            break;
        case SAMP_REMAP_SECTION:
            procRemapBlock( prefix.tick, prefix.length, buff );
            break;
        case SAMP_CALLGRAPH:
//            printf( "sample callgraph\n" );
            break;
        }
        prefix = *next_prefix;
    }
    ProfFree( buff );
    return( B_TRUE );
}



extern bint GetSampleInfo( void )
/*******************************/
{
    if( !initCurrSIO() ) {
        return( B_FALSE );
    }
    if( !verifyHeader() ) {
        ClearSample( CurrSIOData );
        return( B_FALSE );
    }
    if( !readSampleFile() ) {
        ClearSample( CurrSIOData );
        return( B_FALSE );
    }
    /* there must be at least one address map for the first module, or */
    /* we cannot resolve overlays and do mapping.  Should generate an error*/
    if( !LoadImageOverlays() ) {
        ClearSample( CurrSIOData );
        return( B_FALSE );
    }
    close( CurrSIOData->fh );
    /* do the SIOData sets near the end to make it easier to de-link */
    /* the new data if we have an error */
    if( SIOData == NULL ) {
        CurrSIOData->next = CurrSIOData;
    } else {
        CurrSIOData->next = SIOData->next;
        SIOData->next = CurrSIOData;
    }
    SIOData = CurrSIOData;
    SetSampleInfo( CurrSIOData );
    SamplePath[0] = 0;
    return( B_TRUE );
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?