]> pd.if.org Git - liblfds/blob - liblfds/liblfds6.0.0/liblfds600/src/lfds600_slist/lfds600_slist_get_and_set.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds6.0.0 / liblfds600 / src / lfds600_slist / lfds600_slist_get_and_set.c
1 #include "lfds600_slist_internal.h"
2
3
4
5
6
7 /****************************************************************************/
8 int lfds600_slist_get_user_data_from_element( struct lfds600_slist_element *se, void **user_data )
9 {
10   int
11     rv = 1;
12
13   assert( se != NULL );
14   assert( user_data != NULL );
15
16   *user_data = (void *) se->user_data_and_flags[LFDS600_SLIST_USER_DATA];
17
18   if( (lfds600_atom_t) se->user_data_and_flags[LFDS600_SLIST_FLAGS] & LFDS600_SLIST_FLAG_DELETED )
19     rv = 0;
20
21   return( rv );
22 }
23
24
25
26
27
28 /****************************************************************************/
29 int lfds600_slist_set_user_data_in_element( struct lfds600_slist_element *se, void *user_data )
30 {
31   LFDS600_ALIGN(LFDS600_ALIGN_DOUBLE_POINTER) volatile void
32     *user_data_and_flags[2],
33     *new_user_data_and_flags[2];
34
35   int
36     rv = 1;
37
38   assert( se != NULL );
39   // TRD : user_data can be NULL
40
41   user_data_and_flags[LFDS600_SLIST_USER_DATA] = se->user_data_and_flags[LFDS600_SLIST_USER_DATA];
42   user_data_and_flags[LFDS600_SLIST_FLAGS] = se->user_data_and_flags[LFDS600_SLIST_FLAGS];
43
44   new_user_data_and_flags[LFDS600_SLIST_USER_DATA] = user_data;
45
46   do
47   {
48     new_user_data_and_flags[LFDS600_SLIST_FLAGS] = user_data_and_flags[LFDS600_SLIST_FLAGS];
49   }
50   while( !((lfds600_atom_t) user_data_and_flags[LFDS600_SLIST_FLAGS] & LFDS600_SLIST_FLAG_DELETED) and 0 == lfds600_abstraction_dcas((volatile lfds600_atom_t *) se->user_data_and_flags, (lfds600_atom_t *) new_user_data_and_flags, (lfds600_atom_t *) user_data_and_flags) );
51
52   if( (lfds600_atom_t) user_data_and_flags[LFDS600_SLIST_FLAGS] & LFDS600_SLIST_FLAG_DELETED )
53     rv = 0;
54
55   return( rv );
56 }
57
58
59
60
61
62 /****************************************************************************/
63 struct lfds600_slist_element *lfds600_slist_get_head( struct lfds600_slist_state *ss, struct lfds600_slist_element **se )
64 {
65   assert( ss != NULL );
66   assert( se != NULL );
67
68   *se = (struct lfds600_slist_element *) ss->head;
69
70   lfds600_slist_internal_move_to_first_undeleted_element( se );
71
72   return( *se );
73 }
74
75
76
77
78
79 /****************************************************************************/
80 struct lfds600_slist_element *lfds600_slist_get_next( struct lfds600_slist_element *se, struct lfds600_slist_element **next_se )
81 {
82   assert( se != NULL );
83   assert( next_se != NULL );
84
85   *next_se = (struct lfds600_slist_element *) se->next;
86
87   lfds600_slist_internal_move_to_first_undeleted_element( next_se );
88
89   return( *next_se );
90 }
91
92
93
94
95
96 /****************************************************************************/
97 struct lfds600_slist_element *lfds600_slist_get_head_and_then_next( struct lfds600_slist_state *ss, struct lfds600_slist_element **se )
98 {
99   assert( ss != NULL );
100   assert( se != NULL );
101
102   if( *se == NULL )
103     lfds600_slist_get_head( ss, se );
104   else
105     lfds600_slist_get_next( *se, se );
106
107   return( *se );
108 }
109
110
111
112
113
114 /****************************************************************************/
115 void lfds600_slist_internal_move_to_first_undeleted_element( struct lfds600_slist_element **se )
116 {
117   assert( se != NULL );
118
119   while( *se != NULL and (lfds600_atom_t) (*se)->user_data_and_flags[LFDS600_SLIST_FLAGS] & LFDS600_SLIST_FLAG_DELETED )
120     (*se) = (struct lfds600_slist_element *) (*se)->next;
121
122   return;
123 }
124