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; }
DirectResult fusion_shm_deinit( FusionWorld *world ) { int i; DirectResult ret; FusionSHM *shm; FusionSHMShared *shared; D_MAGIC_ASSERT( world, FusionWorld ); shm = &world->shm; D_MAGIC_ASSERT( shm, FusionSHM ); shared = shm->shared; D_MAGIC_ASSERT( shared, FusionSHMShared ); ret = fusion_skirmish_prevail( &shared->lock ); if (ret) return ret; /* Deinitialize shared data. */ if (fusion_master( world )) { D_ASSUME( shared->num_pools == 0 ); for (i=0; i<FUSION_SHM_MAX_POOLS; i++) { if (shared->pools[i].active) { D_MAGIC_ASSERT( &shared->pools[i], FusionSHMPoolShared ); D_MAGIC_ASSERT( &shm->pools[i], FusionSHMPool ); D_WARN( "destroying remaining '%s'", shared->pools[i].name ); fusion_shm_pool_destroy( world, &shared->pools[i] ); } } /* Destroy shared lock. */ fusion_skirmish_destroy( &shared->lock ); D_MAGIC_CLEAR( shared ); } else { for (i=0; i<FUSION_SHM_MAX_POOLS; i++) { if (shared->pools[i].active) { D_MAGIC_ASSERT( &shared->pools[i], FusionSHMPoolShared ); D_MAGIC_ASSERT( &shm->pools[i], FusionSHMPool ); fusion_shm_pool_detach( shm, &shared->pools[i] ); } } fusion_skirmish_dismiss( &shared->lock ); } D_MAGIC_CLEAR( shm ); return DR_OK; }
static int dfb_core_shutdown( CoreDFB *core, bool emergency ) { CoreDFBShared *shared; D_MAGIC_ASSERT( core, CoreDFB ); shared = core->shared; D_MAGIC_ASSERT( shared, CoreDFBShared ); /* Suspend input core to stop all input threads before shutting down. */ if (dfb_input_core.initialized) dfb_input_core.Suspend( dfb_input_core.data_local ); /* Destroy window objects. */ fusion_object_pool_destroy( shared->window_pool, core->world ); /* Close window stacks. */ if (dfb_wm_core.initialized) dfb_wm_close_all_stacks( dfb_wm_core.data_local ); fusion_stop_dispatcher( core->world, emergency ); /* Destroy layer context and region objects. */ fusion_object_pool_destroy( shared->layer_region_pool, core->world ); fusion_object_pool_destroy( shared->layer_context_pool, core->world ); /* Shutdown WM core. */ dfb_core_part_shutdown( core, &dfb_wm_core, emergency ); /* Shutdown layer core. */ dfb_core_part_shutdown( core, &dfb_layer_core, emergency ); dfb_core_part_shutdown( core, &dfb_screen_core, emergency ); /* Destroy surface and palette objects. */ fusion_object_pool_destroy( shared->graphics_state_pool, core->world ); fusion_object_pool_destroy( shared->surface_pool, core->world ); fusion_object_pool_destroy( shared->palette_pool, core->world ); /* Destroy remaining core parts. */ dfb_core_part_shutdown( core, &dfb_graphics_core, emergency ); dfb_core_part_shutdown( core, &dfb_surface_core, emergency ); dfb_core_part_shutdown( core, &dfb_input_core, emergency ); dfb_core_part_shutdown( core, &dfb_system_core, emergency ); dfb_core_part_shutdown( core, &dfb_colorhash_core, emergency ); dfb_core_part_shutdown( core, &dfb_clipboard_core, emergency ); /* Destroy shared memory pool for surface data. */ fusion_shm_pool_destroy( core->world, shared->shmpool_data ); return 0; }
static DFBResult sharedDestroyPool( CoreSurfacePool *pool, void *pool_data, void *pool_local ) { SharedPoolData *data = pool_data; SharedPoolLocalData *local = pool_local; D_MAGIC_ASSERT( pool, CoreSurfacePool ); fusion_shm_pool_destroy( local->world, data->shmpool ); 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 ); }
static int dfb_core_shutdown( CoreDFB *core, bool emergency ) { CoreDFBShared *shared; D_MAGIC_ASSERT( core, CoreDFB ); shared = core->shared; D_MAGIC_ASSERT( shared, CoreDFBShared ); /* Destroy layer context and region objects. */ fusion_object_pool_destroy( shared->layer_region_pool, core->world ); fusion_object_pool_destroy( shared->layer_context_pool, core->world ); /* Shutdown WM core. */ dfb_core_part_shutdown( core, &dfb_wm_core, emergency ); /* Destroy window objects. */ fusion_object_pool_destroy( shared->window_pool, core->world ); /* Shutdown layer core. */ dfb_core_part_shutdown( core, &dfb_layer_core, emergency ); dfb_core_part_shutdown( core, &dfb_screen_core, emergency ); /* Destroy surface and palette objects. */ fusion_object_pool_destroy( shared->surface_pool, core->world ); fusion_object_pool_destroy( shared->palette_pool, core->world ); /* Destroy remaining core parts. */ dfb_core_part_shutdown( core, &dfb_graphics_core, emergency ); dfb_core_part_shutdown( core, &dfb_surface_core, emergency ); dfb_core_part_shutdown( core, &dfb_input_core, emergency ); dfb_core_part_shutdown( core, &dfb_system_core, emergency ); dfb_core_part_shutdown( core, &dfb_colorhash_core, emergency ); dfb_core_part_shutdown( core, &dfb_clipboard_core, emergency ); /* Destroy shared memory pool for surface data. */ fusion_shm_pool_destroy( core->world, shared->shmpool_data ); return 0; }
static int dfb_core_arena_shutdown( FusionArena *arena, void *ctx, bool emergency) { DFBResult ret; CoreDFB *core = ctx; CoreDFBShared *shared; FusionSHMPoolShared *pool; D_MAGIC_ASSERT( core, CoreDFB ); shared = core->shared; D_MAGIC_ASSERT( shared, CoreDFBShared ); pool = shared->shmpool; D_DEBUG_AT( DirectFB_Core, "Shutting down...\n" ); if (!core->master) { D_WARN( "refusing shutdown in slave" ); return dfb_core_leave( core, emergency ); } CoreDFB_Deinit_Dispatch( &shared->call ); /* Shutdown. */ ret = dfb_core_shutdown( core, emergency ); fusion_skirmish_destroy( &shared->lock ); D_MAGIC_CLEAR( shared ); SHFREE( pool, shared ); fusion_shm_pool_destroy( core->world, pool ); return ret; }
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; }