示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
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 );
}
示例#5
0
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;
}
示例#6
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;
}