Ignore:
File:
1 edited

Legend:

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

    rb93bf85 r6b33e89  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jan  9 08:42:05 2023
    13 // Update Count     : 77
     12// Last Modified On : Fri Apr 25 07:02:42 2025
     13// Update Count     : 82
    1414//
    1515
     
    4545#pragma GCC diagnostic pop
    4646
    47 #if !defined(__CFA_NO_STATISTICS__)
     47#if ! defined(__CFA_NO_STATISTICS__)
    4848        #define __STATS_DEF( ...) __VA_ARGS__
    4949#else
     
    158158
    159159        __cfadbg_print_safe(runtime_core, "Kernel : core %p starting\n", this);
    160         #if !defined(__CFA_NO_STATISTICS__)
    161                 if( this->print_halts ) {
     160        #if ! defined(__CFA_NO_STATISTICS__)
     161                if ( this->print_halts ) {
    162162                        __cfaabi_bits_print_safe( STDOUT_FILENO, "Processor : %d - %s (%p)\n", this->unique_id, this->name, (void*)this);
    163163                }
     
    169169
    170170                // if we need to run some special setup, now is the time to do it.
    171                 if(this->init.thrd) {
     171                if (this->init.thrd) {
    172172                        this->init.thrd->curr_cluster = this->cltr;
    173173                        __run_thread(this, this->init.thrd);
     
    185185                        readyThread = __next_thread( this->cltr );
    186186
    187                         if( !readyThread ) {
     187                        if ( ! readyThread ) {
    188188                                // there is no point in holding submissions if we are idle
    189189                                __IO_STATS__(true, io.flush.idle++; )
     
    196196                        }
    197197
    198                         if( !readyThread ) for(5) {
     198                        if ( ! readyThread ) for(5) {
    199199                                readyThread = __next_thread_slow( this->cltr );
    200200
    201                                 if( readyThread ) break;
     201                                if ( readyThread ) break;
    202202
    203203                                // It's unlikely we still I/O to submit, but the arbiter could
     
    210210
    211211                        HALT:
    212                         if( !readyThread ) {
     212                        if ( ! readyThread ) {
    213213                                // Don't block if we are done
    214                                 if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
     214                                if ( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
    215215
    216216                                // Push self to idle stack
    217                                 if(!mark_idle(this->cltr->procs, * this)) continue MAIN_LOOP;
     217                                if ( ! mark_idle(this->cltr->procs, * this)) continue MAIN_LOOP;
    218218
    219219                                // Confirm the ready-queue is empty
    220220                                readyThread = __next_thread_search( this->cltr );
    221                                 if( readyThread ) {
     221                                if ( readyThread ) {
    222222                                        // A thread was found, cancel the halt
    223223                                        mark_awake(this->cltr->procs, * this);
     
    247247
    248248                        // Are we done?
    249                         if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
    250 
    251                         if(__atomic_load_n(&this->io.pending, __ATOMIC_RELAXED) && !__atomic_load_n(&this->io.dirty, __ATOMIC_RELAXED)) {
     249                        if ( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
     250
     251                        if (__atomic_load_n(&this->io.pending, __ATOMIC_RELAXED) && ! __atomic_load_n(&this->io.dirty, __ATOMIC_RELAXED)) {
    252252                                __IO_STATS__(true, io.flush.dirty++; )
    253253                                __cfa_io_flush( this );
     
    263263        post( this->terminated );
    264264
    265         if(this == mainProcessor) {
     265        if (this == mainProcessor) {
    266266                // HACK : the coroutine context switch expects this_thread to be set
    267267                // and it make sense for it to be set in all other cases except here
     
    294294
    295295        // Actually run the thread
    296         RUNNING:  while(true) {
     296        RUNNING:
     297        while( true ) {
    297298                thrd_dst->preempted = __NO_PREEMPTION;
    298299
     
    339340                // In case 2, we lost the race so we now own the thread.
    340341
    341                 if(unlikely(thrd_dst->preempted != __NO_PREEMPTION)) {
     342                if (unlikely(thrd_dst->preempted != __NO_PREEMPTION)) {
    342343                        // Reset the this_thread now that we know
    343344                        // the state isn't active anymore
     
    349350                }
    350351
    351                 if(unlikely(thrd_dst->state == Halting)) {
     352                if (unlikely(thrd_dst->state == Halting)) {
    352353                        // Reset the this_thread now that we know
    353354                        // the state isn't active anymore
     
    418419        }
    419420
    420         #if !defined(__CFA_NO_STATISTICS__)
     421        #if ! defined(__CFA_NO_STATISTICS__)
    421422                /* paranoid */ verify( thrd_src->last_proc != 0p );
    422                 if(thrd_src->last_proc != kernelTLS().this_processor) {
     423                if (thrd_src->last_proc != kernelTLS().this_processor) {
    423424                        __tls_stats()->ready.threads.migration++;
    424425                }
     
    440441        /* paranoid */ verify( thrd->curr_cluster );
    441442        /* paranoid */ #if defined( __CFA_WITH_VERIFY__ )
    442         /* paranoid */  if( thrd->state == Blocked || thrd->state == Start ) assertf( thrd->preempted == __NO_PREEMPTION,
     443        /* paranoid */  if ( thrd->state == Blocked || thrd->state == Start ) assertf( thrd->preempted == __NO_PREEMPTION,
    443444                                        "Error inactive thread marked as preempted, state %d, preemption %d\n", thrd->state, thrd->preempted );
    444         /* paranoid */  if( thrd->preempted != __NO_PREEMPTION ) assertf(thrd->state == Active,
     445        /* paranoid */  if ( thrd->preempted != __NO_PREEMPTION ) assertf(thrd->state == Active,
    445446                                        "Error preempted thread marked as not currently running, state %d, preemption %d\n", thrd->state, thrd->preempted );
    446447        /* paranoid */ #endif
     
    463464        __wake_one( cl );
    464465
    465         #if !defined(__CFA_NO_STATISTICS__)
    466                 if( kernelTLS().this_stats ) {
     466        #if ! defined(__CFA_NO_STATISTICS__)
     467                if ( kernelTLS().this_stats ) {
    467468                        __tls_stats()->ready.threads.threads++;
    468                         if(outside) {
     469                        if (outside) {
    469470                                __tls_stats()->ready.threads.extunpark++;
    470471                        }
     
    542543        /* paranoid */ verify( ready_schedule_islocked());
    543544
    544         if( !thrd ) return;
    545 
    546         if(__must_unpark(thrd)) {
     545        if ( ! thrd ) return;
     546
     547        if (__must_unpark(thrd)) {
    547548                // Wake lost the race,
    548549                __schedule_thread( thrd, hint );
     
    554555
    555556void unpark( thread$ * thrd, unpark_hint hint ) libcfa_public {
    556         if( !thrd ) return;
    557 
    558         if(__must_unpark(thrd)) {
     557        if ( ! thrd ) return;
     558
     559        if (__must_unpark(thrd)) {
    559560                disable_interrupts();
    560561                        // Wake lost the race,
     
    592593                /* paranoid */ verifyf( ((uintptr_t)thrd->context.SP) < ((uintptr_t)__get_stack(thrd->curr_cor)->base ), "ERROR : thread$ %p has been corrupted.\n StackPointer too small.\n", thrd );
    593594
    594                 if( TICKET_RUNNING != thrd->ticket ) { abort( "Thread terminated with pending unpark" ); }
    595                 if( thrd != this->owner ) { abort( "Thread internal monitor has incorrect owner" ); }
    596                 if( this->recursion != 1) { abort( "Thread internal monitor has unbalanced recursion" ); }
     595                if ( TICKET_RUNNING != thrd->ticket ) { abort( "Thread terminated with pending unpark" ); }
     596                if ( thrd != this->owner ) { abort( "Thread internal monitor has incorrect owner" ); }
     597                if ( this->recursion != 1) { abort( "Thread internal monitor has unbalanced recursion" ); }
    597598
    598599                thrd->state = Halting;
     
    618619                // If that is the case, abandon the preemption.
    619620                bool preempted = false;
    620                 if(thrd->rdy_link.next == 0p) {
     621                if (thrd->rdy_link.next == 0p) {
    621622                        preempted = true;
    622623                        thrd->preempted = reason;
     
    641642
    642643        // If no one is sleeping: we are done
    643         if( fdp == 0p ) return;
     644        if ( fdp == 0p ) return;
    644645
    645646        int fd = 1;
    646         if( __atomic_load_n(&fdp->sem, __ATOMIC_SEQ_CST) != 1 ) {
     647        if ( __atomic_load_n(&fdp->sem, __ATOMIC_SEQ_CST) != 1 ) {
    647648                fd = __atomic_exchange_n(&fdp->sem, 1, __ATOMIC_RELAXED);
    648649        }
     
    652653        case 0:
    653654                // If the processor isn't ready to sleep then the exchange will already wake it up
    654                 #if !defined(__CFA_NO_STATISTICS__)
    655                         if( kernelTLS().this_stats ) { __tls_stats()->ready.sleep.early++;
     655                #if ! defined(__CFA_NO_STATISTICS__)
     656                        if ( kernelTLS().this_stats ) { __tls_stats()->ready.sleep.early++;
    656657                        } else { __atomic_fetch_add(&this->stats->ready.sleep.early, 1, __ATOMIC_RELAXED); }
    657658                #endif
     
    659660        case 1:
    660661                // If someone else already said they will wake them: we are done
    661                 #if !defined(__CFA_NO_STATISTICS__)
    662                         if( kernelTLS().this_stats ) { __tls_stats()->ready.sleep.seen++;
     662                #if ! defined(__CFA_NO_STATISTICS__)
     663                        if ( kernelTLS().this_stats ) { __tls_stats()->ready.sleep.seen++;
    663664                        } else { __atomic_fetch_add(&this->stats->ready.sleep.seen, 1, __ATOMIC_RELAXED); }
    664665                #endif
     
    670671                /* paranoid */ verifyf( ret == 0, "Expected return to be 0, was %d\n", ret );
    671672
    672                 #if !defined(__CFA_NO_STATISTICS__)
    673                         if( kernelTLS().this_stats ) { __tls_stats()->ready.sleep.wakes++;
     673                #if ! defined(__CFA_NO_STATISTICS__)
     674                        if ( kernelTLS().this_stats ) { __tls_stats()->ready.sleep.wakes++;
    674675                        } else { __atomic_fetch_add(&this->stats->ready.sleep.wakes, 1, __ATOMIC_RELAXED); }
    675676                #endif
     
    710711
    711712                // Someone already told us to wake-up! No time for a nap.
    712                 if(expected == 1) { return; }
     713                if (expected == 1) { return; }
    713714
    714715                // Try to mark that we are going to sleep
    715                 if(__atomic_compare_exchange_n(&this->idle_wctx.sem, &expected, this->idle_wctx.evfd, false,  __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ) {
     716                if (__atomic_compare_exchange_n(&this->idle_wctx.sem, &expected, this->idle_wctx.evfd, false,  __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ) {
    716717                        // Every one agreed, taking a nap
    717718                        break;
     
    720721
    721722
    722         #if !defined(__CFA_NO_STATISTICS__)
    723                 if(this->print_halts) {
     723        #if ! defined(__CFA_NO_STATISTICS__)
     724                if (this->print_halts) {
    724725                        __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl());
    725726                }
     
    731732                eventfd_t val;
    732733                ssize_t ret = read( this->idle_wctx.evfd, &val, sizeof(val) );
    733                 if(ret < 0) {
     734                if (ret < 0) {
    734735                        switch((int)errno) {
    735736                        case EAGAIN:
     
    746747        }
    747748
    748         #if !defined(__CFA_NO_STATISTICS__)
    749                 if(this->print_halts) {
     749        #if ! defined(__CFA_NO_STATISTICS__)
     750                if (this->print_halts) {
    750751                        __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl());
    751752                }
     
    759760
    760761        /* paranoid */ verify( ! __preemption_enabled() );
    761         if(!try_lock( this )) return false;
     762        if ( ! try_lock( this )) return false;
    762763                this.idle++;
    763764                /* paranoid */ verify( this.idle <= this.total );
     
    784785                        // update the pointer to the head wait context
    785786                        struct __fd_waitctx * wctx = 0;
    786                         if(!this.idles`isEmpty) wctx = &this.idles`first.idle_wctx;
     787                        if ( ! isEmpty( this.idles )) wctx = &first( this. idles ).idle_wctx;
    787788                        __atomic_store_n(&this.fdw, wctx, __ATOMIC_SEQ_CST);
    788789                }
     
    798799        thread$ * thrd = __cfaabi_tls.this_thread;
    799800
    800         if(thrd) {
     801        if (thrd) {
    801802                int len = snprintf( abort_text, abort_text_size, "Error occurred while executing thread %.256s (%p)", thrd->self_cor.name, thrd );
    802803                __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
     
    847848//-----------------------------------------------------------------------------
    848849// Statistics
    849 #if !defined(__CFA_NO_STATISTICS__)
     850#if ! defined(__CFA_NO_STATISTICS__)
    850851        void print_halts( processor & this ) libcfa_public {
    851852                this.print_halts = true;
     
    855856                /* paranoid */ verify( cltr->stats );
    856857
    857                 processor * it = &list`first;
     858                processor * it = &first( list );
    858859                for(unsigned i = 0; i < count; i++) {
    859860                        /* paranoid */ verifyf( it, "Unexpected null iterator, at index %u of %u\n", i, count);
     
    861862                        // __print_stats( it->local_data->this_stats, cltr->print_stats, "Processor", it->name, (void*)it );
    862863                        __tally_stats( cltr->stats, it->local_data->this_stats );
    863                         it = &(*it)`next;
     864                        it = &next( *it );
    864865                }
    865866        }
Note: See TracChangeset for help on using the changeset viewer.