source: libcfa/src/containers/stackLockFree.hfa @ 9dc0836

ADTast-experimentalenumforall-pointer-decaypthread-emulationqualifiedEnum
Last change on this file since 9dc0836 was c08c3cf, checked in by Peter A. Buhr <pabuhr@…>, 4 years ago

fix conflict

  • Property mode set to 100644
File size: 2.2 KB
RevLine 
[04b5cef]1//
[9c438546]2// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
3// The contents of this file are covered under the licence agreement in the
4// file "LICENCE" distributed with Cforall.
5//
[04b5cef]6// stackLockFree.hfa --
7//
[9c438546]8// Author           : Peter A. Buhr
9// Created On       : Wed May 13 20:58:58 2020
10// Last Modified By : Peter A. Buhr
[6f36dde]11// Last Modified On : Wed Jan 20 20:40:03 2021
12// Update Count     : 67
[04b5cef]13//
[9c438546]14
15#pragma once
16
17#include <stdint.h>
18
[fd54fef]19forall( T & )
[9c438546]20union Link {
[280ec46]21        struct {                                                                                        // 32/64-bit x 2
[04b5cef]22                T * volatile top;                                                               // pointer to stack top
[280ec46]23                uintptr_t count;                                                                // count each push
[9c438546]24        };
[314dab6]25        #if __SIZEOF_INT128__ == 16
[280ec46]26        __int128                                                                                        // gcc, 128-bit integer
[9c438546]27        #else
[280ec46]28        uint64_t                                                                                        // 64-bit integer
[314dab6]29        #endif // __SIZEOF_INT128__ == 16
[9c438546]30        atom;
31}; // Link
32
[fd54fef]33forall( T | sized(T) | { Link(T) * ?`next( T * ); } ) {
[64a7146]34        struct StackLF {
[9c438546]35                Link(T) stack;
36        }; // StackLF
37
38        static inline {
39                void ?{}( StackLF(T) & this ) with(this) { stack.atom = 0; }
40
41                T * top( StackLF(T) & this ) with(this) { return stack.top; }
42
43                void push( StackLF(T) & this, T & n ) with(this) {
[6f36dde]44                        *( &n )`next = stack;                                           // atomic assignment unnecessary, or use CAA
[9c438546]45                        for () {                                                                        // busy wait
[0f89d4f]46                          if ( __atomic_compare_exchange_n( &stack.atom, &( &n )`next->atom, (Link(T))@{ {&n, ( &n )`next->count + 1} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) break; // attempt to update top node
[9c438546]47                        } // for
48                } // push
49
50                T * pop( StackLF(T) & this ) with(this) {
[9019b14]51                        Link(T) t @= stack;                                                     // atomic assignment unnecessary, or use CAA
[9c438546]52                        for () {                                                                        // busy wait
53                          if ( t.top == 0p ) return 0p;                         // empty stack ?
[0f89d4f]54                          if ( __atomic_compare_exchange_n( &stack.atom, &t.atom, (Link(T))@{ {( t.top )`next->top, t.count} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) return t.top; // attempt to update top node
[9c438546]55                        } // for
56                } // pop
[64a7146]57
58                bool unsafe_remove( StackLF(T) & this, T * node ) with(this) {
59                        Link(T) * link = &stack;
60                        for() {
61                                T * next = link->top;
62                                if( next == node ) {
[0f89d4f]63                                        link->top = ( node )`next->top;
[64a7146]64                                        return true;
65                                }
66                                if( next == 0p ) return false;
[6f36dde]67                                link = ( next )`next;
[64a7146]68                        }
69                }
[9c438546]70        } // distribution
71} // distribution
72
73
74// Local Variables: //
75// tab-width: 4 //
76// End: //
Note: See TracBrowser for help on using the repository browser.