- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/containers/lockfree.hfa
r0658672 rb2f3880 199 199 200 200 forall( T & ) 201 struct LinkData {202 T * volatile top; // pointer to stack top203 uintptr_t count; // count each push204 };205 206 forall( T & )207 201 union 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 }; 209 206 #if __SIZEOF_INT128__ == 16 210 207 __int128 // gcc, 128-bit integer … … 223 220 void ?{}( StackLF(T) & this ) with(this) { stack.atom = 0; } 224 221 225 T * top( StackLF(T) & this ) with(this) { return stack. data.top; }222 T * top( StackLF(T) & this ) with(this) { return stack.top; } 226 223 227 224 void push( StackLF(T) & this, T & n ) with(this) { 228 225 *( &n )`next = stack; // atomic assignment unnecessary, or use CAA 229 226 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 node227 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 231 228 } // for 232 229 } // push … … 235 232 Link(T) t @= stack; // atomic assignment unnecessary, or use CAA 236 233 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 240 236 } // for 241 237 } // pop … … 243 239 bool unsafe_remove( StackLF(T) & this, T * node ) with(this) { 244 240 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; 251 245 return true; 252 246 } 253 if 247 if( next == 0p ) return false; 254 248 link = ( next )`next; 255 249 }
Note: See TracChangeset
for help on using the changeset viewer.