Ignore:
Timestamp:
Aug 31, 2023, 11:31:15 PM (2 years ago)
Author:
JiadaL <j82liang@…>
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.
Message:

Resolve conflict

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/coroutine.cfa

    r92355883 r2a301ff  
    2828#include "kernel/private.hfa"
    2929#include "exception.hfa"
     30#include "exception.h"
    3031#include "math.hfa"
    3132
     
    7778        free( desc->cancellation );
    7879        desc->cancellation = 0p;
     80}
     81
     82// helper for popping from coroutine's ehm buffer
     83inline 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;
    7988}
    8089
     
    121130        last = 0p;
    122131        cancellation = 0p;
     132    ehm_state.ehm_buffer{};
     133    ehm_state.buffer_lock{};
     134    ehm_state.ehm_enabled = false;
    123135}
    124136
    125137void ^?{}(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
    126155        if(this.state != Halted && this.state != Start && this.state != Primed) {
    127156                coroutine$ * src = active_coroutine();
     
    283312}
    284313
     314
     315////////////////////////////////////////////////////////////////////////////////////////////////////
     316// non local ehm routines
     317
     318void defaultResumeAtHandler( exception_t * except ) {
     319    __cfaehm_allocate_exception( except );
     320    free( except );
     321    __cfaehm_begin_unwind( (void(*)(exception_t *))defaultTerminationHandler );
     322}
     323
     324bool 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
     344bool poll() libcfa_public { return poll( active_coroutine() ); }
     345coroutine$ * resumer() libcfa_public { return active_coroutine()->last; }
     346
     347// user facing ehm operations
     348forall(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)
     363forall(exceptT *, T & | ehm_resume_at( exceptT, T ))
     364void 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
     375forall(exceptT * | { void $throwResume(exceptT &); })
     376void 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
    285386// Local Variables: //
    286387// mode: c //
Note: See TracChangeset for help on using the changeset viewer.