int lfds611_stack_new( struct lfds611_stack_state **ss, lfds611_atom_t number_elements )
{
  int
  rv = 0;

  assert( ss != NULL );
  // TRD : number_elements can be any value in its range

  *ss = (struct lfds611_stack_state *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_stack_state), LFDS611_ALIGN_DOUBLE_POINTER );

  if( *ss != NULL ) {
    // TRD : the size of the lfds611_freelist is the size of the lfds611_stack
    lfds611_freelist_new( &(*ss)->fs, number_elements, lfds611_stack_internal_freelist_init_function, NULL );

    if( (*ss)->fs == NULL ) {
      lfds611_liblfds_aligned_free( *ss );
      *ss = NULL;
    }

    if( (*ss)->fs != NULL ) {
      (*ss)->top[LFDS611_STACK_POINTER] = NULL;
      (*ss)->top[LFDS611_STACK_COUNTER] = 0;
      (*ss)->aba_counter = 0;
      rv = 1;
    }
  }

  LFDS611_BARRIER_STORE;

  return( rv );
}
Ejemplo n.º 2
0
int lfds611_ringbuffer_new( struct lfds611_ringbuffer_state **rs, lfds611_atom_t number_elements, int (*user_data_init_function)(void **user_data, void *user_state), void *user_state )
{
  int
    rv = 0;

  assert( rs != NULL );
  // TRD : number_elements can be any value in its range
  // TRD : user_data_init_function can be NULL
  // TRD : user_state can be NULL

  *rs = (struct lfds611_ringbuffer_state *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_ringbuffer_state), LFDS611_ALIGN_DOUBLE_POINTER );

  if( *rs != NULL )
  {
    lfds611_freelist_new( &(*rs)->fs, number_elements, user_data_init_function, user_state );

    if( (*rs)->fs != NULL )
    {
      lfds611_queue_new( &(*rs)->qs, number_elements );

      if( (*rs)->qs != NULL )
        rv = 1;

      if( (*rs)->qs == NULL )
      {
        lfds611_liblfds_aligned_free( *rs );
        *rs = NULL;
      }
    }

    if( (*rs)->fs == NULL )
    {
      lfds611_liblfds_aligned_free( *rs );
      *rs = NULL;
    }
  }

  LFDS611_BARRIER_STORE;

  return( rv );
}
Ejemplo n.º 3
0
void benchmark_lfds611_freelist( void )
{
  unsigned int
  loop,
  thread_count,
  cpu_count;

  struct lfds611_freelist_state
      *fs;

  struct lfds611_freelist_benchmark
      *fb;

  thread_state_t
  *thread_handles;

  lfds611_atom_t
  total_operations_for_full_test_for_all_cpus,
  total_operations_for_full_test_for_all_cpus_for_one_cpu = 0;

  double
  mean_operations_per_second_per_cpu,
  difference_per_second_per_cpu,
  total_difference_per_second_per_cpu,
  std_dev_per_second_per_cpu,
  scalability;

  /* TRD : here we benchmark the freelist

           the benchmark is to have a single freelist
           where a worker thread busy-works popping and then pushing
  */

  cpu_count = abstraction_cpu_count();

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

  fb = (struct lfds611_freelist_benchmark *) malloc( sizeof(struct lfds611_freelist_benchmark) * cpu_count );

  // TRD : print the benchmark ID and CSV header
  printf( "\n"
          "Release %s Freelist Benchmark #1\n"
          "CPUs,total ops,mean ops/sec per CPU,standard deviation,scalability\n", LFDS611_RELEASE_NUMBER_STRING );

  // TRD : we run CPU count times for scalability
  for( thread_count = 1 ; thread_count <= cpu_count ; thread_count++ ) {
    // TRD : initialisation
    lfds611_freelist_new( &fs, 1000, NULL, NULL );

    for( loop = 0 ; loop < cpu_count ; loop++ ) {
      (fb+loop)->fs = fs;
      (fb+loop)->operation_count = 0;
    }

    // TRD : main test
    for( loop = 0 ; loop < thread_count ; loop++ )
      abstraction_thread_start( &thread_handles[loop], loop, benchmark_lfds611_freelist_thread_pop_and_push, fb+loop );

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

    // TRD : post test math
    total_operations_for_full_test_for_all_cpus = 0;
    total_difference_per_second_per_cpu = 0;

    for( loop = 0 ; loop < thread_count ; loop++ )
      total_operations_for_full_test_for_all_cpus += (fb+loop)->operation_count;

    mean_operations_per_second_per_cpu = ((double) total_operations_for_full_test_for_all_cpus / (double) thread_count) / (double) 10;

    if( thread_count == 1 )
      total_operations_for_full_test_for_all_cpus_for_one_cpu = total_operations_for_full_test_for_all_cpus;

    for( loop = 0 ; loop < thread_count ; loop++ ) {
      difference_per_second_per_cpu = ((double) (fb+loop)->operation_count / (double) 10) - mean_operations_per_second_per_cpu;
      total_difference_per_second_per_cpu += difference_per_second_per_cpu * difference_per_second_per_cpu;
    }

    std_dev_per_second_per_cpu = sqrt( (double) total_difference_per_second_per_cpu );

    scalability = (double) total_operations_for_full_test_for_all_cpus / (double) (total_operations_for_full_test_for_all_cpus_for_one_cpu * thread_count);

    printf( "%u,%u,%.0f,%.0f,%0.2f\n", thread_count, (unsigned int) total_operations_for_full_test_for_all_cpus, mean_operations_per_second_per_cpu, std_dev_per_second_per_cpu, scalability );

    // TRD : cleanup
    lfds611_freelist_delete( fs, NULL, NULL );
  }

  free( fb );

  free( thread_handles );

  return;
}