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_stack_internal_freelist_init_function( void **user_data, void *user_state )
{
  int
  rv = 0;

  assert( user_data != NULL );
  assert( user_state == NULL );

  *user_data = lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_stack_element), LFDS611_ALIGN_DOUBLE_POINTER );

  if( *user_data != NULL )
    rv = 1;

  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 );
}
lfds611_atom_t lfds611_freelist_internal_new_element( struct lfds611_freelist_state *fs, struct lfds611_freelist_element **fe )
{
  lfds611_atom_t
  rv = 0;

  assert( fs != NULL );
  assert( fe != NULL );

  /* TRD : basically, does what you'd expect;

           allocates an element
           calls the user init function
           if anything fails, cleans up,
           sets *fe to NULL
           and returns 0
  */

  *fe = (struct lfds611_freelist_element *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_freelist_element), LFDS611_ALIGN_DOUBLE_POINTER );

  if( *fe != NULL ) {
    if( fs->user_data_init_function == NULL ) {
      (*fe)->user_data = NULL;
      rv = 1;
    }

    if( fs->user_data_init_function != NULL ) {
      rv = fs->user_data_init_function( &(*fe)->user_data, fs->user_state );

      if( rv == 0 ) {
        lfds611_liblfds_aligned_free( *fe );
        *fe = NULL;
      }
    }
  }

  if( rv == 1 )
    lfds611_abstraction_increment( (lfds611_atom_t *) &fs->element_count );

  return( rv );
}
int lfds611_freelist_new( struct lfds611_freelist_state **fs, lfds611_atom_t number_elements, int (*user_data_init_function)(void **user_data, void *user_state), void *user_state )
{
  int
  rv = 0;

  lfds611_atom_t
  element_count;

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

  *fs = (struct lfds611_freelist_state *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_freelist_state), LFDS611_ALIGN_DOUBLE_POINTER );

  if( (*fs) != NULL ) {
    (*fs)->top[LFDS611_FREELIST_POINTER] = NULL;
    (*fs)->top[LFDS611_FREELIST_COUNTER] = 0;
    (*fs)->user_data_init_function = user_data_init_function;
    (*fs)->user_state = user_state;
    (*fs)->aba_counter = 0;
    (*fs)->element_count = 0;

    element_count = lfds611_freelist_new_elements( *fs, number_elements );

    if( element_count == number_elements )
      rv = 1;

    if( element_count != number_elements ) {
      lfds611_liblfds_aligned_free( (*fs) );
      *fs = NULL;
    }
  }

  LFDS611_BARRIER_STORE;

  return( rv );
}