Helixis 1.0
Task Programming API
Data Structures | Defines | Enumerations | Functions
sources/liblfds/liblfds.h File Reference
#include "hlx/core.h"
#include "helixis_internal.h"

Go to the source code of this file.

Data Structures

struct  validation_info

Defines

#define __LIBLFDS_H
#define LIBLFDS_RELEASE_NUMBER   6
#define __LIBLFDS_H

Enumerations

enum  data_structure_validity {
  VALIDITY_VALID, VALIDITY_INVALID_LOOP, VALIDITY_INVALID_MISSING_ELEMENTS, VALIDITY_INVALID_ADDITIONAL_ELEMENTS,
  VALIDITY_INVALID_TEST_DATA
}
enum  freelist_query_type { FREELIST_QUERY_ELEMENT_COUNT, FREELIST_QUERY_VALIDATE }
enum  queue_query_type { QUEUE_QUERY_ELEMENT_COUNT, QUEUE_QUERY_VALIDATE }

Functions

int freelist_new (struct freelist_state **fs, atom_t number_elements, int(*user_data_init_function)(void **user_data, void *user_state), void *user_state)
void freelist_delete (struct freelist_state *fs, void(*user_data_delete_function)(void *user_data, void *user_state), void *user_state)
atom_t freelist_new_elements (struct freelist_state *fs, atom_t number_elements)
struct freelist_element * freelist_pop (struct freelist_state *fs, struct freelist_element **fe)
struct freelist_element * freelist_guaranteed_pop (struct freelist_state *fs, struct freelist_element **fe)
void freelist_push (struct freelist_state *fs, struct freelist_element *fe)
void * freelist_get_user_data_from_element (struct freelist_element *fe, void **user_data)
void freelist_set_user_data_in_element (struct freelist_element *fe, void *user_data)
void freelist_query (struct freelist_state *fs, enum freelist_query_type query_type, void *query_input, void *query_output)
int queue_new (struct queue_state **sq, atom_t number_elements)
void queue_delete (struct queue_state *qs, void(*user_data_delete_function)(void *user_data, void *user_state), void *user_state)
int queue_enqueue (struct queue_state *qs, void *user_data)
int queue_guaranteed_enqueue (struct queue_state *qs, void *user_data)
int queue_dequeue (struct queue_state *qs, void **user_data)
void queue_query (struct queue_state *qs, enum queue_query_type query_type, void *query_input, void *query_output)
int slist_new (struct slist_state **ss, void(*user_data_delete_function)(void *user_data, void *user_state), void *user_state)
void slist_delete (struct slist_state *ss)
struct slist_elementslist_new_head (struct slist_state *ss, void *user_data)
struct slist_elementslist_new_next (struct slist_element *se, void *user_data)
void slist_delete_element (struct slist_state *ss, struct slist_element *se)
void slist_delete_all_elements (struct slist_state *ss)
int slist_get_user_data_from_element (struct slist_element *se, void **user_data)
int slist_set_user_data_in_element (struct slist_element *se, void *user_data)
struct slist_elementslist_get_head (struct slist_state *ss, struct slist_element **se)
struct slist_elementslist_get_next (struct slist_element *se, struct slist_element **next_se)
struct slist_elementslist_get_head_and_then_next (struct slist_state *ss, struct slist_element **se)

Define Documentation

#define __LIBLFDS_H

Definition at line 111 of file liblfds.h.

#define __LIBLFDS_H

Definition at line 111 of file liblfds.h.

#define LIBLFDS_RELEASE_NUMBER   6

Definition at line 10 of file liblfds.h.


Enumeration Type Documentation

Enumerator:
VALIDITY_VALID 
VALIDITY_INVALID_LOOP 
VALIDITY_INVALID_MISSING_ELEMENTS 
VALIDITY_INVALID_ADDITIONAL_ELEMENTS 
VALIDITY_INVALID_TEST_DATA 

Definition at line 13 of file liblfds.h.

Enumerator:
FREELIST_QUERY_ELEMENT_COUNT 
FREELIST_QUERY_VALIDATE 

Definition at line 33 of file liblfds.h.

Enumerator:
QUEUE_QUERY_ELEMENT_COUNT 
QUEUE_QUERY_VALIDATE 

Definition at line 64 of file liblfds.h.


Function Documentation

void freelist_delete ( struct freelist_state *  fs,
void(*)(void *user_data, void *user_state)  user_data_delete_function,
void *  user_state 
)

Referenced by queue_delete().

void* freelist_get_user_data_from_element ( struct freelist_element *  fe,
void **  user_data 
)
struct freelist_element* freelist_guaranteed_pop ( struct freelist_state *  fs,
struct freelist_element **  fe 
) [read]
int freelist_new ( struct freelist_state **  fs,
atom_t  number_elements,
int(*)(void **user_data, void *user_state)  user_data_init_function,
void *  user_state 
)

Referenced by queue_new().

atom_t freelist_new_elements ( struct freelist_state *  fs,
atom_t  number_elements 
)
struct freelist_element* freelist_pop ( struct freelist_state *  fs,
struct freelist_element **  fe 
) [read]
void freelist_push ( struct freelist_state *  fs,
struct freelist_element *  fe 
)

Referenced by queue_delete(), and queue_dequeue().

void freelist_query ( struct freelist_state *  fs,
enum freelist_query_type  query_type,
void *  query_input,
void *  query_output 
)
void freelist_set_user_data_in_element ( struct freelist_element *  fe,
void *  user_data 
)
void queue_delete ( struct queue_state qs,
void(*)(void *user_data, void *user_state)  user_data_delete_function,
void *  user_state 
)

Definition at line 8 of file queue_delete.c.

References hlx_api::aligned_free_entry, queue_state::enqueue, queue_element::fe, freelist_delete(), freelist_push(), queue_state::fs, queue_dequeue(), queue_internal_freelist_delete_function(), and QUEUE_POINTER.

Referenced by hlx_group_destruct().

{
  void
    *user_data;

  /* TRD : user_data_delete_function can be 0 */
  /* TRD : user_state can be 0 */

  while( queue_dequeue(qs, &user_data) )
    if( user_data_delete_function != 0 )
      user_data_delete_function( user_data, user_state );

  /* TRD : fully dequeuing will leave us
           with a single dummy element
           which both qs->enqueue and qs->dequeue point at
           we push this back onto the freelist
           before we delete the freelist
  */

  freelist_push( qs->fs, qs->enqueue[QUEUE_POINTER]->fe );

  freelist_delete( qs->fs, queue_internal_freelist_delete_function, 0 );

  gl_api.aligned_free_entry( qs );

  return;
}
int queue_dequeue ( struct queue_state qs,
void **  user_data 
)

Definition at line 101 of file queue_queue.c.

References ALIGN, ALIGN_DOUBLE_POINTER, and, hlx_api::atomic_dcas_entry, queue_state::dequeue, queue_state::enqueue, queue_element::fe, freelist_push(), queue_state::fs, LOWERED, queue_element::next, QUEUE_COUNTER, QUEUE_PAC_SIZE, QUEUE_POINTER, QUEUE_STATE_ATTEMPT_DEQUEUE, QUEUE_STATE_EMPTY, QUEUE_STATE_ENQUEUE_OUT_OF_PLACE, QUEUE_STATE_UNKNOWN, and RAISED.

Referenced by hlx_group_destruct(), hlx_group_flush_task_buffer(), and queue_delete().

{
  ALIGN(ALIGN_DOUBLE_POINTER) struct queue_element
    *enqueue[QUEUE_PAC_SIZE],
    *dequeue[QUEUE_PAC_SIZE],
    *next[QUEUE_PAC_SIZE];

  unsigned char
    cas_result = 0;

  int
    rv = 1,
    state = QUEUE_STATE_UNKNOWN,
    finished_flag = LOWERED;


  do
  {
    dequeue[QUEUE_POINTER] = qs->dequeue[QUEUE_POINTER];
    dequeue[QUEUE_COUNTER] = qs->dequeue[QUEUE_COUNTER];

    enqueue[QUEUE_POINTER] = qs->enqueue[QUEUE_POINTER];
    enqueue[QUEUE_COUNTER] = qs->enqueue[QUEUE_COUNTER];

    next[QUEUE_POINTER] = dequeue[QUEUE_POINTER]->next[QUEUE_POINTER];
    next[QUEUE_COUNTER] = dequeue[QUEUE_POINTER]->next[QUEUE_COUNTER];

    /* TRD : confirm that dequeue didn't move between reading it
             and reading its next pointer
    */

    if( dequeue[QUEUE_POINTER] == qs->dequeue[QUEUE_POINTER] and dequeue[QUEUE_COUNTER] == qs->dequeue[QUEUE_COUNTER] )
    {
      if( enqueue[QUEUE_POINTER] == dequeue[QUEUE_POINTER] and next[QUEUE_POINTER] == 0 )
        state = QUEUE_STATE_EMPTY;

      if( enqueue[QUEUE_POINTER] == dequeue[QUEUE_POINTER] and next[QUEUE_POINTER] != 0 )
        state = QUEUE_STATE_ENQUEUE_OUT_OF_PLACE;

      if( enqueue[QUEUE_POINTER] != dequeue[QUEUE_POINTER] )
        state = QUEUE_STATE_ATTEMPT_DEQUEUE;

      switch( state )
      {
        case QUEUE_STATE_EMPTY:
          *user_data = 0;
          rv = 0;
          finished_flag = RAISED;
        break;

        case QUEUE_STATE_ENQUEUE_OUT_OF_PLACE:
          next[QUEUE_COUNTER] = enqueue[QUEUE_COUNTER] + 1;
          gl_api.atomic_dcas_entry( (volatile atom_t *) qs->enqueue, (atom_t *) next, (atom_t *) enqueue );
        break;

        case QUEUE_STATE_ATTEMPT_DEQUEUE:
          *user_data = next[QUEUE_POINTER]->user_data;

          next[QUEUE_COUNTER] = dequeue[QUEUE_COUNTER] + 1;
          cas_result = gl_api.atomic_dcas_entry( (volatile atom_t *) qs->dequeue, (atom_t *) next, (atom_t *) dequeue );

          if( cas_result == 1 )
            finished_flag = RAISED;
        break;
      }
    }
  }
  while( finished_flag == LOWERED );

  if( cas_result == 1 )
    freelist_push( qs->fs, dequeue[QUEUE_POINTER]->fe );

  return( rv );
}
int queue_enqueue ( struct queue_state qs,
void *  user_data 
)

Definition at line 8 of file queue_queue.c.

References ALIGN, ALIGN_DOUBLE_POINTER, queue_internal_new_element_from_freelist(), queue_internal_queue(), QUEUE_PAC_SIZE, and QUEUE_POINTER.

Referenced by hlx_group_bufferize_task().

{
  ALIGN(ALIGN_DOUBLE_POINTER) struct queue_element
    *qe[QUEUE_PAC_SIZE];

  /* TRD : user_data can be 0 */

  queue_internal_new_element_from_freelist( qs, qe, user_data );

  if( qe[QUEUE_POINTER] == 0 )
    return( 0 );

  queue_internal_queue( qs, qe );

  return( 1 );
}
int queue_guaranteed_enqueue ( struct queue_state qs,
void *  user_data 
)

Definition at line 30 of file queue_queue.c.

References ALIGN, ALIGN_DOUBLE_POINTER, queue_internal_guaranteed_new_element_from_freelist(), queue_internal_queue(), QUEUE_PAC_SIZE, and QUEUE_POINTER.

Referenced by hlx_group_bufferize_task().

{
  ALIGN(ALIGN_DOUBLE_POINTER) struct queue_element
    *qe[QUEUE_PAC_SIZE];

  /* TRD : user_data can be 0 */

  queue_internal_guaranteed_new_element_from_freelist( qs, qe, user_data );

  if( qe[QUEUE_POINTER] == 0 )
    return( 0 );

  queue_internal_queue( qs, qe );

  return( 1 );
}
int queue_new ( struct queue_state **  sq,
atom_t  number_elements 
)

Definition at line 9 of file queue_new.c.

References ALIGN_DOUBLE_POINTER, hlx_api::aligned_free_entry, hlx_api::aligned_malloc_entry, freelist_new(), queue_internal_freelist_init_function(), queue_internal_new_element_from_freelist(), QUEUE_PAC_SIZE, and QUEUE_POINTER.

Referenced by hlx_group_construct().

{
  int
    rv = 0;

  struct queue_element
    *qe[QUEUE_PAC_SIZE];

  /* TRD : number_elements can be any value in its range */

  *qs = (struct queue_state *) gl_api.aligned_malloc_entry( sizeof(struct queue_state), ALIGN_DOUBLE_POINTER );

  if( *qs != 0 )
  {
    /* TRD : the size of the freelist is the size of the queue (+1 for the leading dummy element, which is hidden from the caller) */
    freelist_new( &(*qs)->fs, number_elements+1, queue_internal_freelist_init_function, 0 );

    if( (*qs)->fs != 0 )
    {
      queue_internal_new_element_from_freelist( *qs, qe, 0 );
      (*qs)->enqueue[QUEUE_POINTER] = (*qs)->dequeue[QUEUE_POINTER] = qe[QUEUE_POINTER];
      (*qs)->aba_counter = 0;
      rv = 1;
    }

    if( (*qs)->fs == 0 )
    {
      gl_api.aligned_free_entry( *qs );
      *qs = 0;
    }
  }

  return( rv );
}
void queue_query ( struct queue_state qs,
enum queue_query_type  query_type,
void *  query_input,
void *  query_output 
)

Definition at line 10 of file queue_query.c.

References freelist_query(), FREELIST_QUERY_ELEMENT_COUNT, queue_state::fs, queue_internal_validate(), QUEUE_QUERY_ELEMENT_COUNT, and QUEUE_QUERY_VALIDATE.

Referenced by hlx_group_get_size().

{
  /* TRD : query_type can be any value in its range */
  /* TRD : query_input can be 0 */

  switch( query_type )
  {
    case QUEUE_QUERY_ELEMENT_COUNT:
      freelist_query( qs->fs, FREELIST_QUERY_ELEMENT_COUNT, 0, query_output );
    break;

    case QUEUE_QUERY_VALIDATE:
      /* TRD : query_input can be 0 */

      queue_internal_validate( qs, (struct validation_info *) query_input, (enum data_structure_validity *) query_output, ((enum data_structure_validity *) query_output)+1 );
    break;
  }

  return;
}
void slist_delete ( struct slist_state ss)
void slist_delete_all_elements ( struct slist_state ss)

Definition at line 15 of file slist_delete.c.

References hlx_api::aligned_free_entry, slist_state::head, slist_element::next, slist_internal_init_slist(), SLIST_USER_DATA, slist_element::user_data_and_flags, slist_state::user_data_delete_function, and slist_state::user_state.

Referenced by _hlx_event_handler_destroy(), and slist_delete().

{
  struct slist_element *volatile se, *volatile se_temp;

  se = ss->head;

  while( se != 0 )
  {
    /* TRD : if a non-deleted element and there is a delete function, call the delete function */
    if( ss->user_data_delete_function != 0 )
      ss->user_data_delete_function( (void *) se->user_data_and_flags[SLIST_USER_DATA], ss->user_state );

    se_temp = se;
    se = se->next;
    gl_api.aligned_free_entry( (void *) se_temp );
  }

  slist_internal_init_slist( ss, ss->user_data_delete_function, ss->user_state );

  return;
}
void slist_delete_element ( struct slist_state ss,
struct slist_element se 
)
struct slist_element* slist_get_head ( struct slist_state ss,
struct slist_element **  se 
) [read]
struct slist_element* slist_get_head_and_then_next ( struct slist_state ss,
struct slist_element **  se 
) [read]

Definition at line 35 of file slist_get_and_set.c.

References slist_get_head(), and slist_get_next().

Referenced by _destroy_channel_manager(), _hlx_event_return_handler_by_hash(), _hlx_get_channel_by_hash(), hlx_event_manager_destroy(), and hlx_event_notify().

{
  if( *se == 0 )
    slist_get_head( ss, se );
  else
    slist_get_next( *se, se );

  return( *se );
}
struct slist_element* slist_get_next ( struct slist_element se,
struct slist_element **  next_se 
) [read]

Definition at line 26 of file slist_get_and_set.c.

References slist_element::next, and slist_internal_move_to_first_undeleted_element().

Referenced by slist_get_head_and_then_next().

{
  *next_se = (struct slist_element *) se->next;

  slist_internal_move_to_first_undeleted_element( next_se );

  return( *next_se );
}
int slist_get_user_data_from_element ( struct slist_element se,
void **  user_data 
)
int slist_new ( struct slist_state **  ss,
void(*)(void *user_data, void *user_state)  user_data_delete_function,
void *  user_state 
)

Definition at line 6 of file slist_new.c.

References ALIGN_SINGLE_POINTER, hlx_api::aligned_malloc_entry, slist_internal_init_slist(), and slist_state::user_data_delete_function.

Referenced by _hlx_event_handler_create_by_hash(), _init_channel_manager(), hlx_chan_create(), and hlx_event_manager_create().

{
  int
    rv = 0;

  /* TRD : user_data_delete_function can be 0 */
  /* TRD : user_state can be 0 */

  *ss = (struct slist_state *) gl_api.aligned_malloc_entry( sizeof(struct slist_state), ALIGN_SINGLE_POINTER );

  if( *ss != 0 )
  {
    slist_internal_init_slist( *ss, user_data_delete_function, user_state );
    rv = 1;
  }

  return( rv );
}
struct slist_element* slist_new_head ( struct slist_state ss,
void *  user_data 
) [read]

Definition at line 37 of file slist_new.c.

References ALIGN, ALIGN_DOUBLE_POINTER, ALIGN_SINGLE_POINTER, hlx_api::aligned_malloc_entry, SLIST_FLAGS, slist_internal_link_element_to_head(), SLIST_NO_FLAGS, SLIST_USER_DATA, and slist_element::user_data_and_flags.

Referenced by _hlx_event_handler_create_by_hash(), _hlx_event_register_callback_with_group(), and hlx_chan_create().

{
  ALIGN(ALIGN_SINGLE_POINTER) struct slist_element
    *volatile se;

  /* TRD : user_data can be 0 */

  se = (struct slist_element *) gl_api.aligned_malloc_entry( sizeof(struct slist_element), ALIGN_DOUBLE_POINTER );

  if( se != 0 )
  {
    se->user_data_and_flags[SLIST_USER_DATA] = user_data;
    se->user_data_and_flags[SLIST_FLAGS] = SLIST_NO_FLAGS;

    slist_internal_link_element_to_head( ss, se );
  }

  return( (struct slist_element *) se );
}
struct slist_element* slist_new_next ( struct slist_element se,
void *  user_data 
) [read]
int slist_set_user_data_in_element ( struct slist_element se,
void *  user_data 
)
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines