]> pd.if.org Git - liblfds/blob - liblfds/liblfds6.1.1/liblfds611/src/lfds611_slist/lfds611_slist_get_and_set.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds6.1.1 / liblfds611 / src / lfds611_slist / lfds611_slist_get_and_set.c
1 #include "lfds611_slist_internal.h"\r
2 \r
3 \r
4 \r
5 \r
6 \r
7 /****************************************************************************/\r
8 int lfds611_slist_get_user_data_from_element( struct lfds611_slist_element *se, void **user_data )\r
9 {\r
10   int\r
11     rv = 1;\r
12 \r
13   assert( se != NULL );\r
14   assert( user_data != NULL );\r
15 \r
16   LFDS611_BARRIER_LOAD;\r
17 \r
18   *user_data = (void *) se->user_data_and_flags[LFDS611_SLIST_USER_DATA];\r
19 \r
20   if( (lfds611_atom_t) se->user_data_and_flags[LFDS611_SLIST_FLAGS] & LFDS611_SLIST_FLAG_DELETED )\r
21     rv = 0;\r
22 \r
23   return( rv );\r
24 }\r
25 \r
26 \r
27 \r
28 \r
29 \r
30 /****************************************************************************/\r
31 int lfds611_slist_set_user_data_in_element( struct lfds611_slist_element *se, void *user_data )\r
32 {\r
33   LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) void\r
34     *user_data_and_flags[2],\r
35     *new_user_data_and_flags[2];\r
36 \r
37   int\r
38     rv = 1;\r
39 \r
40   assert( se != NULL );\r
41   // TRD : user_data can be NULL\r
42 \r
43   LFDS611_BARRIER_LOAD;\r
44 \r
45   user_data_and_flags[LFDS611_SLIST_USER_DATA] = se->user_data_and_flags[LFDS611_SLIST_USER_DATA];\r
46   user_data_and_flags[LFDS611_SLIST_FLAGS] = se->user_data_and_flags[LFDS611_SLIST_FLAGS];\r
47 \r
48   new_user_data_and_flags[LFDS611_SLIST_USER_DATA] = user_data;\r
49 \r
50   do\r
51   {\r
52     new_user_data_and_flags[LFDS611_SLIST_FLAGS] = user_data_and_flags[LFDS611_SLIST_FLAGS];\r
53   }\r
54   while( !((lfds611_atom_t) user_data_and_flags[LFDS611_SLIST_FLAGS] & LFDS611_SLIST_FLAG_DELETED) and\r
55          0 == lfds611_abstraction_dcas((volatile lfds611_atom_t *) se->user_data_and_flags, (lfds611_atom_t *) new_user_data_and_flags, (lfds611_atom_t *) user_data_and_flags) );\r
56 \r
57   if( (lfds611_atom_t) user_data_and_flags[LFDS611_SLIST_FLAGS] & LFDS611_SLIST_FLAG_DELETED )\r
58     rv = 0;\r
59 \r
60   LFDS611_BARRIER_STORE;\r
61 \r
62   return( rv );\r
63 }\r
64 \r
65 \r
66 \r
67 \r
68 \r
69 /****************************************************************************/\r
70 struct lfds611_slist_element *lfds611_slist_get_head( struct lfds611_slist_state *ss, struct lfds611_slist_element **se )\r
71 {\r
72   assert( ss != NULL );\r
73   assert( se != NULL );\r
74 \r
75   LFDS611_BARRIER_LOAD;\r
76 \r
77   *se = (struct lfds611_slist_element *) ss->head;\r
78 \r
79   lfds611_slist_internal_move_to_first_undeleted_element( se );\r
80 \r
81   return( *se );\r
82 }\r
83 \r
84 \r
85 \r
86 \r
87 \r
88 /****************************************************************************/\r
89 struct lfds611_slist_element *lfds611_slist_get_next( struct lfds611_slist_element *se, struct lfds611_slist_element **next_se )\r
90 {\r
91   assert( se != NULL );\r
92   assert( next_se != NULL );\r
93 \r
94   LFDS611_BARRIER_LOAD;\r
95 \r
96   *next_se = (struct lfds611_slist_element *) se->next;\r
97 \r
98   lfds611_slist_internal_move_to_first_undeleted_element( next_se );\r
99 \r
100   return( *next_se );\r
101 }\r
102 \r
103 \r
104 \r
105 \r
106 \r
107 /****************************************************************************/\r
108 struct lfds611_slist_element *lfds611_slist_get_head_and_then_next( struct lfds611_slist_state *ss, struct lfds611_slist_element **se )\r
109 {\r
110   assert( ss != NULL );\r
111   assert( se != NULL );\r
112 \r
113   if( *se == NULL )\r
114     lfds611_slist_get_head( ss, se );\r
115   else\r
116     lfds611_slist_get_next( *se, se );\r
117 \r
118   return( *se );\r
119 }\r
120 \r
121 \r
122 \r
123 \r
124 \r
125 /****************************************************************************/\r
126 void lfds611_slist_internal_move_to_first_undeleted_element( struct lfds611_slist_element **se )\r
127 {\r
128   assert( se != NULL );\r
129 \r
130   while( *se != NULL and (lfds611_atom_t) (*se)->user_data_and_flags[LFDS611_SLIST_FLAGS] & LFDS611_SLIST_FLAG_DELETED )\r
131     (*se) = (struct lfds611_slist_element *) (*se)->next;\r
132 \r
133   return;\r
134 }\r
135 \r