]> pd.if.org Git - liblfds/blob - liblfds/liblfds6.1.0/liblfds610/src/lfds610_queue/lfds610_queue_new.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds6.1.0 / liblfds610 / src / lfds610_queue / lfds610_queue_new.c
1 #include "lfds610_queue_internal.h"
2
3
4
5
6
7 /****************************************************************************/
8 int lfds610_queue_new( struct lfds610_queue_state **qs, lfds610_atom_t number_elements )
9 {
10   int
11     rv = 0;
12
13   struct lfds610_queue_element
14     *qe[LFDS610_QUEUE_PAC_SIZE];
15
16   assert( qs != NULL );
17   // TRD : number_elements can be any value in its range
18
19   *qs = (struct lfds610_queue_state *) lfds610_liblfds_aligned_malloc( sizeof(struct lfds610_queue_state), LFDS610_ALIGN_DOUBLE_POINTER );
20
21   if( *qs != NULL )
22   {
23     // TRD : the size of the lfds610_freelist is the size of the lfds610_queue (+1 for the leading dummy element, which is hidden from the caller)
24     lfds610_freelist_new( &(*qs)->fs, number_elements+1, lfds610_queue_internal_freelist_init_function, NULL );
25
26     if( (*qs)->fs != NULL )
27     {
28       lfds610_queue_internal_new_element_from_freelist( *qs, qe, NULL );
29       (*qs)->enqueue[LFDS610_QUEUE_POINTER] = (*qs)->dequeue[LFDS610_QUEUE_POINTER] = qe[LFDS610_QUEUE_POINTER];
30       (*qs)->enqueue[LFDS610_QUEUE_COUNTER] = (*qs)->dequeue[LFDS610_QUEUE_COUNTER] = 0;
31       (*qs)->aba_counter = 0;
32       rv = 1;
33     }
34
35     if( (*qs)->fs == NULL )
36     {
37       lfds610_liblfds_aligned_free( *qs );
38       *qs = NULL;
39     }
40   }
41
42   LFDS610_BARRIER_STORE;
43
44   return( rv );
45 }
46
47
48
49
50
51 /****************************************************************************/
52 #pragma warning( disable : 4100 )
53
54 void lfds610_queue_use( struct lfds610_queue_state *qs )
55 {
56   assert( qs != NULL );
57
58   LFDS610_BARRIER_LOAD;
59
60   return;
61 }
62
63 #pragma warning( default : 4100 )
64
65
66
67
68
69 /****************************************************************************/
70 #pragma warning( disable : 4100 )
71
72 int lfds610_queue_internal_freelist_init_function( void **user_data, void *user_state )
73 {
74   int
75     rv = 0;
76
77   assert( user_data != NULL );
78   assert( user_state == NULL );
79
80   *user_data = lfds610_liblfds_aligned_malloc( sizeof(struct lfds610_queue_element), LFDS610_ALIGN_DOUBLE_POINTER );
81
82   if( *user_data != NULL )
83     rv = 1;
84
85   return( rv );
86 }
87
88 #pragma warning( default : 4100 )
89
90
91
92
93
94 /****************************************************************************/
95 void lfds610_queue_internal_new_element_from_freelist( struct lfds610_queue_state *qs, struct lfds610_queue_element *qe[LFDS610_QUEUE_PAC_SIZE], void *user_data )
96 {
97   struct lfds610_freelist_element
98     *fe;
99
100   assert( qs != NULL );
101   assert( qe != NULL );
102   // TRD : user_data can be any value in its range
103
104   qe[LFDS610_QUEUE_POINTER] = NULL;
105
106   lfds610_freelist_pop( qs->fs, &fe );
107
108   if( fe != NULL )
109     lfds610_queue_internal_init_element( qs, qe, fe, user_data );
110
111   return;
112 }
113
114
115
116
117
118 /****************************************************************************/
119 void lfds610_queue_internal_guaranteed_new_element_from_freelist( struct lfds610_queue_state *qs, struct lfds610_queue_element *qe[LFDS610_QUEUE_PAC_SIZE], void *user_data )
120 {
121   struct lfds610_freelist_element
122     *fe;
123
124   assert( qs != NULL );
125   assert( qe != NULL );
126   // TRD : user_data can be any value in its range
127
128   qe[LFDS610_QUEUE_POINTER] = NULL;
129
130   lfds610_freelist_guaranteed_pop( qs->fs, &fe );
131
132   if( fe != NULL )
133     lfds610_queue_internal_init_element( qs, qe, fe, user_data );
134
135   return;
136 }
137
138
139
140
141
142 /****************************************************************************/
143 void lfds610_queue_internal_init_element( struct lfds610_queue_state *qs, struct lfds610_queue_element *qe[LFDS610_QUEUE_PAC_SIZE], struct lfds610_freelist_element *fe, void *user_data )
144 {
145   assert( qs != NULL );
146   assert( qe != NULL );
147   assert( fe != NULL );
148   // TRD : user_data can be any value in its range
149
150   lfds610_freelist_get_user_data_from_element( fe, (void **) &qe[LFDS610_QUEUE_POINTER] );
151   qe[LFDS610_QUEUE_COUNTER] = (struct lfds610_queue_element *) lfds610_abstraction_increment( (lfds610_atom_t *) &qs->aba_counter );
152
153   qe[LFDS610_QUEUE_POINTER]->next[LFDS610_QUEUE_POINTER] = NULL;
154   qe[LFDS610_QUEUE_POINTER]->next[LFDS610_QUEUE_COUNTER] = (struct lfds610_queue_element *) lfds610_abstraction_increment( (lfds610_atom_t *) &qs->aba_counter );
155
156   qe[LFDS610_QUEUE_POINTER]->fe = fe;
157   qe[LFDS610_QUEUE_POINTER]->user_data = user_data;
158
159   return;
160 }
161