thread_return_t CALLING_CONVENTION benchmark_lfds611_freelist_thread_pop_and_push( void *freelist_benchmark ) { struct lfds611_freelist_benchmark *fb; struct lfds611_freelist_element *fe; time_t start_time; assert( freelist_benchmark != NULL ); fb = (struct lfds611_freelist_benchmark *) freelist_benchmark; time( &start_time ); while( time(NULL) < start_time + 10 ) { lfds611_freelist_pop( fb->fs, &fe ); lfds611_freelist_push( fb->fs, fe ); fb->operation_count += 2; } return( (thread_return_t) EXIT_SUCCESS ); }
struct lfds611_freelist_element *lfds611_ringbuffer_get_write_element( struct lfds611_ringbuffer_state *rs, struct lfds611_freelist_element **fe, int *overwrite_flag ) { assert( rs != NULL ); assert( fe != NULL ); // TRD : overwrite_flag can be NULL /* TRD : we try to obtain an element from the lfds611_freelist if we can, we populate it and add it to the lfds611_queue if we cannot, then the lfds611_ringbuffer is full so instead we grab the current read element and use that instead dequeue may fail since the lfds611_queue may be emptied during our dequeue attempt so what we actually do here is a loop, attempting the lfds611_freelist and if it fails then a dequeue, until we obtain an element once we have an element, we lfds611_queue it you may be wondering why this operation is in a loop remember - these operations are lock-free; anything can happen in between so for example the pop could fail because the lfds611_freelist is empty; but by the time we go to get an element from the lfds611_queue, the whole lfds611_queue has been emptied back into the lfds611_freelist! if overwrite_flag is provided, we set it to 0 if we obtained a new element from the lfds611_freelist, 1 if we stole an element from the lfds611_queue */ do { if( overwrite_flag != NULL ) *overwrite_flag = 0; lfds611_freelist_pop( rs->fs, fe ); if( *fe == NULL ) { lfds611_ringbuffer_get_read_element( rs, fe ); if( overwrite_flag != NULL and *fe != NULL ) *overwrite_flag = 1; } } while( *fe == NULL ); return( *fe ); }
void lfds611_stack_internal_new_element_from_freelist( struct lfds611_stack_state *ss, struct lfds611_stack_element *se[LFDS611_STACK_PAC_SIZE], void *user_data ) { struct lfds611_freelist_element *fe; assert( ss != NULL ); assert( se != NULL ); // TRD : user_data can be any value in its range lfds611_freelist_pop( ss->fs, &fe ); if( fe == NULL ) se[LFDS611_STACK_POINTER] = NULL; if( fe != NULL ) lfds611_stack_internal_init_element( ss, se, fe, user_data ); return; }