Ejemplo n.º 1
0
int gensetdyn_new (gensetdyn_ref g, unsigned int *i)
{
  register unsigned int r = freelist_pop(g->freelist.s, &g->freelist.len, g->storage.len) ;
  if (r >= g->storage.len)
  {
    if (!gensetdyn_readyplus(g, 1)) return 0 ;
    r = freelist_pop(g->freelist.s, &g->freelist.len, g->storage.len) ;
  }
  *i = r ;
  return 1 ;
}
Ejemplo n.º 2
0
void freelist_delete( struct freelist_state *fs, void (*user_data_delete_function)(void *user_data, void *user_state), void *user_state )
{
  struct freelist_element
    *fe;

  void
    *user_data;

  assert( fs != NULL );
  // TRD : user_data_delete_function can be NULL
  // TRD : user_state can be NULL

  while( freelist_pop(fs, &fe) )
  {
    if( user_data_delete_function != NULL )
    {
      freelist_get_user_data_from_element( fe, &user_data );
      user_data_delete_function( user_data, user_state );
    }

    abstraction_aligned_free( fe );
  }

  abstraction_aligned_free( fs );

  return;
}
Ejemplo n.º 3
0
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_rapid_popping_and_pushing( void *freelist_state )
{
  struct freelist_state
    *fs;

  struct freelist_element
    *fe;

  time_t
    start_time;

  assert( freelist_state != NULL );

  fs = (struct freelist_state *) freelist_state;

  time( &start_time );

  while( time(NULL) < start_time + 10 )
  {
    freelist_pop( fs, &fe );
    freelist_push( fs, fe );
  }

  return( (thread_return_t) EXIT_SUCCESS );
}
Ejemplo n.º 4
0
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_popping_and_pushing_start_pushing( void *freelist_test_popping_and_pushing_state )
{
  struct freelist_test_popping_and_pushing_state
    *pps;

  struct freelist_element
    *fe;

  time_t
    start_time;

  unsigned int
    count;

  assert( freelist_test_popping_and_pushing_state != NULL );

  pps = (struct freelist_test_popping_and_pushing_state *) freelist_test_popping_and_pushing_state;

  time( &start_time );

  while( time(NULL) < start_time + 10 )
  {
    while( freelist_pop(pps->local_fs, &fe) )
      freelist_push( pps->fs, fe );

    count = 0;

    while( count < 1000 )
    {
      freelist_pop( pps->fs, &fe );

      if( fe != NULL )
      {
        freelist_push( pps->local_fs, fe );
        count++;
      }
    }
  }

  // TRD : now push whatever we have in our local freelist
  while( freelist_pop(pps->local_fs, &fe) )
    freelist_push( pps->fs, fe );

  return( (thread_return_t) EXIT_SUCCESS );
}
Ejemplo n.º 5
0
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_pushing( void *freelist_test_pushing_state )
{
  struct freelist_test_pushing_state
    *ftps;

  struct freelist_element
    *fe;

  assert( freelist_test_pushing_state != NULL );

  ftps = (struct freelist_test_pushing_state *) freelist_test_pushing_state;

  while( freelist_pop(ftps->source_fs, &fe) )
    freelist_push( ftps->fs, fe );

  return( (thread_return_t) EXIT_SUCCESS );
}
Ejemplo n.º 6
0
unsigned int genset_new (genset_ref x)
{
  register unsigned int i = freelist_pop(x->freelist, &x->sp, x->max) ;
  if (i == x->max) errno = ENOSPC ;
  return i ;
}
Ejemplo n.º 7
0
void freelist_test_internal_popping( void )
{
  unsigned int
    loop,
    cpu_count,
    count;

  thread_state_t
    *thread_handles;

  enum data_structure_validity
    dvs = VALIDITY_VALID;

  struct freelist_state
    *fs;

  struct freelist_element
    *fe;

  struct freelist_test_popping_state
    *ftps;

  unsigned int
    *found_count;

  /* TRD : we create a freelist with 1,000,000 elements

           the creation function runs in a single thread and creates
           and pushes those elements onto the freelist

           each element contains a void pointer which is its element number

           we then run one thread per CPU
           where each thread loops, popping as quickly as possible
           each popped element is pushed onto a thread-local freelist

           the threads run till the source freelist is empty

           we then check the thread-local freelists
           we should find we have every element

           then tidy up
  */

  internal_display_test_name( "Popping" );

  cpu_count = abstraction_cpu_count();

  freelist_new( &fs, 1000000, freelist_test_internal_popping_init, NULL );
  ftps = malloc( sizeof(struct freelist_test_popping_state) * cpu_count );
  for( loop = 0 ; loop < cpu_count ; loop++ )
  {
    (ftps+loop)->fs = fs;
    freelist_new( &(ftps+loop)->fs_thread_local, 0, NULL, NULL );
  }

  thread_handles = malloc( sizeof(thread_state_t) * cpu_count );

  for( loop = 0 ; loop < cpu_count ; loop++ )
    abstraction_thread_start( &thread_handles[loop], loop, freelist_test_internal_thread_popping, ftps+loop );

  for( loop = 0 ; loop < cpu_count ; loop++ )
    abstraction_thread_wait( thread_handles[loop] );

  free( thread_handles );

  // TRD : now we check the thread-local freelists
  found_count = malloc( sizeof(unsigned int) * 1000000 );
  for( loop = 0 ; loop < 1000000 ; loop++ )
    *(found_count+loop) = 0;

  for( loop = 0 ; loop < cpu_count ; loop++ )
  {
    while( freelist_pop((ftps+loop)->fs_thread_local, &fe) )
    {
      freelist_get_user_data_from_element( fe, (void **) &count );
      (*(found_count+count))++;
      freelist_push( fs, fe );
    }
  }

  for( loop = 0 ; loop < 1000000 and dvs == VALIDITY_VALID ; loop++ )
  {
    if( *(found_count+loop) == 0 )
      dvs = VALIDITY_INVALID_MISSING_ELEMENTS;

    if( *(found_count+loop) > 1 )
      dvs = VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
  }

  // TRD : cleanup
  free( found_count );
  for( loop = 0 ; loop < cpu_count ; loop++ )
    freelist_delete( (ftps+loop)->fs_thread_local, NULL, NULL );
  freelist_delete( fs, NULL, NULL );

  // TRD : print the test result
  internal_display_test_result( 1, "freelist", dvs );

  return;
}
Ejemplo n.º 8
0
void freelist_test_internal_pushing( void )
{
  unsigned int
    loop,
    cpu_count;

  thread_state_t
    *thread_handles;

  enum data_structure_validity
    dvs;

  struct freelist_test_pushing_state
    *ftps;

  struct freelist_element
    *fe;

  struct freelist_state
    *fs,
    *cleanup_fs;

  struct freelist_test_counter_and_thread_number
    *cnt,
    *counter_and_number_trackers;

  struct validation_info
    vi = { 1000000, 1000000 };

  /* TRD : we create an empty freelist, which we will push to

           we then create one freelist per CPU, where this freelist
           contains 1,000,000/cpu_count number of elements and
           each element is an incrementing counter and unique ID
           (from 0 to number of CPUs)

           we then start one thread per CPU, where each thread is
           given one of the populated freelists and pops from that
           to push to the empty freelist

           the reason for this is to achieve memory pre-allocation
           which allows the pushing threads to run at maximum speed

           the threads end when their freelists are empty

           we then fully pop the now populated main freelist (onto
           a second freelist, so we can cleanly free all memory),
           checking that the counts increment on a per unique ID basis
           and that the number of elements we pop equals 1,000,000
           (since each element has an incrementing counter which is
            unique on a per unique ID basis, we can know we didn't lose
            any elements)
  */

  internal_display_test_name( "Pushing" );

  cpu_count = abstraction_cpu_count();

  ftps = malloc( sizeof(struct freelist_test_pushing_state) * cpu_count );

  freelist_new( &fs, 0, NULL, NULL );

  for( loop = 0 ; loop < cpu_count ; loop++ )
  {
    (ftps+loop)->thread_number = (atom_t) loop;
    freelist_new( &(ftps+loop)->source_fs, 1000000 / cpu_count, freelist_test_internal_pushing_init, (void *) (atom_t) loop );
    (ftps+loop)->fs = fs;
  }

  thread_handles = malloc( sizeof(thread_state_t) * cpu_count );

  for( loop = 0 ; loop < cpu_count ; loop++ )
    abstraction_thread_start( &thread_handles[loop], loop, freelist_test_internal_thread_pushing, ftps+loop );

  for( loop = 0 ; loop < cpu_count ; loop++ )
    abstraction_thread_wait( thread_handles[loop] );

  free( thread_handles );

  // TRD : now fully pop and verify the main freelist
  freelist_new( &cleanup_fs, 0, NULL, NULL );

  counter_and_number_trackers = malloc( sizeof(struct freelist_test_counter_and_thread_number) * cpu_count );

  for( loop = 0 ; loop < cpu_count ; loop++ )
  {
    (counter_and_number_trackers+loop)->counter = (1000000 / cpu_count) * loop;
    (counter_and_number_trackers+loop)->thread_number = (atom_t) loop;
  }

  freelist_query( fs, FREELIST_QUERY_VALIDATE, &vi, (void *) &dvs );

  while( dvs == VALIDITY_VALID and freelist_pop(fs, &fe) )
  {
    static int count = 0;

    freelist_get_user_data_from_element( fe, (void **) &cnt );

    if( cnt->counter != (counter_and_number_trackers+cnt->thread_number)->counter++ )
      dvs = VALIDITY_INVALID_MISSING_ELEMENTS;

    freelist_push( cleanup_fs, fe );

    count++;
  }

  // TRD : clean up
  free( counter_and_number_trackers );

  for( loop = 0 ; loop < cpu_count ; loop++ )
    freelist_delete( (ftps+loop)->source_fs, NULL, NULL );

  free( ftps );

  freelist_delete( cleanup_fs, freelist_test_internal_pushing_delete, NULL );
  freelist_delete( fs, NULL, NULL );

  // TRD : print the test result
  internal_display_test_result( 1, "freelist", dvs );

  return;
}