]> pd.if.org Git - liblfds/blob - liblfds/liblfds6.1.1/liblfds611/src/lfds611_stack/lfds611_stack_push_pop.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds6.1.1 / liblfds611 / src / lfds611_stack / lfds611_stack_push_pop.c
1 #include "lfds611_stack_internal.h"\r
2 \r
3 \r
4 \r
5 \r
6 \r
7 /****************************************************************************/\r
8 int lfds611_stack_push( struct lfds611_stack_state *ss, void *user_data )\r
9 {\r
10   LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_stack_element\r
11     *se[LFDS611_STACK_PAC_SIZE];\r
12 \r
13   assert( ss != NULL );\r
14   // TRD : user_data can be NULL\r
15 \r
16   lfds611_stack_internal_new_element_from_freelist( ss, se, user_data );\r
17 \r
18   if( se[LFDS611_STACK_POINTER] == NULL )\r
19     return( 0 );\r
20 \r
21   lfds611_stack_internal_push( ss, se );\r
22 \r
23   return( 1 );\r
24 }\r
25 \r
26 \r
27 \r
28 \r
29 \r
30 /****************************************************************************/\r
31 int lfds611_stack_guaranteed_push( struct lfds611_stack_state *ss, void *user_data )\r
32 {\r
33   LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_stack_element\r
34     *se[LFDS611_STACK_PAC_SIZE];\r
35 \r
36   assert( ss != NULL );\r
37   // TRD : user_data can be NULL\r
38 \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
41            fails of course)\r
42   */\r
43 \r
44   lfds611_stack_internal_new_element( ss, se, user_data );\r
45 \r
46   // TRD : malloc failed\r
47   if( se[LFDS611_STACK_POINTER] == NULL )\r
48     return( 0 );\r
49 \r
50   lfds611_stack_internal_push( ss, se );\r
51 \r
52   return( 1 );\r
53 }\r
54 \r
55 \r
56 \r
57 \r
58 \r
59 /****************************************************************************/\r
60 void lfds611_stack_internal_push( struct lfds611_stack_state *ss, struct lfds611_stack_element *se[LFDS611_STACK_PAC_SIZE] )\r
61 {\r
62   LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_stack_element\r
63     *original_se_next[LFDS611_STACK_PAC_SIZE];\r
64 \r
65   assert( ss != NULL );\r
66   assert( se != NULL );\r
67 \r
68   LFDS611_BARRIER_LOAD;\r
69 \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
72 \r
73   do\r
74   {\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
77   }\r
78   while( 0 == lfds611_abstraction_dcas((volatile lfds611_atom_t *) ss->top, (lfds611_atom_t *) se, (lfds611_atom_t *) original_se_next) );\r
79 \r
80   return;\r
81 }\r
82 \r
83 \r
84 \r
85 \r
86 \r
87 /****************************************************************************/\r
88 int lfds611_stack_pop( struct lfds611_stack_state *ss, void **user_data )\r
89 {\r
90   LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_stack_element\r
91     *se[LFDS611_STACK_PAC_SIZE];\r
92 \r
93   assert( ss != NULL );\r
94   assert( user_data != NULL );\r
95 \r
96   LFDS611_BARRIER_LOAD;\r
97 \r
98   se[LFDS611_STACK_COUNTER] = ss->top[LFDS611_STACK_COUNTER];\r
99   se[LFDS611_STACK_POINTER] = ss->top[LFDS611_STACK_POINTER];\r
100 \r
101   do\r
102   {\r
103     if( se[LFDS611_STACK_POINTER] == NULL )\r
104       return( 0 );\r
105   }\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
107 \r
108   *user_data = se[LFDS611_STACK_POINTER]->user_data;\r
109 \r
110   lfds611_freelist_push( ss->fs, se[LFDS611_STACK_POINTER]->fe );\r
111 \r
112   return( 1 );\r
113 }\r
114 \r