1 #include "lfds610_freelist_internal.h"
7 /****************************************************************************/
8 struct lfds610_freelist_element *lfds610_freelist_pop( struct lfds610_freelist_state *fs, struct lfds610_freelist_element **fe )
10 LFDS610_ALIGN(LFDS610_ALIGN_DOUBLE_POINTER) struct lfds610_freelist_element
11 *fe_local[LFDS610_FREELIST_PAC_SIZE];
18 fe_local[LFDS610_FREELIST_COUNTER] = fs->top[LFDS610_FREELIST_COUNTER];
19 fe_local[LFDS610_FREELIST_POINTER] = fs->top[LFDS610_FREELIST_POINTER];
21 /* TRD : note that lfds610_abstraction_dcas loads the original value of the destination (fs->top) into the compare (fe_local)
22 (this happens of course after the CAS itself has occurred inside lfds610_abstraction_dcas)
27 if( fe_local[LFDS610_FREELIST_POINTER] == NULL )
33 while( 0 == lfds610_abstraction_dcas((volatile lfds610_atom_t *) fs->top, (lfds610_atom_t *) fe_local[LFDS610_FREELIST_POINTER]->next, (lfds610_atom_t *) fe_local) );
35 *fe = (struct lfds610_freelist_element *) fe_local[LFDS610_FREELIST_POINTER];
44 /****************************************************************************/
45 struct lfds610_freelist_element *lfds610_freelist_guaranteed_pop( struct lfds610_freelist_state *fs, struct lfds610_freelist_element **fe )
50 lfds610_freelist_internal_new_element( fs, fe );
59 /****************************************************************************/
60 void lfds610_freelist_push( struct lfds610_freelist_state *fs, struct lfds610_freelist_element *fe )
62 LFDS610_ALIGN(LFDS610_ALIGN_DOUBLE_POINTER) struct lfds610_freelist_element
63 *fe_local[LFDS610_FREELIST_PAC_SIZE],
64 *original_fe_next[LFDS610_FREELIST_PAC_SIZE];
71 fe_local[LFDS610_FREELIST_POINTER] = fe;
72 fe_local[LFDS610_FREELIST_COUNTER] = (struct lfds610_freelist_element *) lfds610_abstraction_increment( (lfds610_atom_t *) &fs->aba_counter );
74 original_fe_next[LFDS610_FREELIST_POINTER] = fs->top[LFDS610_FREELIST_POINTER];
75 original_fe_next[LFDS610_FREELIST_COUNTER] = fs->top[LFDS610_FREELIST_COUNTER];
77 /* TRD : note that lfds610_abstraction_dcas loads the original value of the destination (fs->top) into the compare (original_fe_next)
78 (this happens of course after the CAS itself has occurred inside lfds610_abstraction_dcas)
79 this then causes us in our loop, should we repeat it, to update fe_local->next to a more
80 up-to-date version of the head of the lfds610_freelist
85 fe_local[LFDS610_FREELIST_POINTER]->next[LFDS610_FREELIST_POINTER] = original_fe_next[LFDS610_FREELIST_POINTER];
86 fe_local[LFDS610_FREELIST_POINTER]->next[LFDS610_FREELIST_COUNTER] = original_fe_next[LFDS610_FREELIST_COUNTER];
88 while( 0 == lfds610_abstraction_dcas((volatile lfds610_atom_t *) fs->top, (lfds610_atom_t *) fe_local, (lfds610_atom_t *) original_fe_next) );