static DFBResult sharedInitPool( CoreDFB *core, CoreSurfacePool *pool, void *pool_data, void *pool_local, void *system_data, CoreSurfacePoolDescription *ret_desc ) { DFBResult ret; SharedPoolData *data = pool_data; SharedPoolLocalData *local = pool_local; D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_ASSERT( ret_desc != NULL ); local->core = core; local->world = dfb_core_world( core ); ret = fusion_shm_pool_create( local->world, "Surface Memory Pool", dfb_config->surface_shmpool_size, fusion_config->debugshm, &data->shmpool ); if (ret) return ret; ret_desc->caps = CSPCAPS_VIRTUAL; ret_desc->access[CSAID_CPU] = CSAF_READ | CSAF_WRITE | CSAF_SHARED; ret_desc->types = CSTF_LAYER | CSTF_WINDOW | CSTF_CURSOR | CSTF_FONT | CSTF_SHARED | CSTF_INTERNAL; ret_desc->priority = (dfb_system_caps() & CSCAPS_PREFER_SHM) ? CSPP_PREFERED : CSPP_DEFAULT; if (dfb_system_caps() & CSCAPS_SYSMEM_EXTERNAL) ret_desc->types |= CSTF_EXTERNAL; snprintf( ret_desc->name, DFB_SURFACE_POOL_DESC_NAME_LENGTH, "Shared Memory" ); return DFB_OK; }
static DFBResult dfb_core_initialize( CoreDFB *core ) { int i; DFBResult ret; CoreDFBShared *shared; D_MAGIC_ASSERT( core, CoreDFB ); shared = core->shared; D_MAGIC_ASSERT( shared, CoreDFBShared ); ret = fusion_shm_pool_create( core->world, "DirectFB Data Pool", 0x1000000, fusion_config->debugshm, &shared->shmpool_data ); if (ret) return ret; shared->layer_context_pool = dfb_layer_context_pool_create( core->world ); shared->layer_region_pool = dfb_layer_region_pool_create( core->world ); shared->palette_pool = dfb_palette_pool_create( core->world ); shared->surface_pool = dfb_surface_pool_create( core->world ); shared->window_pool = dfb_window_pool_create( core->world ); for (i=0; i<D_ARRAY_SIZE(core_parts); i++) { DFBResult ret; if ((ret = dfb_core_part_initialize( core, core_parts[i] ))) { dfb_core_shutdown( core, true ); return ret; } } return DFB_OK; }
static int dfb_core_arena_initialize( FusionArena *arena, void *ctx ) { DFBResult ret; CoreDFB *core = ctx; CoreDFBShared *shared; FusionSHMPoolShared *pool; D_MAGIC_ASSERT( core, CoreDFB ); D_DEBUG_AT( DirectFB_Core, "Initializing...\n" ); /* Create the shared memory pool first! */ ret = fusion_shm_pool_create( core->world, "DirectFB Main Pool", 0x400000, fusion_config->debugshm, &pool ); if (ret) return ret; /* Allocate shared structure in the new pool. */ shared = SHCALLOC( pool, 1, sizeof(CoreDFBShared) ); if (!shared) { fusion_shm_pool_destroy( core->world, pool ); return D_OOSHM(); } core->shared = shared; core->master = true; shared->shmpool = pool; D_MAGIC_SET( shared, CoreDFBShared ); /* Initialize. */ ret = dfb_core_initialize( core ); if (ret) { D_MAGIC_CLEAR( shared ); SHFREE( pool, shared ); fusion_shm_pool_destroy( core->world, pool ); return ret; } fusion_skirmish_init( &shared->lock, "DirectFB Core", core->world ); CoreDFB_Init_Dispatch( core, core, &shared->call ); fusion_call_add_permissions( &shared->call, 0, FUSION_CALL_PERMIT_EXECUTE ); /* Register shared data. */ fusion_arena_add_shared_field( arena, "Core/Shared", shared ); return DFB_OK; }
static void bench_shmpool( bool debug ) { DirectResult ret; void *mem[256]; const int sizes[8] = { 12, 36, 200, 120, 39, 3082, 8, 1040 }; FusionSHMPoolShared *pool; ret = fusion_shm_pool_create( world, "Benchmark Pool", 524288, debug, &pool ); if (ret) { DirectFBError( "fusion_shm_pool_create() failed", ret ); return; } BENCH_START(); BENCH_LOOP() { int i; for (i=0; i<128; i++) mem[i] = SHMALLOC( pool, sizes[i&7] ); for (i=0; i<64; i++) SHFREE( pool, mem[i] ); for (i=128; i<192; i++) mem[i] = SHMALLOC( pool, sizes[i&7] ); for (i=64; i<128; i++) SHFREE( pool, mem[i] ); for (i=192; i<256; i++) mem[i] = SHMALLOC( pool, sizes[i&7] ); for (i=128; i<256; i++) SHFREE( pool, mem[i] ); } BENCH_STOP(); printf( "shm pool alloc/free %s -> %8.2f k/sec\n", debug ? "(debug)" : " ", BENCH_RESULT_BY(256) ); fusion_shm_pool_destroy( world, pool ); }
int main( int argc, char *argv[] ) { DirectResult ret; FusionWorld *world; StretRegion *root; StretRegion *child[16]; int child_num = 0; StretIteration iteration; DFBRegion clip; FusionSHMPoolShared *pool; ret = fusion_enter( -1, 0, FER_ANY, &world ); if (ret) return -1; ret = fusion_shm_pool_create( world, "StReT Test Pool", 0x10000, direct_config->debug, &pool ); if (ret) { fusion_exit( world, false ); return -1; } D_INFO( "StReT/Test: Starting...\n" ); ret = stret_region_create( 0, NULL, 0, SRF_ACTIVE, 2, 0, 0, 1000, 1000, NULL, 0, pool, &root ); if (ret) { D_DERROR( ret, "StReT/Test: Could not create root region!\n" ); goto error_root; } else { ret = stret_region_create( 0, NULL, 0, SRF_ACTIVE, 1, 10, 10, 100, 100, root, 1, pool, &child[child_num++] ); if (ret) { D_DERROR( ret, "StReT/Test: Could not create child region!\n" ); goto error_child; } else { ret = stret_region_create( 0, NULL, 0, SRF_ACTIVE, 1, 50, 50, 30, 30, child[0], 0, pool, &child[child_num++] ); if (ret) { D_DERROR( ret, "StReT/Test: Could not create child region!\n" ); goto error_child; } ret = stret_region_create( 0, NULL, 0, SRF_ACTIVE, 1, 20, 20, 30, 30, child[0], 0, pool, &child[child_num++] ); if (ret) { D_DERROR( ret, "StReT/Test: Could not create child region!\n" ); goto error_child; } else { ret = stret_region_create( 0, NULL, 0, SRF_ACTIVE, 1, 10, 10, 10, 10, child[2], 0, pool, &child[child_num++] ); if (ret) { D_DERROR( ret, "StReT/Test: Could not create child region!\n" ); goto error_child; } ret = stret_region_create( 0, NULL, 0, SRF_ACTIVE, 1, 20, 20, 10, 10, child[2], 0, pool, &child[child_num++] ); if (ret) { D_DERROR( ret, "StReT/Test: Could not create child region!\n" ); goto error_child; } } } ret = stret_region_create( 0, NULL, 0, SRF_ACTIVE, 1, 200, 10, 200, 200, root, 0, pool, &child[child_num++] ); if (ret) { D_DERROR( ret, "StReT/Test: Could not create child region!\n" ); goto error_child; } } stret_iteration_init( &iteration, root, NULL ); clip = (DFBRegion) { 50, 50, 200, 59 }; D_ASSERT( stret_iteration_next( &iteration, &clip ) == child[4] ); //D_ASSERT( stret_iteration_next( &iteration, &clip ) == child[3] ); D_ASSERT( stret_iteration_next( &iteration, &clip ) == child[2] ); //D_ASSERT( stret_iteration_next( &iteration, &clip ) == child[1] ); D_ASSERT( stret_iteration_next( &iteration, &clip ) == child[0] ); D_ASSERT( stret_iteration_next( &iteration, &clip ) == child[5] ); D_ASSERT( stret_iteration_next( &iteration, &clip ) == root ); D_ASSERT( stret_iteration_next( &iteration, &clip ) == NULL ); stret_region_destroy( child[child_num-1] ); error_child: while (--child_num) stret_region_destroy( child[child_num-1] ); stret_region_destroy( root ); error_root: fusion_shm_pool_destroy( world, pool ); fusion_exit( world, false ); return 0; }
int main( int argc, char *argv[] ) { DirectResult ret; FusionWorld *world; FusionCall call = {0}; FusionSHMPoolShared *pool; void *buffer; int i, max_busy = 0, active = 1; long long t1 = 0, t2; long long start = 0; long long bytes = 0; long long last_bytes = 0; unsigned long blocks = 0; unsigned long last_blocks = 0; unsigned long last_busy = 0; u32 checksum = 0; bool produce = true; int delay = 66000; if (parse_cmdline( argc, argv )) return -1; if (bit_rate) { int blocks_per_sec = (bit_rate * 1024 / 8) / block_size; if (blocks_per_sec < 100) delay = 900000 / blocks_per_sec - 2000; else delay = 300000 * 100 / blocks_per_sec; num_blocks = bit_rate * 1024 / 8 / block_size * delay / 900000; if (num_blocks > MAX_NUM_BLOCKS) num_blocks = MAX_NUM_BLOCKS; if (!num_blocks) { num_blocks = 1; delay = 970 * block_size / (bit_rate * 1024 / 8) * 1000 - 2000; } } sync(); if (run_busy) { pthread_create( &busy_thread, NULL, busy_loop, NULL ); printf( "Calibrating...\n" ); pthread_mutex_lock( &busy_lock ); for (i=0; i<7; i++) { int busy_rate; busy_count = 0; t1 = get_millis(); pthread_mutex_unlock( &busy_lock ); usleep( 300000 ); pthread_mutex_lock( &busy_lock ); t2 = get_millis(); busy_rate = busy_count * 1000 / (t2 - t1); if (busy_rate > max_busy) max_busy = busy_rate; } printf( "Calibrating done. (%d busy counts/sec)\n", max_busy ); } ret = fusion_enter( -1, 23, FER_MASTER, &world ); if (ret) return ret; ret = fusion_call_init( &call, call_handler, NULL, world ); if (ret) return ret; ret = fusion_shm_pool_create( world, "Stream Buffer", block_size + 8192, false, &pool ); if (ret) return ret; ret = fusion_shm_pool_allocate( pool, block_size, false, true, &buffer ); if (ret) return ret; /* * Do the fork() magic! */ if (do_fork) { fusion_world_set_fork_action( world, FFA_FORK ); switch (fork()) { case -1: D_PERROR( "fork() failed!\n" ); return -1; case 0: /* child continues as the producer */ run_busy = false; break; default: /* parent is the consumer (callback in Fusion Dispatch thread) */ produce = false; usleep( 50000 ); } fusion_world_set_fork_action( world, FFA_CLOSE ); } start = t1 = get_millis(); if (run_busy) { busy_count = 0; pthread_mutex_unlock( &busy_lock ); } #ifdef LINUX_2_4 delay -= 10000; #endif do { if (bit_rate || !produce) { if (delay > 10) usleep( delay ); } if (produce) { for (i=0; i<num_blocks; i++) { int n; u32 retsum; u32 *values = buffer; for (n=0; n<block_size/4; n++) { values[n] = n; checksum += n; } bytes += block_size; fusion_call_execute( &call, do_thread ? FCEF_NODIRECT : FCEF_NONE, 0, buffer, (int*) &retsum ); if (retsum != checksum) D_ERROR( "Checksum returned by consumer (0x%08x) does not match 0x%08x!\n", retsum, checksum ); } blocks += num_blocks; } t2 = get_millis(); if (t2 - t1 > 2000) { if (produce) { long long kbits = 0, avgkbits, total_time, diff_time, diff_bytes; printf( "\n\n\n" ); total_time = t2 - start; diff_time = t2 - t1; diff_bytes = bytes - last_bytes; avgkbits = (long long)bytes * 8LL * 1000LL / (long long)total_time / 1024LL; if (diff_time) kbits = (long long)diff_bytes * 8LL * 1000LL / (long long)diff_time / 1024LL; printf( "Total Time: %7lld ms\n", total_time ); printf( "Stream Size: %7lld kb\n", bytes / 1024 ); printf( "Stream Rate: %7lld kb/sec -> %lld.%03lld MBit (avg. %lld.%03lld MBit)\n", kbits / 8, (kbits * 1000 / 1024) / 1000, (kbits * 1000 / 1024) % 1000, (avgkbits * 1000 / 1024) / 1000, (avgkbits * 1000 / 1024) % 1000 ); printf( "\n" ); if (last_bytes && bit_rate) { long long diff_bytes = (bytes - last_bytes) * 1000 / (t2 - t1); long long need_bytes = bit_rate * 1024 / 8; if (diff_bytes) { int new_blocks = (num_blocks * need_bytes + diff_bytes/2) / diff_bytes; num_blocks = (new_blocks + num_blocks + 1) / 2; if (num_blocks > MAX_NUM_BLOCKS) num_blocks = MAX_NUM_BLOCKS; } } read_stat(); if (ftotal != ctotal && dtotal) { int load, aload; load = 1000 - didle * 1000 / dtotal; aload = 1000 - (cidle - fidle) * 1000 / (ctotal - ftotal); printf( "Overall Stats\n" ); printf( " Total Time: %7lld ms\n", t2 - start ); printf( " Block Size: %7ld\n", block_size ); printf( " Blocks/cycle: %7ld\n", num_blocks ); printf( " Blocks/second: %7lld\n", (blocks - last_blocks) * 1000 / diff_time ); printf( " Delay: %7d\n", delay ); printf( " CPU Load: %5d.%d %% (avg. %d.%d %%)\n", load / 10, load % 10, aload / 10, aload % 10 ); } last_bytes = bytes; last_blocks = blocks; } if (run_busy) { pthread_mutex_lock( &busy_lock ); if (last_busy) { int busy_diff; int busy_rate, busy_load; int abusy_rate, abusy_load; busy_diff = busy_count - last_busy; busy_rate = max_busy - (busy_diff * 1000 / (t2 - t1)); busy_load = busy_rate * 1000 / max_busy; abusy_rate = max_busy - (busy_count * 1000 / (t2 - start)); abusy_load = abusy_rate * 1000 / max_busy; printf( " Real CPU Load: %5d.%d %% (avg. %d.%d %%)\n", busy_load / 10, busy_load % 10, abusy_load / 10, abusy_load % 10 ); } last_busy = busy_count; pthread_mutex_unlock( &busy_lock ); } t1 = t2; } } while (active > 0); if (run_busy) { busy_alive = 0; pthread_join( busy_thread, NULL ); } return -1; }