1 #include "lfds610_stack_internal.h"
7 /****************************************************************************/
8 int lfds610_stack_push( struct lfds610_stack_state *ss, void *user_data )
10 LFDS610_ALIGN(LFDS610_ALIGN_DOUBLE_POINTER) struct lfds610_stack_element
11 *se[LFDS610_STACK_PAC_SIZE];
14 // TRD : user_data can be NULL
16 lfds610_stack_internal_new_element_from_freelist( ss, se, user_data );
18 if( se[LFDS610_STACK_POINTER] == NULL )
21 lfds610_stack_internal_push( ss, se );
30 /****************************************************************************/
31 int lfds610_stack_guaranteed_push( struct lfds610_stack_state *ss, void *user_data )
33 LFDS610_ALIGN(LFDS610_ALIGN_DOUBLE_POINTER) struct lfds610_stack_element
34 *se[LFDS610_STACK_PAC_SIZE];
37 // TRD : user_data can be NULL
39 /* TRD : this function allocated a new lfds610_freelist element and uses that
40 to push onto the lfds610_stack, guaranteeing success (unless malloc()
44 lfds610_stack_internal_new_element( ss, se, user_data );
46 // TRD : malloc failed
47 if( se[LFDS610_STACK_POINTER] == NULL )
50 lfds610_stack_internal_push( ss, se );
59 /****************************************************************************/
60 void lfds610_stack_internal_push( struct lfds610_stack_state *ss, struct lfds610_stack_element *se[LFDS610_STACK_PAC_SIZE] )
62 LFDS610_ALIGN(LFDS610_ALIGN_DOUBLE_POINTER) struct lfds610_stack_element
63 *original_se_next[LFDS610_STACK_PAC_SIZE];
70 original_se_next[LFDS610_STACK_POINTER] = ss->top[LFDS610_STACK_POINTER];
71 original_se_next[LFDS610_STACK_COUNTER] = ss->top[LFDS610_STACK_COUNTER];
75 se[LFDS610_STACK_POINTER]->next[LFDS610_STACK_POINTER] = original_se_next[LFDS610_STACK_POINTER];
76 se[LFDS610_STACK_POINTER]->next[LFDS610_STACK_COUNTER] = original_se_next[LFDS610_STACK_COUNTER];
78 while( 0 == lfds610_abstraction_dcas((volatile lfds610_atom_t *) ss->top, (lfds610_atom_t *) se, (lfds610_atom_t *) original_se_next) );
87 /****************************************************************************/
88 int lfds610_stack_pop( struct lfds610_stack_state *ss, void **user_data )
90 LFDS610_ALIGN(LFDS610_ALIGN_DOUBLE_POINTER) struct lfds610_stack_element
91 *se[LFDS610_STACK_PAC_SIZE];
94 assert( user_data != NULL );
98 se[LFDS610_STACK_COUNTER] = ss->top[LFDS610_STACK_COUNTER];
99 se[LFDS610_STACK_POINTER] = ss->top[LFDS610_STACK_POINTER];
103 if( se[LFDS610_STACK_POINTER] == NULL )
106 while( 0 == lfds610_abstraction_dcas((volatile lfds610_atom_t *) ss->top, (lfds610_atom_t *) se[LFDS610_STACK_POINTER]->next, (lfds610_atom_t *) se) );
108 *user_data = se[LFDS610_STACK_POINTER]->user_data;
110 lfds610_freelist_push( ss->fs, se[LFDS610_STACK_POINTER]->fe );