Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/containers/stackLockFree.hfa

    r0f89d4f r9019b14  
    1 //
     1// 
    22// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
    33// The contents of this file are covered under the licence agreement in the
    44// file "LICENCE" distributed with Cforall.
    55//
    6 // stackLockFree.hfa --
    7 //
     6// stackLockFree.hfa -- 
     7// 
    88// Author           : Peter A. Buhr
    99// Created On       : Wed May 13 20:58:58 2020
    1010// Last Modified By : Peter A. Buhr
    11 // Last Modified On : Mon May 18 13:30:08 2020
    12 // Update Count     : 55
    13 //
     11// Last Modified On : Sun Jun 14 13:25:09 2020
     12// Update Count     : 64
     13// 
    1414
    1515#pragma once
     
    1919forall( dtype T )
    2020union Link {
    21         struct {                                                                        // 32/64-bit x 2
     21        struct {                                                                                        // 32/64-bit x 2
    2222                T * volatile top;                                                               // pointer to stack top
    23                 uintptr_t count;                                                // count each push
     23                uintptr_t count;                                                                // count each push
    2424        };
    2525        #if __SIZEOF_INT128__ == 16
    26         __int128                                                                        // gcc, 128-bit integer
     26        __int128                                                                                        // gcc, 128-bit integer
    2727        #else
    28         uint64_t                                                                        // 64-bit integer
     28        uint64_t                                                                                        // 64-bit integer
    2929        #endif // __SIZEOF_INT128__ == 16
    3030        atom;
    3131}; // Link
    3232
    33 forall( otype T | { Link(T) * ?`next( T * ); } ) {
    34         struct StackLF {
     33forall( dtype T | sized(T) | { Link(T) * getNext( T * ); } ) {
     34    struct StackLF {
    3535                Link(T) stack;
    3636        }; // StackLF
     
    4242
    4343                void push( StackLF(T) & this, T & n ) with(this) {
     44                        *getNext( &n ) = stack;                                         // atomic assignment unnecessary, or use CAA
    4445                        for () {                                                                        // busy wait
    45                                 *( &n )`next = stack;                                   // atomic assignment unnecessary, or use CAA
    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
     46                          if ( __atomic_compare_exchange_n( &stack.atom, &getNext( &n )->atom, (Link(T))@{ {&n, getNext( &n )->count + 1} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) break; // attempt to update top node
    4747                        } // for
    4848                } // push
    4949
    5050                T * pop( StackLF(T) & this ) with(this) {
    51                         Link(T) t @= {};
     51                        Link(T) t @= stack;                                                     // atomic assignment unnecessary, or use CAA
    5252                        for () {                                                                        // busy wait
    53                                 t = stack;                                                              // atomic assignment unnecessary, or use CAA
    5453                          if ( t.top == 0p ) return 0p;                         // empty stack ?
    55                           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
     54                          if ( __atomic_compare_exchange_n( &stack.atom, &t.atom, (Link(T))@{ {getNext( t.top )->top, t.count} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) return t.top; // attempt to update top node
    5655                        } // for
    5756                } // pop
    58 
    59                 bool unsafe_remove( StackLF(T) & this, T * node ) with(this) {
    60                         Link(T) * link = &stack;
    61                         for() {
    62                                 T * next = link->top;
    63                                 if( next == node ) {
    64                                         link->top = ( node )`next->top;
    65                                         return true;
    66                                 }
    67                                 if( next == 0p ) return false;
    68                                 link = (next)`next;
    69                         }
    70                 }
    7157        } // distribution
    7258} // distribution
Note: See TracChangeset for help on using the changeset viewer.