Ignore:
File:
1 edited

Legend:

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

    rb2f3880 r0658672  
    199199
    200200forall( T & )
     201struct LinkData {
     202        T * volatile top;                                                               // pointer to stack top
     203        uintptr_t count;                                                                // count each push
     204};
     205
     206forall( T & )
    201207union Link {
    202         struct {                                                                                        // 32/64-bit x 2
    203                 T * volatile top;                                                               // pointer to stack top
    204                 uintptr_t count;                                                                // count each push
    205         };
     208        LinkData(T) data;
    206209        #if __SIZEOF_INT128__ == 16
    207210        __int128                                                                                        // gcc, 128-bit integer
     
    220223                void ?{}( StackLF(T) & this ) with(this) { stack.atom = 0; }
    221224
    222                 T * top( StackLF(T) & this ) with(this) { return stack.top; }
     225                T * top( StackLF(T) & this ) with(this) { return stack.data.top; }
    223226
    224227                void push( StackLF(T) & this, T & n ) with(this) {
    225228                        *( &n )`next = stack;                                           // atomic assignment unnecessary, or use CAA
    226229                        for () {                                                                        // busy wait
    227                           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
     230                                if ( __atomic_compare_exchange_n( &stack.atom, &( &n )`next->atom, (Link(T))@{ (LinkData(T))@{ &n, ( &n )`next->data.count + 1} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) break; // attempt to update top node
    228231                        } // for
    229232                } // push
     
    232235                        Link(T) t @= stack;                                                     // atomic assignment unnecessary, or use CAA
    233236                        for () {                                                                        // busy wait
    234                           if ( t.top == 0p ) return 0p;                         // empty stack ?
    235                           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
     237                                if ( t.data.top == 0p ) return 0p;                              // empty stack ?
     238                                Link(T) * next = ( t.data.top )`next;
     239                                if ( __atomic_compare_exchange_n( &stack.atom, &t.atom, (Link(T))@{ (LinkData(T))@{ next->data.top, t.data.count } }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) return t.data.top; // attempt to update top node
    236240                        } // for
    237241                } // pop
     
    239243                bool unsafe_remove( StackLF(T) & this, T * node ) with(this) {
    240244                        Link(T) * link = &stack;
    241                         for() {
    242                                 T * next = link->top;
    243                                 if( next == node ) {
    244                                         link->top = ( node )`next->top;
     245                        for () {
     246                                // TODO: Avoiding some problems with double fields access.
     247                                LinkData(T) * data = &link->data;
     248                                T * next = (T *)&(*data).top;
     249                                if ( next == node ) {
     250                                        data->top = ( node )`next->data.top;
    245251                                        return true;
    246252                                }
    247                                 if( next == 0p ) return false;
     253                                if ( next == 0p ) return false;
    248254                                link = ( next )`next;
    249255                        }
Note: See TracChangeset for help on using the changeset viewer.