Changeset c06551b
- Timestamp:
- Jun 9, 2022, 4:30:00 PM (2 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
- Children:
- 6d41f66
- Parents:
- aeb20a4
- Files:
-
- 2 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel/fwd.hfa
raeb20a4 rc06551b 200 200 struct thread$ * expected = this.ptr; 201 201 if(expected == 1p) return false; 202 /* paranoid */ verify( expected == 0p );203 202 if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 204 203 park(); … … 213 212 thread$ * post(oneshot & this, bool do_unpark = true) { 214 213 struct thread$ * got = __atomic_exchange_n( &this.ptr, 1p, __ATOMIC_SEQ_CST); 215 if( got == 0p ) return 0p;214 if( got == 0p || got == 1p ) return 0p; 216 215 if(do_unpark) unpark( got ); 217 216 return got; … … 263 262 264 263 // The future is not fulfilled, try to setup the wait context 265 /* paranoid */ verify( expected == 0p );266 264 if(__atomic_compare_exchange_n(&this.ptr, &expected, &wait_ctx, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 267 265 return true; … … 275 273 // should retract the wait ctx 276 274 // intented to be use by wait, wait_any, waitfor, etc. rather than used directly 277 voidretract( future_t & this, oneshot & wait_ctx ) {275 bool retract( future_t & this, oneshot & wait_ctx ) { 278 276 // Remove the wait context 279 277 struct oneshot * got = __atomic_exchange_n( &this.ptr, 0p, __ATOMIC_SEQ_CST); 280 278 281 279 // got == 0p: future was never actually setup, just return 282 if( got == 0p ) return ;280 if( got == 0p ) return false; 283 281 284 282 // got == wait_ctx: since fulfil does an atomic_swap, 285 283 // if we got back the original then no one else saw context 286 284 // It is safe to delete (which could happen after the return) 287 if( got == &wait_ctx ) return ;285 if( got == &wait_ctx ) return false; 288 286 289 287 // got == 1p: the future is ready and the context was fully consumed 290 288 // the server won't use the pointer again 291 289 // It is safe to delete (which could happen after the return) 292 if( got == 1p ) return ;290 if( got == 1p ) return true; 293 291 294 292 // got == 2p: the future is ready but the context hasn't fully been consumed … … 296 294 if( got == 2p ) { 297 295 while( this.ptr != 1p ) Pause(); 298 return ;296 return false; 299 297 } 300 298 … … 379 377 return ret; 380 378 } 379 380 // Wait for any future to be fulfilled 381 future_t & wait_any( future_t * futures, size_t num_futures ) { 382 oneshot temp; 383 384 // setup all futures 385 // if any are already satisfied return 386 for ( i; num_futures ) { 387 if( !setup(futures[i], temp) ) return futures[i]; 388 } 389 390 // Wait context is setup, just wait on it 391 wait( temp ); 392 393 size_t ret; 394 // attempt to retract all futures 395 for ( i; num_futures ) { 396 if ( retract( futures[i], temp ) ) ret = i; 397 } 398 399 return futures[ret]; 400 } 381 401 } 382 402
Note: See TracChangeset
for help on using the changeset viewer.