Changeset 1c56bf7 for libcfa/src/concurrency
- Timestamp:
- Jun 10, 2022, 2:59:21 PM (2 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
- Children:
- f3da205
- Parents:
- 6d41f66
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel/fwd.hfa
r6d41f66 r1c56bf7 274 274 // intented to be use by wait, wait_any, waitfor, etc. rather than used directly 275 275 bool retract( future_t & this, oneshot & wait_ctx ) { 276 // Remove the wait context 277 struct oneshot * got = __atomic_exchange_n( &this.ptr, 0p, __ATOMIC_SEQ_CST); 278 279 // got == 0p: future was never actually setup, just return 280 if( got == 0p ) return false; 281 282 // got == wait_ctx: since fulfil does an atomic_swap, 283 // if we got back the original then no one else saw context 284 // It is safe to delete (which could happen after the return) 285 if( got == &wait_ctx ) return false; 286 287 // got == 1p: the future is ready and the context was fully consumed 288 // the server won't use the pointer again 289 // It is safe to delete (which could happen after the return) 290 if( got == 1p ) return true; 291 292 // got == 2p: the future is ready but the context hasn't fully been consumed 293 // spin until it is safe to move on 294 if( got == 2p ) { 295 while( this.ptr != 1p ) Pause(); 296 return false; 297 } 298 299 // got == any thing else, something wen't wrong here, abort 300 abort("Future in unexpected state"); 276 for() { 277 struct oneshot * expected = this.ptr; 278 279 // expected == 0p: future was never actually setup, just return 280 if( expected == 0p ) return false; 281 282 // expected == 1p: the future is ready and the context was fully consumed 283 // the server won't use the pointer again 284 // It is safe to delete (which could happen after the return) 285 if( expected == 1p ) return true; 286 287 // expected == 2p: the future is ready but the context hasn't fully been consumed 288 // spin until it is safe to move on 289 if( expected == 2p ) { 290 while( this.ptr != 1p ) Pause(); 291 /* paranoid */ verify( this.ptr != 1p ); 292 return true; 293 } 294 295 // expected != wait_ctx: the future was setup with a different context ?!?! 296 // something went wrong here, abort 297 if( expected != &wait_ctx ) abort("Future in unexpected state"); 298 299 // we still have the original context, then no one else saw it 300 // attempt to remove the context so it doesn't get consumed. 301 if(__atomic_compare_exchange_n( &this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 302 return false; 303 } 304 } 301 305 } 302 306
Note: See TracChangeset
for help on using the changeset viewer.