1 #include "lfds611_stack_internal.h"
\r
7 /****************************************************************************/
\r
8 int lfds611_stack_push( struct lfds611_stack_state *ss, void *user_data )
\r
10 LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_stack_element
\r
11 *se[LFDS611_STACK_PAC_SIZE];
\r
13 assert( ss != NULL );
\r
14 // TRD : user_data can be NULL
\r
16 lfds611_stack_internal_new_element_from_freelist( ss, se, user_data );
\r
18 if( se[LFDS611_STACK_POINTER] == NULL )
\r
21 lfds611_stack_internal_push( ss, se );
\r
30 /****************************************************************************/
\r
31 int lfds611_stack_guaranteed_push( struct lfds611_stack_state *ss, void *user_data )
\r
33 LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_stack_element
\r
34 *se[LFDS611_STACK_PAC_SIZE];
\r
36 assert( ss != NULL );
\r
37 // TRD : user_data can be NULL
\r
39 /* TRD : this function allocated a new lfds611_freelist element and uses that
\r
40 to push onto the lfds611_stack, guaranteeing success (unless malloc()
\r
44 lfds611_stack_internal_new_element( ss, se, user_data );
\r
46 // TRD : malloc failed
\r
47 if( se[LFDS611_STACK_POINTER] == NULL )
\r
50 lfds611_stack_internal_push( ss, se );
\r
59 /****************************************************************************/
\r
60 void lfds611_stack_internal_push( struct lfds611_stack_state *ss, struct lfds611_stack_element *se[LFDS611_STACK_PAC_SIZE] )
\r
62 LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_stack_element
\r
63 *original_se_next[LFDS611_STACK_PAC_SIZE];
\r
65 assert( ss != NULL );
\r
66 assert( se != NULL );
\r
68 LFDS611_BARRIER_LOAD;
\r
70 original_se_next[LFDS611_STACK_POINTER] = ss->top[LFDS611_STACK_POINTER];
\r
71 original_se_next[LFDS611_STACK_COUNTER] = ss->top[LFDS611_STACK_COUNTER];
\r
75 se[LFDS611_STACK_POINTER]->next[LFDS611_STACK_POINTER] = original_se_next[LFDS611_STACK_POINTER];
\r
76 se[LFDS611_STACK_POINTER]->next[LFDS611_STACK_COUNTER] = original_se_next[LFDS611_STACK_COUNTER];
\r
78 while( 0 == lfds611_abstraction_dcas((volatile lfds611_atom_t *) ss->top, (lfds611_atom_t *) se, (lfds611_atom_t *) original_se_next) );
\r
87 /****************************************************************************/
\r
88 int lfds611_stack_pop( struct lfds611_stack_state *ss, void **user_data )
\r
90 LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_stack_element
\r
91 *se[LFDS611_STACK_PAC_SIZE];
\r
93 assert( ss != NULL );
\r
94 assert( user_data != NULL );
\r
96 LFDS611_BARRIER_LOAD;
\r
98 se[LFDS611_STACK_COUNTER] = ss->top[LFDS611_STACK_COUNTER];
\r
99 se[LFDS611_STACK_POINTER] = ss->top[LFDS611_STACK_POINTER];
\r
103 if( se[LFDS611_STACK_POINTER] == NULL )
\r
106 while( 0 == lfds611_abstraction_dcas((volatile lfds611_atom_t *) ss->top, (lfds611_atom_t *) se[LFDS611_STACK_POINTER]->next, (lfds611_atom_t *) se) );
\r
108 *user_data = se[LFDS611_STACK_POINTER]->user_data;
\r
110 lfds611_freelist_push( ss->fs, se[LFDS611_STACK_POINTER]->fe );
\r