]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.1.0/liblfds710/src/lfds710_stack/lfds710_stack_pop.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds7.1.0 / liblfds710 / src / lfds710_stack / lfds710_stack_pop.c
1 /***** includes *****/
2 #include "lfds710_stack_internal.h"
3
4
5
6
7
8 /****************************************************************************/
9 int lfds710_stack_pop( struct lfds710_stack_state *ss,
10                        struct lfds710_stack_element **se )
11 {
12   char unsigned
13     result;
14
15   lfds710_pal_uint_t
16     backoff_iteration = LFDS710_BACKOFF_INITIAL_VALUE;
17
18   struct lfds710_stack_element LFDS710_PAL_ALIGN(LFDS710_PAL_ALIGN_DOUBLE_POINTER)
19     *new_top[PAC_SIZE],
20     *volatile original_top[PAC_SIZE];
21
22   LFDS710_PAL_ASSERT( ss != NULL );
23   LFDS710_PAL_ASSERT( se != NULL );
24
25   LFDS710_MISC_BARRIER_LOAD;
26
27   original_top[COUNTER] = ss->top[COUNTER];
28   original_top[POINTER] = ss->top[POINTER];
29
30   do
31   {
32     if( original_top[POINTER] == NULL )
33     {
34       *se = NULL;
35       return 0;
36     }
37
38     new_top[COUNTER] = original_top[COUNTER] + 1;
39     new_top[POINTER] = original_top[POINTER]->next;
40
41     LFDS710_PAL_ATOMIC_DWCAS( ss->top, original_top, new_top, LFDS710_MISC_CAS_STRENGTH_WEAK, result );
42
43     if( result == 0 )
44     {
45       LFDS710_BACKOFF_EXPONENTIAL_BACKOFF( ss->pop_backoff, backoff_iteration );
46       LFDS710_MISC_BARRIER_LOAD;
47     }
48   }
49   while( result == 0 );
50
51   *se = original_top[POINTER];
52
53   LFDS710_BACKOFF_AUTOTUNE( ss->pop_backoff, backoff_iteration );
54
55   return 1;
56 }
57