Changeset 2a301ff for libcfa/src/concurrency/coroutine.cfa
- Timestamp:
- Aug 31, 2023, 11:31:15 PM (2 years ago)
- Branches:
- master
- Children:
- 950c58e
- Parents:
- 92355883 (diff), 686912c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - File:
-
- 1 edited
-
libcfa/src/concurrency/coroutine.cfa (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/coroutine.cfa
r92355883 r2a301ff 28 28 #include "kernel/private.hfa" 29 29 #include "exception.hfa" 30 #include "exception.h" 30 31 #include "math.hfa" 31 32 … … 77 78 free( desc->cancellation ); 78 79 desc->cancellation = 0p; 80 } 81 82 // helper for popping from coroutine's ehm buffer 83 inline nonlocal_exception * pop_ehm_head( coroutine$ * this ) { 84 lock( this->ehm_state.buffer_lock __cfaabi_dbg_ctx2 ); 85 nonlocal_exception * nl_ex = pop_head( this->ehm_state.ehm_buffer ); 86 unlock( this->ehm_state.buffer_lock ); 87 return nl_ex; 79 88 } 80 89 … … 121 130 last = 0p; 122 131 cancellation = 0p; 132 ehm_state.ehm_buffer{}; 133 ehm_state.buffer_lock{}; 134 ehm_state.ehm_enabled = false; 123 135 } 124 136 125 137 void ^?{}(coroutine$& this) libcfa_public { 138 // handle any leftover pending non-local exceptions 139 nonlocal_exception * nl_ex = pop_ehm_head( &this ); 140 unsigned unhandled_ex = 0; 141 142 // if any leftover exceptions handle 143 while ( nl_ex != 0p ){ 144 unhandled_ex++; 145 free( nl_ex->the_exception ); 146 free( nl_ex ); 147 nl_ex = pop_ehm_head( &this ); 148 } 149 150 #ifdef __CFA_DEBUG__ 151 if ( unhandled_ex > 0 ) 152 printf( "Warning: Coroutine %p exited with %u pending nonlocal exceptions.\n", &this, unhandled_ex ); 153 #endif 154 126 155 if(this.state != Halted && this.state != Start && this.state != Primed) { 127 156 coroutine$ * src = active_coroutine(); … … 283 312 } 284 313 314 315 //////////////////////////////////////////////////////////////////////////////////////////////////// 316 // non local ehm routines 317 318 void defaultResumeAtHandler( exception_t * except ) { 319 __cfaehm_allocate_exception( except ); 320 free( except ); 321 __cfaehm_begin_unwind( (void(*)(exception_t *))defaultTerminationHandler ); 322 } 323 324 bool poll( coroutine$ * cor ) libcfa_public { 325 nonlocal_exception * nl_ex = pop_ehm_head( cor ); 326 327 // if no exceptions return false 328 if ( nl_ex == 0p ) return false; 329 330 // otherwise loop and throwResume all pending exceptions 331 while ( nl_ex != 0p ){ 332 exception_t * ex = nl_ex->the_exception; 333 free( nl_ex ); 334 __cfaehm_throw_resume( ex, defaultResumeAtHandler ); 335 336 // only reached if resumption handled. other dealloc handled in defaultResumeAtHandler 337 free( ex ); 338 nl_ex = pop_ehm_head( cor ); 339 } 340 341 return true; 342 } 343 344 bool poll() libcfa_public { return poll( active_coroutine() ); } 345 coroutine$ * resumer() libcfa_public { return active_coroutine()->last; } 346 347 // user facing ehm operations 348 forall(T & | is_coroutine(T)) { 349 // enable/disable non-local exceptions 350 void enable_ehm( T & cor ) libcfa_public { get_coroutine( cor )->ehm_state.ehm_enabled = true; } 351 void disable_ehm( T & cor ) libcfa_public { get_coroutine( cor )->ehm_state.ehm_enabled = false; } 352 353 // poll for non-local exceptions 354 bool poll( T & cor ) libcfa_public { return poll( get_coroutine( cor ) ); } 355 356 // poll iff nonlocal ehm is enabled 357 bool checked_poll( T & cor ) libcfa_public { return get_coroutine( cor )->ehm_state.ehm_enabled ? poll( cor ) : false; } 358 359 coroutine$ * resumer( T & cor ) libcfa_public { return get_coroutine( cor )->last; } 360 } 361 362 // resume non local exception at receiver (i.e. enqueue in ehm buffer) 363 forall(exceptT *, T & | ehm_resume_at( exceptT, T )) 364 void resumeAt( T & receiver, exceptT & ex ) libcfa_public { 365 coroutine$ * cor = get_coroutine( receiver ); 366 nonlocal_exception * nl_ex = alloc(); 367 exceptT * ex_copy = alloc(); 368 memcpy( ex_copy, &ex, sizeof(exceptT) ); 369 (*nl_ex){ (exception_t *)ex_copy }; 370 lock( cor->ehm_state.buffer_lock __cfaabi_dbg_ctx2 ); 371 append( cor->ehm_state.ehm_buffer, nl_ex ); 372 unlock( cor->ehm_state.buffer_lock ); 373 } 374 375 forall(exceptT * | { void $throwResume(exceptT &); }) 376 void resumeAt( coroutine$ * receiver, exceptT & ex ) libcfa_public { 377 nonlocal_exception * nl_ex = alloc(); 378 exceptT * ex_copy = alloc(); 379 memcpy( ex_copy, &ex, sizeof(exceptT) ); 380 (*nl_ex){ (exception_t *)ex_copy }; 381 lock( receiver->ehm_state.buffer_lock __cfaabi_dbg_ctx2 ); 382 append( receiver->ehm_state.ehm_buffer, nl_ex ); 383 unlock( receiver->ehm_state.buffer_lock ); 384 } 385 285 386 // Local Variables: // 286 387 // mode: c //
Note:
See TracChangeset
for help on using the changeset viewer.