Ignore:
File:
1 edited

Legend:

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

    r0658672 rb2f3880  
    199199
    200200forall( T & )
    201 struct LinkData {
    202         T * volatile top;                                                               // pointer to stack top
    203         uintptr_t count;                                                                // count each push
    204 };
    205 
    206 forall( T & )
    207201union Link {
    208         LinkData(T) data;
     202        struct {                                                                                        // 32/64-bit x 2
     203                T * volatile top;                                                               // pointer to stack top
     204                uintptr_t count;                                                                // count each push
     205        };
    209206        #if __SIZEOF_INT128__ == 16
    210207        __int128                                                                                        // gcc, 128-bit integer
     
    223220                void ?{}( StackLF(T) & this ) with(this) { stack.atom = 0; }
    224221
    225                 T * top( StackLF(T) & this ) with(this) { return stack.data.top; }
     222                T * top( StackLF(T) & this ) with(this) { return stack.top; }
    226223
    227224                void push( StackLF(T) & this, T & n ) with(this) {
    228225                        *( &n )`next = stack;                                           // atomic assignment unnecessary, or use CAA
    229226                        for () {                                                                        // busy wait
    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
     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
    231228                        } // for
    232229                } // push
     
    235232                        Link(T) t @= stack;                                                     // atomic assignment unnecessary, or use CAA
    236233                        for () {                                                                        // busy wait
    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
     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
    240236                        } // for
    241237                } // pop
     
    243239                bool unsafe_remove( StackLF(T) & this, T * node ) with(this) {
    244240                        Link(T) * link = &stack;
    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;
     241                        for() {
     242                                T * next = link->top;
     243                                if( next == node ) {
     244                                        link->top = ( node )`next->top;
    251245                                        return true;
    252246                                }
    253                                 if ( next == 0p ) return false;
     247                                if( next == 0p ) return false;
    254248                                link = ( next )`next;
    255249                        }
Note: See TracChangeset for help on using the changeset viewer.