Ejemplo n.º 1
0
unsigned VMShrink()
{
    int                 i;
    int                 j;
    unsigned            kill_time;
    unsigned            kill_i;
    unsigned            kill_j;
    virt_page           *pg;
    imp_image_handle    *ii;

    kill_time = UINT_MAX;
    kill_i = 0;
    kill_j = 0;
    for( ii = ImageList; ii != NULL; ii = ii->next_image ) {
        if( ii->virt != NULL ) {
            for( i = ii->vm_dir_num-1; i >= 0; --i ) {
                if( ii->virt[i] != NULL ) {
                    for( j = DIR_SIZE-1; j >= 0; --j ) {
                        pg = ii->virt[i][j];
                        if( pg != NULL && pg->offset == 0 ) {
                            if( kill_time > pg->block->time_stamp ) {
                                kill_time = pg->block->time_stamp;
                                kill_i = i;
                                kill_j = j;
                            }
                        }
                    }
                }
            }
        }
    }
    if( kill_time == UINT_MAX ) return( 0 );
    return( KillPages( ii, kill_i, kill_j ) );
}
Ejemplo n.º 2
0
unsigned VMShrink( void )
{
    int                 i;
    int                 j;
    unsigned            kill_time;
    unsigned            kill_i;
    unsigned            kill_j;
    virt_page           *pg;
    imp_image_handle    *iih;
    imp_image_handle    *kill_iih;

    kill_time = UINT_MAX;
    kill_i = 0;
    kill_j = 0;
    kill_iih = NULL;
    /* search oldest page by time_stamp */
    for( iih = ImageList; iih != NULL; iih = iih->next_image ) {
        if( iih->virt != NULL ) {
            for( i = iih->vm_dir_num-1; i >= 0; --i ) {
                if( iih->virt[i] != NULL ) {
                    for( j = DIR_SIZE-1; j >= 0; --j ) {
                        pg = iih->virt[i][j];
                        if( pg != NULL && pg->offset == 0 ) {
                            if( kill_time > pg->block->time_stamp ) {
                                kill_time = pg->block->time_stamp;
                                kill_i = i;
                                kill_j = j;
                                kill_iih = iih;
                            }
                        }
                    }
                }
            }
        }
    }
    if( kill_iih == NULL )
        return( 0 );
    return( KillPages( kill_iih, kill_i, kill_j ) );
}
Ejemplo n.º 3
0
void *VMBlock( imp_image_handle *iih, virt_mem start, size_t len )
{
    unsigned            dir_idx;
    unsigned            pg_idx;
    unsigned            tmp_idx;
    unsigned            i;
    unsigned            j;
    unsigned            num_pages;
    virt_mem            pg_start;
    virt_page           *pg;
    virt_page           *zero;
    loaded_block        *block;

    dir_idx = GET_DIR( start );
    if( iih->virt[dir_idx] == NULL ) {
        if( !InitPageDir( iih, dir_idx ) ) {
            return( NULL );
        }
    }
    pg_idx = GET_PAGE( start );
    len += start % VM_PAGE_SIZE;
    pg_start = start & ~(virt_mem)(VM_PAGE_SIZE - 1);
    pg = iih->virt[dir_idx][pg_idx];
    if( pg == NULL || ( pg->block->len - pg->offset ) < len ) {
        /* unloaded previously loaded block */
        if( pg != NULL ) {
            tmp_idx = dir_idx;
            /* find first page of the block */
            i = pg_idx;
            for( ;; ) {
                iih->virt[tmp_idx][i] = NULL;
                if( pg->offset == 0 )
                    break;
                if( i == 0 ) {
                    --tmp_idx;
                    i = DIR_SIZE;
                }
                --i;
                --pg;
            }
            DCFree( pg );
        }
        num_pages = BLOCK_FACTOR( len, VM_PAGE_SIZE );
        pg = DCAlloc( num_pages * ( sizeof( *pg ) + VM_PAGE_SIZE ) + sizeof( loaded_block ) - 1 );
        if( pg == NULL ) {
            DCStatus( DS_ERR | DS_NO_MEM );
            return( NULL );
        }
        /* set up new page table entries */
        block = (loaded_block *)&pg[num_pages];
        tmp_idx = dir_idx;
        for( j = pg_idx, i = 0; i < num_pages; ++j, ++i ) {
            pg[i].block = block;
            pg[i].offset = i * VM_PAGE_SIZE;
            if( j >= DIR_SIZE ) {
                ++tmp_idx;
                j = 0;
            }
            if( iih->virt[tmp_idx] == NULL ) {
                if( !InitPageDir( iih, tmp_idx ) ) {
                    /* unwind the setup already done */
                    num_pages = i;
                    for( i = 0; i < num_pages; ++i, ++pg_idx ) {
                        if( pg_idx >= DIR_SIZE ) {
                            ++dir_idx;
                            pg_idx = 0;
                        }
                        iih->virt[dir_idx][pg_idx] = NULL;
                    }
                    DCFree( pg );
                    return( NULL );
                }
            }
            if( iih->virt[tmp_idx][j] != NULL ) {
                /*
                    We just ran into another allocated block, so we have
                    to kill all the pages mapped in by it. We know that
                    if the page pointer is non-NULL, it will be offset==0
                    since KillPages will clean out the others.
                */
                KillPages( iih, tmp_idx, j );
            }
            iih->virt[tmp_idx][j] = &pg[i];
        }
        /* read in new block */
        len = num_pages * VM_PAGE_SIZE;
        block->len = len;
        pg_start += iih->bias;
        if( DCSeek( iih->sym_fp, pg_start, DIG_ORG ) ) {
            DCStatus( DS_ERR | DS_FSEEK_FAILED );
            return( NULL );
        }
        /* last block might be a short read */
        if( DCRead( iih->sym_fp, pg->block->data, len ) == DIG_RW_ERROR ) {
            DCStatus( DS_ERR | DS_FREAD_FAILED );
            return( NULL );
        }
        pg = iih->virt[dir_idx][pg_idx];
    }
    ++TimeStamp;
    if( TimeStamp == 0 ) {
        /* deal with wrap-around */
        for( iih = ImageList; iih != NULL; iih = iih->next_image ) {
            if( iih->virt != NULL ) {
                for( i = iih->vm_dir_num; i-- > 0; ) {
                    if( iih->virt[i] != NULL ) {
                        for( j = DIR_SIZE; j-- > 0; ) {
                            zero = iih->virt[i][j];
                            if( zero != NULL ) {
                                zero->block->time_stamp = 0;
                            }
                        }
                    }
                }
            }
        }
        ++TimeStamp;
    }
    pg->block->time_stamp = TimeStamp;
    return( &pg->block->data[(start & (VM_PAGE_SIZE - 1)) + pg->offset] );
}