]> pd.if.org Git - liblfds/blob - liblfds/liblfds6.1.1/liblfds611/src/lfds611_queue/lfds611_queue_new.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds6.1.1 / liblfds611 / src / lfds611_queue / lfds611_queue_new.c
1 #include "lfds611_queue_internal.h"\r
2 \r
3 \r
4 \r
5 \r
6 \r
7 /****************************************************************************/\r
8 int lfds611_queue_new( struct lfds611_queue_state **qs, lfds611_atom_t number_elements )\r
9 {\r
10   int\r
11     rv = 0;\r
12 \r
13   struct lfds611_queue_element\r
14     *qe[LFDS611_QUEUE_PAC_SIZE];\r
15 \r
16   assert( qs != NULL );\r
17   // TRD : number_elements can be any value in its range\r
18 \r
19   *qs = (struct lfds611_queue_state *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_queue_state), LFDS611_ALIGN_DOUBLE_POINTER );\r
20 \r
21   if( *qs != NULL )\r
22   {\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
25 \r
26     if( (*qs)->fs != NULL )\r
27     {\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
32       rv = 1;\r
33     }\r
34 \r
35     if( (*qs)->fs == NULL )\r
36     {\r
37       lfds611_liblfds_aligned_free( *qs );\r
38       *qs = NULL;\r
39     }\r
40   }\r
41 \r
42   LFDS611_BARRIER_STORE;\r
43 \r
44   return( rv );\r
45 }\r
46 \r
47 \r
48 \r
49 \r
50 \r
51 /****************************************************************************/\r
52 #pragma warning( disable : 4100 )\r
53 \r
54 void lfds611_queue_use( struct lfds611_queue_state *qs )\r
55 {\r
56   assert( qs != NULL );\r
57 \r
58   LFDS611_BARRIER_LOAD;\r
59 \r
60   return;\r
61 }\r
62 \r
63 #pragma warning( default : 4100 )\r
64 \r
65 \r
66 \r
67 \r
68 \r
69 /****************************************************************************/\r
70 #pragma warning( disable : 4100 )\r
71 \r
72 int lfds611_queue_internal_freelist_init_function( void **user_data, void *user_state )\r
73 {\r
74   int\r
75     rv = 0;\r
76 \r
77   assert( user_data != NULL );\r
78   assert( user_state == NULL );\r
79 \r
80   *user_data = lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_queue_element), LFDS611_ALIGN_DOUBLE_POINTER );\r
81 \r
82   if( *user_data != NULL )\r
83     rv = 1;\r
84 \r
85   return( rv );\r
86 }\r
87 \r
88 #pragma warning( default : 4100 )\r
89 \r
90 \r
91 \r
92 \r
93 \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
96 {\r
97   struct lfds611_freelist_element\r
98     *fe;\r
99 \r
100   assert( qs != NULL );\r
101   assert( qe != NULL );\r
102   // TRD : user_data can be any value in its range\r
103 \r
104   qe[LFDS611_QUEUE_POINTER] = NULL;\r
105 \r
106   lfds611_freelist_pop( qs->fs, &fe );\r
107 \r
108   if( fe != NULL )\r
109     lfds611_queue_internal_init_element( qs, qe, fe, user_data );\r
110 \r
111   return;\r
112 }\r
113 \r
114 \r
115 \r
116 \r
117 \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
120 {\r
121   struct lfds611_freelist_element\r
122     *fe;\r
123 \r
124   assert( qs != NULL );\r
125   assert( qe != NULL );\r
126   // TRD : user_data can be any value in its range\r
127 \r
128   qe[LFDS611_QUEUE_POINTER] = NULL;\r
129 \r
130   lfds611_freelist_guaranteed_pop( qs->fs, &fe );\r
131 \r
132   if( fe != NULL )\r
133     lfds611_queue_internal_init_element( qs, qe, fe, user_data );\r
134 \r
135   return;\r
136 }\r
137 \r
138 \r
139 \r
140 \r
141 \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
144 {\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
149 \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
152 \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
155 \r
156   qe[LFDS611_QUEUE_POINTER]->fe = fe;\r
157   qe[LFDS611_QUEUE_POINTER]->user_data = user_data;\r
158 \r
159   return;\r
160 }\r
161 \r