Example #1
0
void bli_pool_checkout_block( pblk_t* block, pool_t* pool )
{
	pblk_t* block_ptrs;
	dim_t   top_index;

	// If the pool is exhausted, add a block.
	if ( bli_pool_is_exhausted( pool ) )
	{
		bli_pool_grow( 1, pool );
	}

	// At this point, at least one block is guaranteed to be available.

	// Query the current block_ptrs array.
	block_ptrs = bli_pool_block_ptrs( pool );

	// Query the top_index of the pool.
	top_index = bli_pool_top_index( pool );

	// Copy the block at top_index to the caller's pblk_t struct.
	//bli_pblk_copy( *(block_ptrs[top_index]), *block );
	*block = block_ptrs[top_index];

	// Notice that we don't actually need to clear the contents of
	// block_ptrs[top_index]. It will get overwritten eventually when
	// the block is checked back in.
	bli_pblk_clear( &block_ptrs[top_index] );

	// Increment the pool's top_index.
	bli_pool_set_top_index( top_index + 1, pool );
}
Example #2
0
void bli_pool_shrink( dim_t num_blocks_sub, pool_t* pool )
{
	pblk_t* block_ptrs;
	dim_t   num_blocks;
	dim_t   num_blocks_avail;
	dim_t   num_blocks_new;

	dim_t   top_index;

	dim_t   i;

	// Query the total number of blocks presently allocated.
	num_blocks = bli_pool_num_blocks( pool );

	// Query the top_index of the pool.
	top_index = bli_pool_top_index( pool );

	// Compute the number of blocks available to be checked out
	// (and thus available for removal).
	num_blocks_avail = num_blocks - top_index;

	// If the requested decrease is more than the number of available
	// blocks in the pool, only remove the number of blocks available.
	if ( num_blocks_avail < num_blocks_sub )
		num_blocks_sub = num_blocks_avail;

	// If the effective requested decrease is zero (or the requested
	// decrease was negative), return early.
	if ( num_blocks_sub < 1 ) return;

	// Query the current block_ptrs array.
	block_ptrs = bli_pool_block_ptrs( pool );

	// Compute the new total number of blocks.
	num_blocks_new = num_blocks - num_blocks_sub;

	// Free the individual blocks.
	for ( i = num_blocks_new; i < num_blocks; ++i )
	{
		bli_pool_free_block( &(block_ptrs[i]) );
	}

	// Update the pool_t struct.
	bli_pool_set_num_blocks( num_blocks_new, pool );

	// Note that after shrinking the pool, num_blocks < block_ptrs_len.
	// This means the pool can grow again by num_blocks_sub before
	// a re-allocation of block_ptrs is triggered.
}
Example #3
0
void bli_pool_checkin_block( pblk_t* block, pool_t* pool )
{
	pblk_t* block_ptrs;
	dim_t   top_index;

	// Query the current block_ptrs array.
	block_ptrs = bli_pool_block_ptrs( pool );

	// Query the top_index of the pool.
	top_index = bli_pool_top_index( pool );

	// Copy the caller's pblk_t struct to the block at top_index - 1.
	//bli_pblk_copy( *(block_ptrs[top_index-1]), *block );
	block_ptrs[top_index-1] = *block;

	// Decrement the pool's top_index.
	bli_pool_set_top_index( top_index - 1, pool );
}
Example #4
0
void bli_pool_finalize( pool_t* pool )
{
	pblk_t* block_ptrs;
	dim_t   num_blocks;
	dim_t   top_index;
	dim_t   i;

	// NOTE: This implementation assumes that either:
	// - all blocks have been checked in by all threads, or
	// - some subset of blocks have been checked in and the caller
	//   is bli_pool_reinit().

	// Query the current block_ptrs array.
	block_ptrs = bli_pool_block_ptrs( pool );

	// Query the total number of blocks presently allocated.
	num_blocks = bli_pool_num_blocks( pool );

	// Query the top_index of the pool.
	top_index  = bli_pool_top_index( pool );

	// Free the individual blocks currently in the pool.
	for ( i = top_index; i < num_blocks; ++i )
	{
		bli_pool_free_block( &(block_ptrs[i]) );
	}

	// Free the block_ptrs array.
	bli_free( block_ptrs );

	// Clear the contents of the pool_t struct.
	bli_pool_set_block_ptrs( NULL, pool );
	bli_pool_set_block_ptrs_len( 0, pool );
	bli_pool_set_num_blocks( 0, pool );
	bli_pool_set_top_index( 0, pool );
	bli_pool_set_block_size( 0, pool );
	bli_pool_set_align_size( 0, pool );
}
Example #5
0
File: bli_pool.c Project: rwl/blis
void bli_pool_finalize( pool_t* pool )
{
	pblk_t* block_ptrs;
	dim_t   num_blocks;
	dim_t   i;

	// NOTE: This implementation assumes that all blocks have been
	// checked in by all threads.

	// Query the current block_ptrs array and total number of blocks
	// presently allocated.
	block_ptrs = bli_pool_block_ptrs( pool );
	num_blocks = bli_pool_num_blocks( pool );

	// Free the individual blocks.
	for ( i = 0; i < num_blocks; ++i )
	{
		bli_pool_free_block( &(block_ptrs[i]) );
	}

	// Free the block_ptrs array.
	bli_free( block_ptrs );
}
Example #6
0
void bli_pool_print( pool_t* pool )
{
	pblk_t* block_ptrs     = bli_pool_block_ptrs( pool );
	dim_t   block_ptrs_len = bli_pool_block_ptrs_len( pool );
	dim_t   top_index      = bli_pool_top_index( pool );
	dim_t   num_blocks     = bli_pool_num_blocks( pool );
	dim_t   block_size     = bli_pool_block_size( pool );
	dim_t   align_size     = bli_pool_align_size( pool );
	dim_t   i;

	printf( "pool struct ---------------\n" );
	printf( "  block_ptrs:      %p\n", block_ptrs );
	printf( "  block_ptrs_len:  %ld\n", block_ptrs_len );
	printf( "  top_index:       %ld\n", top_index );
	printf( "  num_blocks:      %ld\n", num_blocks );
	printf( "  block_size:      %ld\n", block_size );
	printf( "  align_size:      %ld\n", align_size );
	printf( "  pblks   sys    align\n" );
	for ( i = 0; i < num_blocks; ++i )
	{
	printf( "  %ld: %p %p\n", i, bli_pblk_buf_sys(   &block_ptrs[i] ),
	                             bli_pblk_buf_align( &block_ptrs[i] ) );
	}
}
Example #7
0
void bli_pool_grow( dim_t num_blocks_add, pool_t* pool )
{
	pblk_t* block_ptrs_cur;
	dim_t   block_ptrs_len_cur;
	dim_t   num_blocks_cur;

	pblk_t* block_ptrs_new;
	dim_t   num_blocks_new;

	siz_t   block_size;
	siz_t   align_size;
	dim_t   top_index;

	dim_t   i;

	// If the requested increase is zero (or negative), return early.
	if ( num_blocks_add < 1 ) return;

	// Query the allocated length of the block_ptrs array and also the
	// total number of blocks allocated.
	block_ptrs_len_cur = bli_pool_block_ptrs_len( pool );
	num_blocks_cur     = bli_pool_num_blocks( pool );

	// Compute the total number of allocated blocks that will exist
	// after we grow the pool.
	num_blocks_new = num_blocks_cur + num_blocks_add;

	// If the new total number of allocated blocks is larger than the
	// allocated length of the block_ptrs array, we need to allocate
	// a new (larger) block_ptrs array.
	if ( num_blocks_new > block_ptrs_len_cur )
	{
		// Query the current block_ptrs array.
		block_ptrs_cur = bli_pool_block_ptrs( pool );

		// Allocate a new block_ptrs array of length num_blocks_new.
		block_ptrs_new = bli_malloc( num_blocks_new * sizeof( pblk_t ) );

		// Query the top_index of the pool.
		top_index = bli_pool_top_index( pool );

		// Copy the contents of the old block_ptrs array to the new/resized
		// array. Notice that we can begin with top_index since all entries
		// from 0 to top_index-1 have been checked out to threads.
		for ( i = top_index; i < num_blocks_cur; ++i ) 
		{
//printf( "bli_pool_grow: copying from %lu\n", top_index );
			block_ptrs_new[i] = block_ptrs_cur[i];
		}

//printf( "bli_pool_grow: bp_cur: %p\n", block_ptrs_cur );
		// Free the old block_ptrs array.
		bli_free( block_ptrs_cur );

		// Update the pool_t struct with the new block_ptrs array and
		// record its allocated length.
		bli_pool_set_block_ptrs( block_ptrs_new, pool );
		bli_pool_set_block_ptrs_len( num_blocks_new, pool );
	}

	// At this point, we are guaranteed to have enough unused elements
	// in the block_ptrs array to accommodate an additional num_blocks_add
	// blocks.

	// Query the current block_ptrs array (which was possibly just resized).
	block_ptrs_cur = bli_pool_block_ptrs( pool );

	// Query the block size and alignment size of the current pool.
	block_size = bli_pool_block_size( pool );
	align_size = bli_pool_align_size( pool );

	// Allocate the requested additional blocks in the resized array.
	for ( i = num_blocks_cur; i < num_blocks_new; ++i ) 
	{
//printf( "libblis: growing pool, block_size = %lu\n", block_size ); fflush( stdout );

		bli_pool_alloc_block( block_size, align_size, &(block_ptrs_cur[i]) );
	}

	// Update the pool_t struct with the new number of allocated blocks.
	// Notice that top_index remains unchanged, as do the block_size and
	// align_size fields.
	bli_pool_set_num_blocks( num_blocks_new, pool );
}