Ignore:
Timestamp:
Apr 25, 2025, 7:39:09 AM (8 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
65bd3c2
Parents:
b195498
Message:

change backquote call to regular call

File:
1 edited

Legend:

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

    rb195498 r6b33e89  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 18 21:47:12 2023
    13 // Update Count     : 25
     12// Last Modified On : Fri Apr 25 06:48:19 2025
     13// Update Count     : 31
    1414//
    1515
     
    8282// helper for popping from coroutine's ehm buffer
    8383static 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;
     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;
    8888}
    8989
     
    9797
    9898void __stack_prepare( __stack_info_t * this, size_t create_size );
    99 static void __stack_clean  ( __stack_info_t * this );
     99static void __stack_clean( __stack_info_t * this );
    100100
    101101//-----------------------------------------------------------------------------
     
    105105
    106106        // Did we get a piece of storage ?
    107         if (this.storage || storageSize != 0) {
     107        if ( this.storage || storageSize != 0 ) {
    108108                // We either got a piece of storage or the user asked for a specific size
    109109                // Immediately create the stack
     
    128128        state = Start;
    129129        starter = 0p;
    130         last = 0p;
     130        this.last = 0p;
    131131        cancellation = 0p;
    132     ehm_state.ehm_buffer{};
    133     ehm_state.buffer_lock{};
    134     ehm_state.ehm_enabled = false;
    135 }
    136 
    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 
    155         if(this.state != Halted && this.state != Start && this.state != Primed) {
     132        ehm_state.ehm_buffer{};
     133        ehm_state.buffer_lock{};
     134        ehm_state.ehm_enabled = false;
     135}
     136
     137void ^?{}( 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        for ( ; nl_ex != 0p; nl_ex = pop_ehm_head( &this ) ) {
     144                unhandled_ex++;
     145                free( nl_ex->the_exception );
     146                free( nl_ex );
     147        }
     148
     149        #ifdef __CFA_DEBUG__
     150        if ( unhandled_ex > 0 )
     151                printf( "Warning: Coroutine %p exited with %u pending nonlocal exceptions.\n", &this, unhandled_ex );
     152        #endif
     153
     154        if ( this.state != Halted && this.state != Start && this.state != Primed ) {
    156155                coroutine$ * src = active_coroutine();
    157156                coroutine$ * dst = &this;
     
    174173// Part of the Public API
    175174// Not inline since only ever called once per coroutine
    176 forall(T & | is_coroutine(T) | { EHM_DEFAULT_VTABLE(CoroutineCancelled(T)); })
    177 void prime(T& cor) libcfa_public {
    178         coroutine$* this = get_coroutine(cor);
    179         assert(this->state == Start);
     175forall( T & | is_coroutine(T) | { EHM_DEFAULT_VTABLE(CoroutineCancelled(T)); } )
     176void prime( T & cor ) libcfa_public {
     177        coroutine$ * this = get_coroutine(cor);
     178        assert( this->state == Start );
    180179
    181180        this->state = Primed;
    182         resume(cor);
     181        resume( cor );
    183182}
    184183
    185184static [void *, size_t] __stack_alloc( size_t storageSize ) {
    186185        const size_t stack_data_size = libCeiling( sizeof(__stack_t), 16 ); // minimum alignment
    187         assert(__page_size != 0l);
     186        assert( __page_size != 0l );
    188187        size_t size = libCeiling( storageSize, 16 ) + stack_data_size;
    189         size = ceiling(size, __page_size);
     188        size = ceiling( size, __page_size );
    190189
    191190        // If we are running debug, we also need to allocate a guardpage to catch stack overflows.
     
    193192        #if CFA_COROUTINE_USE_MMAP
    194193                storage = mmap(0p, size + __page_size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
    195                 if(storage == ((void*)-1)) {
     194                if (storage == ((void*)-1)) {
    196195                        abort( "coroutine stack creation : internal error, mmap failure, error(%d) %s.", errno, strerror( errno ) );
    197196                }
     
    227226                size_t size = ((intptr_t)this->storage->base) - ((intptr_t)this->storage->limit) + sizeof(__stack_t);
    228227                storage = (void *)(((intptr_t)storage) - __page_size);
    229                 if(munmap(storage, size + __page_size) == -1) {
     228                if (munmap(storage, size + __page_size) == -1) {
    230229                        abort( "coroutine stack destruction : internal error, munmap failure, error(%d) %s.", errno, strerror( errno ) );
    231230                }
     
    248247        void * storage;
    249248        size_t size;
    250         if ( !this->storage ) {
     249        if ( ! this->storage ) {
    251250                userStack = false;
    252251                [storage, size] = __stack_alloc( create_size );
     
    302301                athrd->corctx_flag = false;
    303302
    304                 if(cor->state == Primed) {
     303                if (cor->state == Primed) {
    305304                        __cfactx_suspend();
    306305                }
     
    317316
    318317void defaultResumeAtHandler( exception_t * except ) {
    319     __cfaehm_allocate_exception( except );
    320     __cfaehm_begin_unwind( (void(*)(exception_t *))defaultTerminationHandler );
     318        __cfaehm_allocate_exception( except );
     319        __cfaehm_begin_unwind( (void(*)(exception_t *))defaultTerminationHandler );
    321320}
    322321
     
    328327
    329328bool poll( coroutine$ * cor ) libcfa_public {
    330     nonlocal_exception * nl_ex = pop_ehm_head( cor );
    331 
    332     // if no exceptions return false
    333     if ( nl_ex == 0p ) return false;
    334    
    335     // otherwise loop and throwResume all pending exceptions
    336     while ( nl_ex != 0p ){
     329        nonlocal_exception * nl_ex = pop_ehm_head( cor );
     330
     331        // if no exceptions return false
     332        if ( nl_ex == 0p ) return false;
     333       
     334        // otherwise loop and throwResume all pending exceptions
     335        for ( ; nl_ex != 0p; nl_ex = pop_ehm_head( cor ) ) {
    337336                ehm_cleanup ex_holder{ nl_ex->the_exception };
    338         free( nl_ex );
    339         __cfaehm_throw_resume( ex_holder.ex , defaultResumeAtHandler );
    340        
    341         nl_ex = pop_ehm_head( cor );
    342     }
    343    
    344     return true;
     337                free( nl_ex );
     338                __cfaehm_throw_resume( ex_holder.ex , defaultResumeAtHandler );
     339        }
     340       
     341        return true;
    345342}
    346343
     
    354351// user facing ehm operations
    355352forall(T & | is_coroutine(T)) {
    356     // enable/disable non-local exceptions
    357     void enable_ehm( T & cor ) libcfa_public { get_coroutine( cor )->ehm_state.ehm_enabled = true; }
    358     void disable_ehm( T & cor ) libcfa_public { get_coroutine( cor )->ehm_state.ehm_enabled = false; }
    359 
    360     // poll for non-local exceptions
    361     bool poll( T & cor ) libcfa_public { return poll( get_coroutine( cor ) ); }
    362 
    363     // poll iff nonlocal ehm is enabled
    364     bool checked_poll( T & cor ) libcfa_public { return get_coroutine( cor )->ehm_state.ehm_enabled ? poll( cor ) : false; }
    365 
    366     coroutine$ * resumer( T & cor ) libcfa_public { return get_coroutine( cor )->last; }
    367     coroutine$ * first_resumer( T & cor ) libcfa_public { return get_coroutine( cor )->starter; }
     353        // enable/disable non-local exceptions
     354        void enable_ehm( T & cor ) libcfa_public { get_coroutine( cor )->ehm_state.ehm_enabled = true; }
     355        void disable_ehm( T & cor ) libcfa_public { get_coroutine( cor )->ehm_state.ehm_enabled = false; }
     356
     357        // poll for non-local exceptions
     358        bool poll( T & cor ) libcfa_public { return poll( get_coroutine( cor ) ); }
     359
     360        // poll iff nonlocal ehm is enabled
     361        bool checked_poll( T & cor ) libcfa_public { return get_coroutine( cor )->ehm_state.ehm_enabled ? poll( cor ) : false; }
     362
     363        coroutine$ * resumer( T & cor ) libcfa_public { return get_coroutine( cor )->last; }
     364        coroutine$ * first_resumer( T & cor ) libcfa_public { return get_coroutine( cor )->starter; }
    368365}
    369366
     
    371368forall(exceptT *, T & | ehm_resume_at( exceptT, T ))
    372369void resumeAt( T & receiver, exceptT & ex ) libcfa_public {
    373     coroutine$ * cor = get_coroutine( receiver );
    374     nonlocal_exception * nl_ex = alloc();
    375     exceptT * ex_copy = alloc();
    376     memcpy( ex_copy, &ex, sizeof(exceptT) );
    377     (*nl_ex){ (exception_t *)ex_copy };
    378     lock( cor->ehm_state.buffer_lock __cfaabi_dbg_ctx2 );
    379     append( cor->ehm_state.ehm_buffer, nl_ex );
    380     unlock( cor->ehm_state.buffer_lock );
     370        coroutine$ * cor = get_coroutine( receiver );
     371        nonlocal_exception * nl_ex = alloc();
     372        exceptT * ex_copy = alloc();
     373        memcpy( ex_copy, &ex, sizeof(exceptT) );
     374        (*nl_ex){ (exception_t *)ex_copy };
     375        lock( cor->ehm_state.buffer_lock __cfaabi_dbg_ctx2 );
     376        append( cor->ehm_state.ehm_buffer, nl_ex );
     377        unlock( cor->ehm_state.buffer_lock );
    381378}
    382379
    383380forall(exceptT * | { void $throwResume(exceptT &); })
    384381void resumeAt( coroutine$ * receiver, exceptT & ex ) libcfa_public {
    385     nonlocal_exception * nl_ex = alloc();
    386     exceptT * ex_copy = alloc();
    387     memcpy( ex_copy, &ex, sizeof(exceptT) );
    388     (*nl_ex){ (exception_t *)ex_copy };
    389     lock( receiver->ehm_state.buffer_lock __cfaabi_dbg_ctx2 );
    390     append( receiver->ehm_state.ehm_buffer, nl_ex );
    391     unlock( receiver->ehm_state.buffer_lock );
     382        nonlocal_exception * nl_ex = alloc();
     383        exceptT * ex_copy = alloc();
     384        memcpy( ex_copy, &ex, sizeof(exceptT) );
     385        (*nl_ex){ (exception_t *)ex_copy };
     386        lock( receiver->ehm_state.buffer_lock __cfaabi_dbg_ctx2 );
     387        append( receiver->ehm_state.ehm_buffer, nl_ex );
     388        unlock( receiver->ehm_state.buffer_lock );
    392389}
    393390
Note: See TracChangeset for help on using the changeset viewer.