]> pd.if.org Git - liblfds/blob - liblfds/liblfds6.0.0/liblfds600/src/lfds600_queue/lfds600_queue_new.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds6.0.0 / liblfds600 / src / lfds600_queue / lfds600_queue_new.c
1 #include "lfds600_queue_internal.h"
2
3
4
5
6
7 /****************************************************************************/
8 int lfds600_queue_new( struct lfds600_queue_state **qs, lfds600_atom_t number_elements )
9 {
10   int
11     rv = 0;
12
13   struct lfds600_queue_element
14     *qe[LFDS600_QUEUE_PAC_SIZE];
15
16   assert( qs != NULL );
17   // TRD : number_elements can be any value in its range
18
19   *qs = (struct lfds600_queue_state *) lfds600_abstraction_aligned_malloc( sizeof(struct lfds600_queue_state), LFDS600_ALIGN_DOUBLE_POINTER );
20
21   if( *qs != NULL )
22   {
23     // TRD : the size of the lfds600_freelist is the size of the lfds600_queue (+1 for the leading dummy element, which is hidden from the caller)
24     lfds600_freelist_new( &(*qs)->fs, number_elements+1, lfds600_queue_internal_freelist_init_function, NULL );
25
26     if( (*qs)->fs != NULL )
27     {
28       lfds600_queue_internal_new_element_from_freelist( *qs, qe, NULL );
29       (*qs)->enqueue[LFDS600_QUEUE_POINTER] = (*qs)->dequeue[LFDS600_QUEUE_POINTER] = qe[LFDS600_QUEUE_POINTER];
30       (*qs)->aba_counter = 0;
31       rv = 1;
32     }
33
34     if( (*qs)->fs == NULL )
35     {
36       lfds600_abstraction_aligned_free( *qs );
37       *qs = NULL;
38     }
39   }
40
41   return( rv );
42 }
43
44
45
46
47
48 /****************************************************************************/
49 #pragma warning( disable : 4100 )
50
51 int lfds600_queue_internal_freelist_init_function( void **user_data, void *user_state )
52 {
53   int
54     rv = 0;
55
56   assert( user_data != NULL );
57   assert( user_state == NULL );
58
59   *user_data = lfds600_abstraction_aligned_malloc( sizeof(struct lfds600_queue_element), LFDS600_ALIGN_DOUBLE_POINTER );
60
61   if( *user_data != NULL )
62     rv = 1;
63
64   return( rv );
65 }
66
67 #pragma warning( default : 4100 )
68
69
70
71
72
73 /****************************************************************************/
74 void lfds600_queue_internal_new_element_from_freelist( struct lfds600_queue_state *qs, struct lfds600_queue_element *qe[LFDS600_QUEUE_PAC_SIZE], void *user_data )
75 {
76   struct lfds600_freelist_element
77     *fe;
78
79   assert( qs != NULL );
80   assert( qe != NULL );
81   // TRD : user_data can be any value in its range
82
83   qe[LFDS600_QUEUE_POINTER] = NULL;
84
85   lfds600_freelist_pop( qs->fs, &fe );
86
87   if( fe != NULL )
88     lfds600_queue_internal_init_element( qs, qe, fe, user_data );
89
90   return;
91 }
92
93
94
95
96
97 /****************************************************************************/
98 void lfds600_queue_internal_guaranteed_new_element_from_freelist( struct lfds600_queue_state *qs, struct lfds600_queue_element *qe[LFDS600_QUEUE_PAC_SIZE], void *user_data )
99 {
100   struct lfds600_freelist_element
101     *fe;
102
103   assert( qs != NULL );
104   assert( qe != NULL );
105   // TRD : user_data can be any value in its range
106
107   qe[LFDS600_QUEUE_POINTER] = NULL;
108
109   lfds600_freelist_guaranteed_pop( qs->fs, &fe );
110
111   if( fe != NULL )
112     lfds600_queue_internal_init_element( qs, qe, fe, user_data );
113
114   return;
115 }
116
117
118
119
120
121 /****************************************************************************/
122 void lfds600_queue_internal_init_element( struct lfds600_queue_state *qs, struct lfds600_queue_element *qe[LFDS600_QUEUE_PAC_SIZE], struct lfds600_freelist_element *fe, void *user_data )
123 {
124   assert( qs != NULL );
125   assert( qe != NULL );
126   assert( fe != NULL );
127   // TRD : user_data can be any value in its range
128
129   lfds600_freelist_get_user_data_from_element( fe, (void **) &qe[LFDS600_QUEUE_POINTER] );
130   qe[LFDS600_QUEUE_COUNTER] = (struct lfds600_queue_element *) lfds600_abstraction_increment( (lfds600_atom_t *) &qs->aba_counter );
131
132   qe[LFDS600_QUEUE_POINTER]->next[LFDS600_QUEUE_POINTER] = NULL;
133   qe[LFDS600_QUEUE_POINTER]->next[LFDS600_QUEUE_COUNTER] = (struct lfds600_queue_element *) lfds600_abstraction_increment( (lfds600_atom_t *) &qs->aba_counter );
134
135   qe[LFDS600_QUEUE_POINTER]->fe = fe;
136   qe[LFDS600_QUEUE_POINTER]->user_data = user_data;
137
138   return;
139 }
140