]> pd.if.org Git - liblfds/blob - liblfds/liblfds6.0.1/liblfds601/src/lfds601_stack/lfds601_stack_push_pop.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds6.0.1 / liblfds601 / src / lfds601_stack / lfds601_stack_push_pop.c
1 #include "lfds601_stack_internal.h"\r
2 \r
3 \r
4 \r
5 \r
6 \r
7 /****************************************************************************/\r
8 int lfds601_stack_push( struct lfds601_stack_state *ss, void *user_data )\r
9 {\r
10   LFDS601_ALIGN(LFDS601_ALIGN_DOUBLE_POINTER) struct lfds601_stack_element\r
11     *se[LFDS601_STACK_PAC_SIZE];\r
12 \r
13   assert( ss != NULL );\r
14   // TRD : user_data can be NULL\r
15 \r
16   lfds601_stack_internal_new_element_from_freelist( ss, se, user_data );\r
17 \r
18   if( se[LFDS601_STACK_POINTER] == NULL )\r
19     return( 0 );\r
20 \r
21   lfds601_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 lfds601_stack_guaranteed_push( struct lfds601_stack_state *ss, void *user_data )\r
32 {\r
33   LFDS601_ALIGN(LFDS601_ALIGN_DOUBLE_POINTER) struct lfds601_stack_element\r
34     *se[LFDS601_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 lfds601_freelist element and uses that\r
40            to push onto the lfds601_stack, guaranteeing success (unless malloc()\r
41            fails of course)\r
42   */\r
43 \r
44   lfds601_stack_internal_new_element( ss, se, user_data );\r
45 \r
46   // TRD : malloc failed\r
47   if( se[LFDS601_STACK_POINTER] == NULL )\r
48     return( 0 );\r
49 \r
50   lfds601_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 lfds601_stack_internal_push( struct lfds601_stack_state *ss, struct lfds601_stack_element *se[LFDS601_STACK_PAC_SIZE] )\r
61 {\r
62   LFDS601_ALIGN(LFDS601_ALIGN_DOUBLE_POINTER) struct lfds601_stack_element\r
63     *original_se_next[LFDS601_STACK_PAC_SIZE];\r
64 \r
65   assert( ss != NULL );\r
66   assert( se != NULL );\r
67 \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
70 \r
71   do\r
72   {\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
75   }\r
76   while( 0 == lfds601_abstraction_dcas((volatile lfds601_atom_t *) ss->top, (lfds601_atom_t *) se, (lfds601_atom_t *) original_se_next) );\r
77 \r
78   return;\r
79 }\r
80 \r
81 \r
82 \r
83 \r
84 \r
85 /****************************************************************************/\r
86 int lfds601_stack_pop( struct lfds601_stack_state *ss, void **user_data )\r
87 {\r
88   LFDS601_ALIGN(LFDS601_ALIGN_DOUBLE_POINTER) struct lfds601_stack_element\r
89     *se[LFDS601_STACK_PAC_SIZE];\r
90 \r
91   assert( ss != NULL );\r
92   assert( user_data != NULL );\r
93 \r
94   se[LFDS601_STACK_COUNTER] = ss->top[LFDS601_STACK_COUNTER];\r
95   se[LFDS601_STACK_POINTER] = ss->top[LFDS601_STACK_POINTER];\r
96 \r
97   do\r
98   {\r
99     if( se[LFDS601_STACK_POINTER] == NULL )\r
100       return( 0 );\r
101   }\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
103 \r
104   *user_data = se[LFDS601_STACK_POINTER]->user_data;\r
105 \r
106   lfds601_freelist_push( ss->fs, se[LFDS601_STACK_POINTER]->fe );\r
107 \r
108   return( 1 );\r
109 }\r
110 \r