]> pd.if.org Git - liblfds/blob - liblfds/liblfds6.0.0/liblfds600/src/lfds600_freelist/lfds600_freelist_new.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds6.0.0 / liblfds600 / src / lfds600_freelist / lfds600_freelist_new.c
1 #include "lfds600_freelist_internal.h"
2
3
4
5
6
7 /****************************************************************************/
8 int lfds600_freelist_new( struct lfds600_freelist_state **fs, lfds600_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   lfds600_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 lfds600_freelist_state *) lfds600_abstraction_aligned_malloc( sizeof(struct lfds600_freelist_state), LFDS600_ALIGN_DOUBLE_POINTER );
21
22   if( (*fs) != NULL )
23   {
24     (*fs)->top[LFDS600_FREELIST_POINTER] = NULL;
25     (*fs)->top[LFDS600_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 = lfds600_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       lfds600_abstraction_aligned_free( (*fs) );
39       *fs = NULL;
40     }
41   }
42
43   return( rv );
44 }
45
46
47
48
49
50 /****************************************************************************/
51 lfds600_atom_t lfds600_freelist_new_elements( struct lfds600_freelist_state *fs, lfds600_atom_t number_elements )
52 {
53   struct lfds600_freelist_element
54     *fe;
55
56   lfds600_atom_t
57     loop,
58     count = 0;
59
60   assert( fs != NULL );
61   // TRD : number_elements can be any value in its range
62   // TRD : user_data_init_function can be NULL
63
64   for( loop = 0 ; loop < number_elements ; loop++ )
65     if( lfds600_freelist_internal_new_element(fs, &fe) )
66     {
67       lfds600_freelist_push( fs, fe );
68       count++;
69     }
70
71   return( count );
72 }
73
74
75
76
77
78 /****************************************************************************/
79 lfds600_atom_t lfds600_freelist_internal_new_element( struct lfds600_freelist_state *fs, struct lfds600_freelist_element **fe )
80 {
81   lfds600_atom_t
82     rv = 0;
83
84   assert( fs != NULL );
85   assert( fe != NULL );
86
87   /* TRD : basically, does what you'd expect;
88
89            allocates an element
90            calls the user init function
91            if anything fails, cleans up,
92            sets *fe to NULL
93            and returns 0
94   */
95
96   *fe = (struct lfds600_freelist_element *) lfds600_abstraction_aligned_malloc( sizeof(struct lfds600_freelist_element), LFDS600_ALIGN_DOUBLE_POINTER );
97
98   if( *fe != NULL )
99   {
100     if( fs->user_data_init_function == NULL )
101     {
102       (*fe)->user_data = NULL;
103       rv = 1;
104     }
105
106     if( fs->user_data_init_function != NULL )
107     {
108       rv = fs->user_data_init_function( &(*fe)->user_data, fs->user_state );
109
110       if( rv == 0 )
111       {
112         lfds600_abstraction_aligned_free( *fe );
113         *fe = NULL;
114       }
115     }
116   }
117
118   if( rv == 1 )
119     lfds600_abstraction_increment( (lfds600_atom_t *) &fs->element_count );
120
121   return( rv );
122 }
123