1 #include "lfds601_stack_internal.h"
\r
7 /****************************************************************************/
\r
8 int lfds601_stack_push( struct lfds601_stack_state *ss, void *user_data )
\r
10 LFDS601_ALIGN(LFDS601_ALIGN_DOUBLE_POINTER) struct lfds601_stack_element
\r
11 *se[LFDS601_STACK_PAC_SIZE];
\r
13 assert( ss != NULL );
\r
14 // TRD : user_data can be NULL
\r
16 lfds601_stack_internal_new_element_from_freelist( ss, se, user_data );
\r
18 if( se[LFDS601_STACK_POINTER] == NULL )
\r
21 lfds601_stack_internal_push( ss, se );
\r
30 /****************************************************************************/
\r
31 int lfds601_stack_guaranteed_push( struct lfds601_stack_state *ss, void *user_data )
\r
33 LFDS601_ALIGN(LFDS601_ALIGN_DOUBLE_POINTER) struct lfds601_stack_element
\r
34 *se[LFDS601_STACK_PAC_SIZE];
\r
36 assert( ss != NULL );
\r
37 // TRD : user_data can be NULL
\r
39 /* TRD : this function allocated a new lfds601_freelist element and uses that
\r
40 to push onto the lfds601_stack, guaranteeing success (unless malloc()
\r
44 lfds601_stack_internal_new_element( ss, se, user_data );
\r
46 // TRD : malloc failed
\r
47 if( se[LFDS601_STACK_POINTER] == NULL )
\r
50 lfds601_stack_internal_push( ss, se );
\r
59 /****************************************************************************/
\r
60 void lfds601_stack_internal_push( struct lfds601_stack_state *ss, struct lfds601_stack_element *se[LFDS601_STACK_PAC_SIZE] )
\r
62 LFDS601_ALIGN(LFDS601_ALIGN_DOUBLE_POINTER) struct lfds601_stack_element
\r
63 *original_se_next[LFDS601_STACK_PAC_SIZE];
\r
65 assert( ss != NULL );
\r
66 assert( se != NULL );
\r
68 original_se_next[LFDS601_STACK_POINTER] = ss->top[LFDS601_STACK_POINTER];
\r
69 original_se_next[LFDS601_STACK_COUNTER] = ss->top[LFDS601_STACK_COUNTER];
\r
73 se[LFDS601_STACK_POINTER]->next[LFDS601_STACK_POINTER] = original_se_next[LFDS601_STACK_POINTER];
\r
74 se[LFDS601_STACK_POINTER]->next[LFDS601_STACK_COUNTER] = original_se_next[LFDS601_STACK_COUNTER];
\r
76 while( 0 == lfds601_abstraction_dcas((volatile lfds601_atom_t *) ss->top, (lfds601_atom_t *) se, (lfds601_atom_t *) original_se_next) );
\r
85 /****************************************************************************/
\r
86 int lfds601_stack_pop( struct lfds601_stack_state *ss, void **user_data )
\r
88 LFDS601_ALIGN(LFDS601_ALIGN_DOUBLE_POINTER) struct lfds601_stack_element
\r
89 *se[LFDS601_STACK_PAC_SIZE];
\r
91 assert( ss != NULL );
\r
92 assert( user_data != NULL );
\r
94 se[LFDS601_STACK_COUNTER] = ss->top[LFDS601_STACK_COUNTER];
\r
95 se[LFDS601_STACK_POINTER] = ss->top[LFDS601_STACK_POINTER];
\r
99 if( se[LFDS601_STACK_POINTER] == NULL )
\r
102 while( 0 == lfds601_abstraction_dcas((volatile lfds601_atom_t *) ss->top, (lfds601_atom_t *) se[LFDS601_STACK_POINTER]->next, (lfds601_atom_t *) se) );
\r
104 *user_data = se[LFDS601_STACK_POINTER]->user_data;
\r
106 lfds601_freelist_push( ss->fs, se[LFDS601_STACK_POINTER]->fe );
\r