2 #include "lfds710_list_addonly_singlylinked_unordered_internal.h"
8 /****************************************************************************/
9 void lfds710_list_asu_insert_at_position( struct lfds710_list_asu_state *lasus,
10 struct lfds710_list_asu_element *lasue,
11 struct lfds710_list_asu_element *lasue_predecessor,
12 enum lfds710_list_asu_position position )
14 LFDS710_PAL_ASSERT( lasus != NULL );
15 LFDS710_PAL_ASSERT( lasue != NULL );
16 LFDS710_PAL_ASSERT( (lfds710_pal_uint_t) &lasue->next % LFDS710_PAL_ALIGN_SINGLE_POINTER == 0 );
17 LFDS710_PAL_ASSERT( (lfds710_pal_uint_t) &lasue->value % LFDS710_PAL_ALIGN_SINGLE_POINTER == 0 );
18 // TRD : lasue_predecessor asserted in the switch
19 // TRD : position can be any value in its range
23 case LFDS710_LIST_ASU_POSITION_START:
24 lfds710_list_asu_insert_at_start( lasus, lasue );
27 case LFDS710_LIST_ASU_POSITION_END:
28 lfds710_list_asu_insert_at_end( lasus, lasue );
31 case LFDS710_LIST_ASU_POSITION_AFTER:
32 lfds710_list_asu_insert_after_element( lasus, lasue, lasue_predecessor );
43 /****************************************************************************/
44 void lfds710_list_asu_insert_at_start( struct lfds710_list_asu_state *lasus,
45 struct lfds710_list_asu_element *lasue )
51 backoff_iteration = LFDS710_BACKOFF_INITIAL_VALUE;
53 LFDS710_PAL_ASSERT( lasus != NULL );
54 LFDS710_PAL_ASSERT( lasue != NULL );
55 LFDS710_PAL_ASSERT( (lfds710_pal_uint_t) &lasue->next % LFDS710_PAL_ALIGN_SINGLE_POINTER == 0 );
56 LFDS710_PAL_ASSERT( (lfds710_pal_uint_t) &lasue->value % LFDS710_PAL_ALIGN_SINGLE_POINTER == 0 );
58 LFDS710_MISC_BARRIER_LOAD;
60 lasue->next = lasus->start->next;
64 LFDS710_MISC_BARRIER_STORE;
65 LFDS710_PAL_ATOMIC_CAS( &lasus->start->next, (struct lfds710_list_asu_element **) &lasue->next, lasue, LFDS710_MISC_CAS_STRENGTH_WEAK, result );
67 LFDS710_BACKOFF_EXPONENTIAL_BACKOFF( lasus->start_backoff, backoff_iteration );
71 LFDS710_BACKOFF_AUTOTUNE( lasus->start_backoff, backoff_iteration );
80 /****************************************************************************/
81 void lfds710_list_asu_insert_at_end( struct lfds710_list_asu_state *lasus,
82 struct lfds710_list_asu_element *lasue )
87 enum lfds710_misc_flag
88 finished_flag = LFDS710_MISC_FLAG_LOWERED;
91 backoff_iteration = LFDS710_BACKOFF_INITIAL_VALUE;
93 struct lfds710_list_asu_element LFDS710_PAL_ALIGN(LFDS710_PAL_ALIGN_SINGLE_POINTER)
96 struct lfds710_list_asu_element
100 LFDS710_PAL_ASSERT( lasus != NULL );
101 LFDS710_PAL_ASSERT( lasue != NULL );
102 LFDS710_PAL_ASSERT( (lfds710_pal_uint_t) &lasue->next % LFDS710_PAL_ALIGN_SINGLE_POINTER == 0 );
103 LFDS710_PAL_ASSERT( (lfds710_pal_uint_t) &lasue->value % LFDS710_PAL_ALIGN_SINGLE_POINTER == 0 );
105 /* TRD : begin by assuming end is correctly pointing to the final element
106 try to link (comparing for next being NULL)
107 if we fail, move down list till we find last element
109 when successful, update end to ourselves
111 note there's a leading dummy element
112 so lasus->end always points to an element
115 LFDS710_MISC_BARRIER_LOAD;
118 lasue_end = lasus->end;
120 while( finished_flag == LFDS710_MISC_FLAG_LOWERED )
124 LFDS710_MISC_BARRIER_STORE;
125 LFDS710_PAL_ATOMIC_CAS( &lasue_end->next, &compare, lasue, LFDS710_MISC_CAS_STRENGTH_STRONG, result );
128 finished_flag = LFDS710_MISC_FLAG_RAISED;
131 LFDS710_BACKOFF_EXPONENTIAL_BACKOFF( lasus->end_backoff, backoff_iteration );
134 lasue_next = LFDS710_LIST_ASU_GET_NEXT( *lasue_end );
136 while( lasue_next != NULL )
138 lasue_end = lasue_next;
139 lasue_next = LFDS710_LIST_ASU_GET_NEXT( *lasue_end );
146 LFDS710_BACKOFF_AUTOTUNE( lasus->end_backoff, backoff_iteration );
155 /****************************************************************************/
156 #pragma warning( disable : 4100 )
158 void lfds710_list_asu_insert_after_element( struct lfds710_list_asu_state *lasus,
159 struct lfds710_list_asu_element *lasue,
160 struct lfds710_list_asu_element *lasue_predecessor )
166 backoff_iteration = LFDS710_BACKOFF_INITIAL_VALUE;
168 LFDS710_PAL_ASSERT( lasus != NULL );
169 LFDS710_PAL_ASSERT( lasue != NULL );
170 LFDS710_PAL_ASSERT( (lfds710_pal_uint_t) &lasue->next % LFDS710_PAL_ALIGN_SINGLE_POINTER == 0 );
171 LFDS710_PAL_ASSERT( (lfds710_pal_uint_t) &lasue->value % LFDS710_PAL_ALIGN_SINGLE_POINTER == 0 );
172 LFDS710_PAL_ASSERT( lasue_predecessor != NULL );
174 LFDS710_MISC_BARRIER_LOAD;
176 lasue->next = lasue_predecessor->next;
180 LFDS710_MISC_BARRIER_STORE;
181 LFDS710_PAL_ATOMIC_CAS( &lasue_predecessor->next, (struct lfds710_list_asu_element **) &lasue->next, lasue, LFDS710_MISC_CAS_STRENGTH_WEAK, result );
183 LFDS710_BACKOFF_EXPONENTIAL_BACKOFF( lasus->after_backoff, backoff_iteration );
185 while( result == 0 );
187 LFDS710_BACKOFF_AUTOTUNE( lasus->after_backoff, backoff_iteration );
192 #pragma warning( default : 4100 )