예제 #1
0
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;
}