1 #include "lfds611_freelist_internal.h"
\r
7 /****************************************************************************/
\r
8 int lfds611_freelist_new( struct lfds611_freelist_state **fs, lfds611_atom_t number_elements, int (*user_data_init_function)(void **user_data, void *user_state), void *user_state )
\r
16 assert( fs != NULL );
\r
17 // TRD : number_elements can be any value in its range
\r
18 // TRD : user_data_init_function can be NULL
\r
20 *fs = (struct lfds611_freelist_state *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_freelist_state), LFDS611_ALIGN_DOUBLE_POINTER );
\r
24 (*fs)->top[LFDS611_FREELIST_POINTER] = NULL;
\r
25 (*fs)->top[LFDS611_FREELIST_COUNTER] = 0;
\r
26 (*fs)->user_data_init_function = user_data_init_function;
\r
27 (*fs)->user_state = user_state;
\r
28 (*fs)->aba_counter = 0;
\r
29 (*fs)->element_count = 0;
\r
31 element_count = lfds611_freelist_new_elements( *fs, number_elements );
\r
33 if( element_count == number_elements )
\r
36 if( element_count != number_elements )
\r
38 lfds611_liblfds_aligned_free( (*fs) );
\r
43 LFDS611_BARRIER_STORE;
\r
52 /****************************************************************************/
\r
53 #pragma warning( disable : 4100 )
\r
55 void lfds611_freelist_use( struct lfds611_freelist_state *fs )
\r
57 assert( fs != NULL );
\r
59 LFDS611_BARRIER_LOAD;
\r
64 #pragma warning( default : 4100 )
\r
70 /****************************************************************************/
\r
71 lfds611_atom_t lfds611_freelist_new_elements( struct lfds611_freelist_state *fs, lfds611_atom_t number_elements )
\r
73 struct lfds611_freelist_element
\r
80 assert( fs != NULL );
\r
81 // TRD : number_elements can be any value in its range
\r
82 // TRD : user_data_init_function can be NULL
\r
84 for( loop = 0 ; loop < number_elements ; loop++ )
\r
85 if( lfds611_freelist_internal_new_element(fs, &fe) )
\r
87 lfds611_freelist_push( fs, fe );
\r
98 /****************************************************************************/
\r
99 lfds611_atom_t lfds611_freelist_internal_new_element( struct lfds611_freelist_state *fs, struct lfds611_freelist_element **fe )
\r
104 assert( fs != NULL );
\r
105 assert( fe != NULL );
\r
107 /* TRD : basically, does what you'd expect;
\r
109 allocates an element
\r
110 calls the user init function
\r
111 if anything fails, cleans up,
\r
116 *fe = (struct lfds611_freelist_element *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_freelist_element), LFDS611_ALIGN_DOUBLE_POINTER );
\r
120 if( fs->user_data_init_function == NULL )
\r
122 (*fe)->user_data = NULL;
\r
126 if( fs->user_data_init_function != NULL )
\r
128 rv = fs->user_data_init_function( &(*fe)->user_data, fs->user_state );
\r
132 lfds611_liblfds_aligned_free( *fe );
\r
139 lfds611_abstraction_increment( (lfds611_atom_t *) &fs->element_count );
\r