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 ); }
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 ); }
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; }