]> pd.if.org Git - liblfds/blob - liblfds/liblfds6.1.0/liblfds610/src/lfds610_freelist/lfds610_freelist_new.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds6.1.0 / liblfds610 / src / lfds610_freelist / lfds610_freelist_new.c
1 #include "lfds610_freelist_internal.h"
2
3
4
5
6
7 /****************************************************************************/
8 int lfds610_freelist_new( struct lfds610_freelist_state **fs, lfds610_atom_t number_elements, int (*user_data_init_function)(void **user_data, void *user_state), void *user_state )
9 {
10   int
11     rv = 0;
12
13   lfds610_atom_t
14     element_count;
15
16   assert( fs != NULL );
17   // TRD : number_elements can be any value in its range
18   // TRD : user_data_init_function can be NULL
19
20   *fs = (struct lfds610_freelist_state *) lfds610_liblfds_aligned_malloc( sizeof(struct lfds610_freelist_state), LFDS610_ALIGN_DOUBLE_POINTER );
21
22   if( (*fs) != NULL )
23   {
24     (*fs)->top[LFDS610_FREELIST_POINTER] = NULL;
25     (*fs)->top[LFDS610_FREELIST_COUNTER] = 0;
26     (*fs)->user_data_init_function = user_data_init_function;
27     (*fs)->user_state = user_state;
28     (*fs)->aba_counter = 0;
29     (*fs)->element_count = 0;
30
31     element_count = lfds610_freelist_new_elements( *fs, number_elements );
32
33     if( element_count == number_elements )
34       rv = 1;
35
36     if( element_count != number_elements )
37     {
38       lfds610_liblfds_aligned_free( (*fs) );
39       *fs = NULL;
40     }
41   }
42
43   LFDS610_BARRIER_STORE;
44
45   return( rv );
46 }
47
48
49
50
51
52 /****************************************************************************/
53 #pragma warning( disable : 4100 )
54
55 void lfds610_freelist_use( struct lfds610_freelist_state *fs )
56 {
57   assert( fs != NULL );
58
59   LFDS610_BARRIER_LOAD;
60
61   return;
62 }
63
64 #pragma warning( default : 4100 )
65
66
67
68
69
70 /****************************************************************************/
71 lfds610_atom_t lfds610_freelist_new_elements( struct lfds610_freelist_state *fs, lfds610_atom_t number_elements )
72 {
73   struct lfds610_freelist_element
74     *fe;
75
76   lfds610_atom_t
77     loop,
78     count = 0;
79
80   assert( fs != NULL );
81   // TRD : number_elements can be any value in its range
82   // TRD : user_data_init_function can be NULL
83
84   for( loop = 0 ; loop < number_elements ; loop++ )
85     if( lfds610_freelist_internal_new_element(fs, &fe) )
86     {
87       lfds610_freelist_push( fs, fe );
88       count++;
89     }
90
91   return( count );
92 }
93
94
95
96
97
98 /****************************************************************************/
99 lfds610_atom_t lfds610_freelist_internal_new_element( struct lfds610_freelist_state *fs, struct lfds610_freelist_element **fe )
100 {
101   lfds610_atom_t
102     rv = 0;
103
104   assert( fs != NULL );
105   assert( fe != NULL );
106
107   /* TRD : basically, does what you'd expect;
108
109            allocates an element
110            calls the user init function
111            if anything fails, cleans up,
112            sets *fe to NULL
113            and returns 0
114   */
115
116   *fe = (struct lfds610_freelist_element *) lfds610_liblfds_aligned_malloc( sizeof(struct lfds610_freelist_element), LFDS610_ALIGN_DOUBLE_POINTER );
117
118   if( *fe != NULL )
119   {
120     if( fs->user_data_init_function == NULL )
121     {
122       (*fe)->user_data = NULL;
123       rv = 1;
124     }
125
126     if( fs->user_data_init_function != NULL )
127     {
128       rv = fs->user_data_init_function( &(*fe)->user_data, fs->user_state );
129
130       if( rv == 0 )
131       {
132         lfds610_liblfds_aligned_free( *fe );
133         *fe = NULL;
134       }
135     }
136   }
137
138   if( rv == 1 )
139     lfds610_abstraction_increment( (lfds610_atom_t *) &fs->element_count );
140
141   return( rv );
142 }
143