1 #include "lfds600_stack_internal.h"
7 /****************************************************************************/
8 int lfds600_stack_push( struct lfds600_stack_state *ss, void *user_data )
10 LFDS600_ALIGN(LFDS600_ALIGN_DOUBLE_POINTER) struct lfds600_stack_element
11 *se[LFDS600_STACK_PAC_SIZE];
14 // TRD : user_data can be NULL
16 lfds600_stack_internal_new_element_from_freelist( ss, se, user_data );
18 if( se[LFDS600_STACK_POINTER] == NULL )
21 lfds600_stack_internal_push( ss, se );
30 /****************************************************************************/
31 int lfds600_stack_guaranteed_push( struct lfds600_stack_state *ss, void *user_data )
33 LFDS600_ALIGN(LFDS600_ALIGN_DOUBLE_POINTER) struct lfds600_stack_element
34 *se[LFDS600_STACK_PAC_SIZE];
37 // TRD : user_data can be NULL
39 /* TRD : this function allocated a new lfds600_freelist element and uses that
40 to push onto the lfds600_stack, guaranteeing success (unless malloc()
44 lfds600_stack_internal_new_element( ss, se, user_data );
46 // TRD : malloc failed
47 if( se[LFDS600_STACK_POINTER] == NULL )
50 lfds600_stack_internal_push( ss, se );
59 /****************************************************************************/
60 void lfds600_stack_internal_push( struct lfds600_stack_state *ss, struct lfds600_stack_element *se[LFDS600_STACK_PAC_SIZE] )
62 LFDS600_ALIGN(LFDS600_ALIGN_DOUBLE_POINTER) struct lfds600_stack_element
63 *original_se_next[LFDS600_STACK_PAC_SIZE];
68 original_se_next[LFDS600_STACK_POINTER] = ss->top[LFDS600_STACK_POINTER];
69 original_se_next[LFDS600_STACK_COUNTER] = ss->top[LFDS600_STACK_COUNTER];
73 se[LFDS600_STACK_POINTER]->next[LFDS600_STACK_POINTER] = original_se_next[LFDS600_STACK_POINTER];
74 se[LFDS600_STACK_POINTER]->next[LFDS600_STACK_COUNTER] = original_se_next[LFDS600_STACK_COUNTER];
76 while( 0 == lfds600_abstraction_dcas((volatile lfds600_atom_t *) ss->top, (lfds600_atom_t *) se, (lfds600_atom_t *) original_se_next) );
85 /****************************************************************************/
86 int lfds600_stack_pop( struct lfds600_stack_state *ss, void **user_data )
88 LFDS600_ALIGN(LFDS600_ALIGN_DOUBLE_POINTER) struct lfds600_stack_element
89 *se[LFDS600_STACK_PAC_SIZE];
92 assert( user_data != NULL );
94 se[LFDS600_STACK_COUNTER] = ss->top[LFDS600_STACK_COUNTER];
95 se[LFDS600_STACK_POINTER] = ss->top[LFDS600_STACK_POINTER];
99 if( se[LFDS600_STACK_POINTER] == NULL )
102 while( 0 == lfds600_abstraction_dcas((volatile lfds600_atom_t *) ss->top, (lfds600_atom_t *) se[LFDS600_STACK_POINTER]->next, (lfds600_atom_t *) se) );
104 *user_data = se[LFDS600_STACK_POINTER]->user_data;
106 lfds600_freelist_push( ss->fs, se[LFDS600_STACK_POINTER]->fe );