1 #include "lfds611_queue_internal.h"
\r
7 /****************************************************************************/
\r
8 int lfds611_queue_new( struct lfds611_queue_state **qs, lfds611_atom_t number_elements )
\r
13 struct lfds611_queue_element
\r
14 *qe[LFDS611_QUEUE_PAC_SIZE];
\r
16 assert( qs != NULL );
\r
17 // TRD : number_elements can be any value in its range
\r
19 *qs = (struct lfds611_queue_state *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_queue_state), LFDS611_ALIGN_DOUBLE_POINTER );
\r
23 // TRD : the size of the lfds611_freelist is the size of the lfds611_queue (+1 for the leading dummy element, which is hidden from the caller)
\r
24 lfds611_freelist_new( &(*qs)->fs, number_elements+1, lfds611_queue_internal_freelist_init_function, NULL );
\r
26 if( (*qs)->fs != NULL )
\r
28 lfds611_queue_internal_new_element_from_freelist( *qs, qe, NULL );
\r
29 (*qs)->enqueue[LFDS611_QUEUE_POINTER] = (*qs)->dequeue[LFDS611_QUEUE_POINTER] = qe[LFDS611_QUEUE_POINTER];
\r
30 (*qs)->enqueue[LFDS611_QUEUE_COUNTER] = (*qs)->dequeue[LFDS611_QUEUE_COUNTER] = 0;
\r
31 (*qs)->aba_counter = 0;
\r
35 if( (*qs)->fs == NULL )
\r
37 lfds611_liblfds_aligned_free( *qs );
\r
42 LFDS611_BARRIER_STORE;
\r
51 /****************************************************************************/
\r
52 #pragma warning( disable : 4100 )
\r
54 void lfds611_queue_use( struct lfds611_queue_state *qs )
\r
56 assert( qs != NULL );
\r
58 LFDS611_BARRIER_LOAD;
\r
63 #pragma warning( default : 4100 )
\r
69 /****************************************************************************/
\r
70 #pragma warning( disable : 4100 )
\r
72 int lfds611_queue_internal_freelist_init_function( void **user_data, void *user_state )
\r
77 assert( user_data != NULL );
\r
78 assert( user_state == NULL );
\r
80 *user_data = lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_queue_element), LFDS611_ALIGN_DOUBLE_POINTER );
\r
82 if( *user_data != NULL )
\r
88 #pragma warning( default : 4100 )
\r
94 /****************************************************************************/
\r
95 void lfds611_queue_internal_new_element_from_freelist( struct lfds611_queue_state *qs, struct lfds611_queue_element *qe[LFDS611_QUEUE_PAC_SIZE], void *user_data )
\r
97 struct lfds611_freelist_element
\r
100 assert( qs != NULL );
\r
101 assert( qe != NULL );
\r
102 // TRD : user_data can be any value in its range
\r
104 qe[LFDS611_QUEUE_POINTER] = NULL;
\r
106 lfds611_freelist_pop( qs->fs, &fe );
\r
109 lfds611_queue_internal_init_element( qs, qe, fe, user_data );
\r
118 /****************************************************************************/
\r
119 void lfds611_queue_internal_guaranteed_new_element_from_freelist( struct lfds611_queue_state *qs, struct lfds611_queue_element *qe[LFDS611_QUEUE_PAC_SIZE], void *user_data )
\r
121 struct lfds611_freelist_element
\r
124 assert( qs != NULL );
\r
125 assert( qe != NULL );
\r
126 // TRD : user_data can be any value in its range
\r
128 qe[LFDS611_QUEUE_POINTER] = NULL;
\r
130 lfds611_freelist_guaranteed_pop( qs->fs, &fe );
\r
133 lfds611_queue_internal_init_element( qs, qe, fe, user_data );
\r
142 /****************************************************************************/
\r
143 void lfds611_queue_internal_init_element( struct lfds611_queue_state *qs, struct lfds611_queue_element *qe[LFDS611_QUEUE_PAC_SIZE], struct lfds611_freelist_element *fe, void *user_data )
\r
145 assert( qs != NULL );
\r
146 assert( qe != NULL );
\r
147 assert( fe != NULL );
\r
148 // TRD : user_data can be any value in its range
\r
150 lfds611_freelist_get_user_data_from_element( fe, (void **) &qe[LFDS611_QUEUE_POINTER] );
\r
151 qe[LFDS611_QUEUE_COUNTER] = (struct lfds611_queue_element *) lfds611_abstraction_increment( (lfds611_atom_t *) &qs->aba_counter );
\r
153 qe[LFDS611_QUEUE_POINTER]->next[LFDS611_QUEUE_POINTER] = NULL;
\r
154 qe[LFDS611_QUEUE_POINTER]->next[LFDS611_QUEUE_COUNTER] = (struct lfds611_queue_element *) lfds611_abstraction_increment( (lfds611_atom_t *) &qs->aba_counter );
\r
156 qe[LFDS611_QUEUE_POINTER]->fe = fe;
\r
157 qe[LFDS611_QUEUE_POINTER]->user_data = user_data;
\r