1 #include "lfds600_freelist_internal.h"
7 /****************************************************************************/
8 struct lfds600_freelist_element *lfds600_freelist_pop( struct lfds600_freelist_state *fs, struct lfds600_freelist_element **fe )
10 LFDS600_ALIGN(LFDS600_ALIGN_DOUBLE_POINTER) struct lfds600_freelist_element
11 *fe_local[LFDS600_FREELIST_PAC_SIZE];
16 fe_local[LFDS600_FREELIST_COUNTER] = fs->top[LFDS600_FREELIST_COUNTER];
17 fe_local[LFDS600_FREELIST_POINTER] = fs->top[LFDS600_FREELIST_POINTER];
19 /* TRD : note that lfds600_abstraction_dcas loads the original value of the destination (fs->top) into the compare (fe_local)
20 (this happens of course after the CAS itself has occurred inside lfds600_abstraction_dcas)
25 if( fe_local[LFDS600_FREELIST_POINTER] == NULL )
31 while( 0 == lfds600_abstraction_dcas((volatile lfds600_atom_t *) fs->top, (lfds600_atom_t *) fe_local[LFDS600_FREELIST_POINTER]->next, (lfds600_atom_t *) fe_local) );
33 *fe = (struct lfds600_freelist_element *) fe_local[LFDS600_FREELIST_POINTER];
42 /****************************************************************************/
43 struct lfds600_freelist_element *lfds600_freelist_guaranteed_pop( struct lfds600_freelist_state *fs, struct lfds600_freelist_element **fe )
48 lfds600_freelist_internal_new_element( fs, fe );
57 /****************************************************************************/
58 void lfds600_freelist_push( struct lfds600_freelist_state *fs, struct lfds600_freelist_element *fe )
60 LFDS600_ALIGN(LFDS600_ALIGN_DOUBLE_POINTER) struct lfds600_freelist_element
61 *fe_local[LFDS600_FREELIST_PAC_SIZE],
62 *original_fe_next[LFDS600_FREELIST_PAC_SIZE];
67 fe_local[LFDS600_FREELIST_POINTER] = fe;
68 fe_local[LFDS600_FREELIST_COUNTER] = (struct lfds600_freelist_element *) lfds600_abstraction_increment( (lfds600_atom_t *) &fs->aba_counter );
70 original_fe_next[LFDS600_FREELIST_POINTER] = fs->top[LFDS600_FREELIST_POINTER];
71 original_fe_next[LFDS600_FREELIST_COUNTER] = fs->top[LFDS600_FREELIST_COUNTER];
73 /* TRD : note that lfds600_abstraction_dcas loads the original value of the destination (fs->top) into the compare (original_fe_next)
74 (this happens of course after the CAS itself has occurred inside lfds600_abstraction_dcas)
75 this then causes us in our loop, should we repeat it, to update fe_local->next to a more
76 up-to-date version of the head of the lfds600_freelist
81 fe_local[LFDS600_FREELIST_POINTER]->next[LFDS600_FREELIST_POINTER] = original_fe_next[LFDS600_FREELIST_POINTER];
82 fe_local[LFDS600_FREELIST_POINTER]->next[LFDS600_FREELIST_COUNTER] = original_fe_next[LFDS600_FREELIST_COUNTER];
84 while( 0 == lfds600_abstraction_dcas((volatile lfds600_atom_t *) fs->top, (lfds600_atom_t *) fe_local, (lfds600_atom_t *) original_fe_next) );