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