]> pd.if.org Git - liblfds/blob - liblfds/liblfds6.0.1/liblfds601/src/lfds601_queue/lfds601_queue_new.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds6.0.1 / liblfds601 / src / lfds601_queue / lfds601_queue_new.c
1 #include "lfds601_queue_internal.h"\r
2 \r
3 \r
4 \r
5 \r
6 \r
7 /****************************************************************************/\r
8 int lfds601_queue_new( struct lfds601_queue_state **qs, lfds601_atom_t number_elements )\r
9 {\r
10   int\r
11     rv = 0;\r
12 \r
13   struct lfds601_queue_element\r
14     *qe[LFDS601_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 lfds601_queue_state *) lfds601_abstraction_aligned_malloc( sizeof(struct lfds601_queue_state), LFDS601_ALIGN_DOUBLE_POINTER );\r
20 \r
21   if( *qs != NULL )\r
22   {\r
23     // TRD : the size of the lfds601_freelist is the size of the lfds601_queue (+1 for the leading dummy element, which is hidden from the caller)\r
24     lfds601_freelist_new( &(*qs)->fs, number_elements+1, lfds601_queue_internal_freelist_init_function, NULL );\r
25 \r
26     if( (*qs)->fs != NULL )\r
27     {\r
28       lfds601_queue_internal_new_element_from_freelist( *qs, qe, NULL );\r
29       (*qs)->enqueue[LFDS601_QUEUE_POINTER] = (*qs)->dequeue[LFDS601_QUEUE_POINTER] = qe[LFDS601_QUEUE_POINTER];\r
30       (*qs)->aba_counter = 0;\r
31       rv = 1;\r
32     }\r
33 \r
34     if( (*qs)->fs == NULL )\r
35     {\r
36       lfds601_abstraction_aligned_free( *qs );\r
37       *qs = NULL;\r
38     }\r
39   }\r
40 \r
41   return( rv );\r
42 }\r
43 \r
44 \r
45 \r
46 \r
47 \r
48 /****************************************************************************/\r
49 #pragma warning( disable : 4100 )\r
50 \r
51 int lfds601_queue_internal_freelist_init_function( void **user_data, void *user_state )\r
52 {\r
53   int\r
54     rv = 0;\r
55 \r
56   assert( user_data != NULL );\r
57   assert( user_state == NULL );\r
58 \r
59   *user_data = lfds601_abstraction_aligned_malloc( sizeof(struct lfds601_queue_element), LFDS601_ALIGN_DOUBLE_POINTER );\r
60 \r
61   if( *user_data != NULL )\r
62     rv = 1;\r
63 \r
64   return( rv );\r
65 }\r
66 \r
67 #pragma warning( default : 4100 )\r
68 \r
69 \r
70 \r
71 \r
72 \r
73 /****************************************************************************/\r
74 void lfds601_queue_internal_new_element_from_freelist( struct lfds601_queue_state *qs, struct lfds601_queue_element *qe[LFDS601_QUEUE_PAC_SIZE], void *user_data )\r
75 {\r
76   struct lfds601_freelist_element\r
77     *fe;\r
78 \r
79   assert( qs != NULL );\r
80   assert( qe != NULL );\r
81   // TRD : user_data can be any value in its range\r
82 \r
83   qe[LFDS601_QUEUE_POINTER] = NULL;\r
84 \r
85   lfds601_freelist_pop( qs->fs, &fe );\r
86 \r
87   if( fe != NULL )\r
88     lfds601_queue_internal_init_element( qs, qe, fe, user_data );\r
89 \r
90   return;\r
91 }\r
92 \r
93 \r
94 \r
95 \r
96 \r
97 /****************************************************************************/\r
98 void lfds601_queue_internal_guaranteed_new_element_from_freelist( struct lfds601_queue_state *qs, struct lfds601_queue_element *qe[LFDS601_QUEUE_PAC_SIZE], void *user_data )\r
99 {\r
100   struct lfds601_freelist_element\r
101     *fe;\r
102 \r
103   assert( qs != NULL );\r
104   assert( qe != NULL );\r
105   // TRD : user_data can be any value in its range\r
106 \r
107   qe[LFDS601_QUEUE_POINTER] = NULL;\r
108 \r
109   lfds601_freelist_guaranteed_pop( qs->fs, &fe );\r
110 \r
111   if( fe != NULL )\r
112     lfds601_queue_internal_init_element( qs, qe, fe, user_data );\r
113 \r
114   return;\r
115 }\r
116 \r
117 \r
118 \r
119 \r
120 \r
121 /****************************************************************************/\r
122 void lfds601_queue_internal_init_element( struct lfds601_queue_state *qs, struct lfds601_queue_element *qe[LFDS601_QUEUE_PAC_SIZE], struct lfds601_freelist_element *fe, void *user_data )\r
123 {\r
124   assert( qs != NULL );\r
125   assert( qe != NULL );\r
126   assert( fe != NULL );\r
127   // TRD : user_data can be any value in its range\r
128 \r
129   lfds601_freelist_get_user_data_from_element( fe, (void **) &qe[LFDS601_QUEUE_POINTER] );\r
130   qe[LFDS601_QUEUE_COUNTER] = (struct lfds601_queue_element *) lfds601_abstraction_increment( (lfds601_atom_t *) &qs->aba_counter );\r
131 \r
132   qe[LFDS601_QUEUE_POINTER]->next[LFDS601_QUEUE_POINTER] = NULL;\r
133   qe[LFDS601_QUEUE_POINTER]->next[LFDS601_QUEUE_COUNTER] = (struct lfds601_queue_element *) lfds601_abstraction_increment( (lfds601_atom_t *) &qs->aba_counter );\r
134 \r
135   qe[LFDS601_QUEUE_POINTER]->fe = fe;\r
136   qe[LFDS601_QUEUE_POINTER]->user_data = user_data;\r
137 \r
138   return;\r
139 }\r
140 \r