]> pd.if.org Git - liblfds/blob - liblfds/liblfds6.0.0/liblfds600/src/lfds600_stack/lfds600_stack_push_pop.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds6.0.0 / liblfds600 / src / lfds600_stack / lfds600_stack_push_pop.c
1 #include "lfds600_stack_internal.h"
2
3
4
5
6
7 /****************************************************************************/
8 int lfds600_stack_push( struct lfds600_stack_state *ss, void *user_data )
9 {
10   LFDS600_ALIGN(LFDS600_ALIGN_DOUBLE_POINTER) struct lfds600_stack_element
11     *se[LFDS600_STACK_PAC_SIZE];
12
13   assert( ss != NULL );
14   // TRD : user_data can be NULL
15
16   lfds600_stack_internal_new_element_from_freelist( ss, se, user_data );
17
18   if( se[LFDS600_STACK_POINTER] == NULL )
19     return( 0 );
20
21   lfds600_stack_internal_push( ss, se );
22
23   return( 1 );
24 }
25
26
27
28
29
30 /****************************************************************************/
31 int lfds600_stack_guaranteed_push( struct lfds600_stack_state *ss, void *user_data )
32 {
33   LFDS600_ALIGN(LFDS600_ALIGN_DOUBLE_POINTER) struct lfds600_stack_element
34     *se[LFDS600_STACK_PAC_SIZE];
35
36   assert( ss != NULL );
37   // TRD : user_data can be NULL
38
39   /* TRD : this function allocated a new lfds600_freelist element and uses that
40            to push onto the lfds600_stack, guaranteeing success (unless malloc()
41            fails of course)
42   */
43
44   lfds600_stack_internal_new_element( ss, se, user_data );
45
46   // TRD : malloc failed
47   if( se[LFDS600_STACK_POINTER] == NULL )
48     return( 0 );
49
50   lfds600_stack_internal_push( ss, se );
51
52   return( 1 );
53 }
54
55
56
57
58
59 /****************************************************************************/
60 void lfds600_stack_internal_push( struct lfds600_stack_state *ss, struct lfds600_stack_element *se[LFDS600_STACK_PAC_SIZE] )
61 {
62   LFDS600_ALIGN(LFDS600_ALIGN_DOUBLE_POINTER) struct lfds600_stack_element
63     *original_se_next[LFDS600_STACK_PAC_SIZE];
64
65   assert( ss != NULL );
66   assert( se != NULL );
67
68   original_se_next[LFDS600_STACK_POINTER] = ss->top[LFDS600_STACK_POINTER];
69   original_se_next[LFDS600_STACK_COUNTER] = ss->top[LFDS600_STACK_COUNTER];
70
71   do
72   {
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];
75   }
76   while( 0 == lfds600_abstraction_dcas((volatile lfds600_atom_t *) ss->top, (lfds600_atom_t *) se, (lfds600_atom_t *) original_se_next) );
77
78   return;
79 }
80
81
82
83
84
85 /****************************************************************************/
86 int lfds600_stack_pop( struct lfds600_stack_state *ss, void **user_data )
87 {
88   LFDS600_ALIGN(LFDS600_ALIGN_DOUBLE_POINTER) struct lfds600_stack_element
89     *se[LFDS600_STACK_PAC_SIZE];
90
91   assert( ss != NULL );
92   assert( user_data != NULL );
93
94   se[LFDS600_STACK_COUNTER] = ss->top[LFDS600_STACK_COUNTER];
95   se[LFDS600_STACK_POINTER] = ss->top[LFDS600_STACK_POINTER];
96
97   do
98   {
99     if( se[LFDS600_STACK_POINTER] == NULL )
100       return( 0 );
101   }
102   while( 0 == lfds600_abstraction_dcas((volatile lfds600_atom_t *) ss->top, (lfds600_atom_t *) se[LFDS600_STACK_POINTER]->next, (lfds600_atom_t *) se) );
103
104   *user_data = se[LFDS600_STACK_POINTER]->user_data;
105
106   lfds600_freelist_push( ss->fs, se[LFDS600_STACK_POINTER]->fe );
107
108   return( 1 );
109 }
110