Changeset aec68b6


Ignore:
Timestamp:
Apr 25, 2021, 10:11:27 PM (4 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
24711a3, 5456537
Parents:
9b71679 (diff), c323837 (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:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
libcfa/src
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/bits/locks.hfa

    r9b71679 raec68b6  
    3737        extern "C" {
    3838                extern void disable_interrupts() OPTIONAL_THREAD;
    39                 extern void enable_interrupts_noPoll() OPTIONAL_THREAD;
     39                extern void enable_interrupts( bool poll = true ) OPTIONAL_THREAD;
    4040
    4141                #ifdef __CFA_DEBUG__
     
    5757                        __cfaabi_dbg_record_lock( this, caller );
    5858                } else {
    59                         enable_interrupts_noPoll();
     59                        enable_interrupts( false );
    6060                }
    6161                return result;
     
    9090        static inline void unlock( __spinlock_t & this ) {
    9191                __atomic_clear( &this.lock, __ATOMIC_RELEASE );
    92                 enable_interrupts_noPoll();
     92                enable_interrupts( false );
    9393        }
    9494#endif
  • libcfa/src/concurrency/alarm.cfa

    r9b71679 raec68b6  
    116116        unlock( event_kernel->lock );
    117117        this->set = true;
    118         enable_interrupts( __cfaabi_dbg_ctx );
     118        enable_interrupts();
    119119}
    120120
     
    127127        }
    128128        unlock( event_kernel->lock );
    129         enable_interrupts( __cfaabi_dbg_ctx );
     129        enable_interrupts();
    130130        this->set = false;
    131131}
  • libcfa/src/concurrency/clib/cfathread.cfa

    r9b71679 raec68b6  
    117117
    118118        this_thrd->state = Ready;
    119         enable_interrupts( __cfaabi_dbg_ctx );
     119        enable_interrupts();
    120120}
    121121
  • libcfa/src/concurrency/future.hfa

    r9b71679 raec68b6  
    3737
    3838                // Fulfil the future, returns whether or not someone was unblocked
    39                 bool fulfil( future(T) & this, T result ) {
     39                $thread * fulfil( future(T) & this, T result ) {
    4040                        this.result = result;
    4141                        return fulfil( (future_t&)this );
     
    9696                bool fulfil( multi_future(T) & this, T result ) {
    9797                        this.result = result;
    98                         return fulfil( (future_t&)this );
     98                        return fulfil( (future_t&)this ) != 0p;
    9999                }
    100100
  • libcfa/src/concurrency/invoke.c

    r9b71679 raec68b6  
    3434
    3535extern void disable_interrupts() OPTIONAL_THREAD;
    36 extern void enable_interrupts( __cfaabi_dbg_ctx_param );
     36extern void enable_interrupts( _Bool poll );
    3737
    3838void __cfactx_invoke_coroutine(
     
    8282) {
    8383        // Officially start the thread by enabling preemption
    84         enable_interrupts( __cfaabi_dbg_ctx );
     84        enable_interrupts( true );
    8585
    8686        // Call the main of the thread
  • libcfa/src/concurrency/io.cfa

    r9b71679 raec68b6  
    9090        static inline __u32 __release_sqes( struct $io_context & );
    9191
    92         void __cfa_io_drain( processor * proc ) {
     92        bool __cfa_io_drain( processor * proc ) {
    9393                /* paranoid */ verify( ! __preemption_enabled() );
    9494                /* paranoid */ verify( proc );
     
    104104                __STATS__( false, io.calls.drain++; io.calls.completed += count; )
    105105
     106                if(count == 0) return false;
     107
    106108                for(i; count) {
    107109                        unsigned idx = (head + i) & mask;
     
    124126                /* paranoid */ verify( ! __preemption_enabled() );
    125127
    126                 return;
     128                return true;
    127129        }
    128130
     
    242244                        // Allocation was successful
    243245                        __STATS__( true, io.alloc.fast += 1; )
    244                         enable_interrupts( __cfaabi_dbg_ctx );
     246                        enable_interrupts();
    245247
    246248                        __cfadbg_print_safe(io, "Kernel I/O : fast allocation successful from ring %d\n", ctx->fd);
     
    254256                // Fast path failed, fallback on arbitration
    255257                __STATS__( true, io.alloc.slow += 1; )
    256                 enable_interrupts( __cfaabi_dbg_ctx );
     258                enable_interrupts();
    257259
    258260                $io_arbiter * ioarb = proc->cltr->io.arbiter;
     
    312314                        // Mark the instance as no longer in-use, re-enable interrupts and return
    313315                        __STATS__( true, io.submit.fast += 1; )
    314                         enable_interrupts( __cfaabi_dbg_ctx );
     316                        enable_interrupts();
    315317
    316318                        __cfadbg_print_safe(io, "Kernel I/O : submitted on fast path\n");
     
    320322                // Fast path failed, fallback on arbitration
    321323                __STATS__( true, io.submit.slow += 1; )
    322                 enable_interrupts( __cfaabi_dbg_ctx );
     324                enable_interrupts();
    323325
    324326                __cfadbg_print_safe(io, "Kernel I/O : falling back on arbiter for submission\n");
  • libcfa/src/concurrency/io/types.hfa

    r9b71679 raec68b6  
    179179
    180180static inline {
    181         bool fulfil( io_future_t & this, __s32 result ) {
     181        $thread * fulfil( io_future_t & this, __s32 result, bool do_unpark = true ) {
    182182                this.result = result;
    183                 return fulfil(this.self);
     183                return fulfil(this.self, do_unpark);
    184184        }
    185185
  • libcfa/src/concurrency/kernel.cfa

    r9b71679 raec68b6  
    110110static $thread * __next_thread(cluster * this);
    111111static $thread * __next_thread_slow(cluster * this);
     112static inline bool __must_unpark( $thread * thrd ) __attribute((nonnull(1)));
    112113static void __run_thread(processor * this, $thread * dst);
    113114static void __wake_one(cluster * cltr);
     
    118119
    119120extern void __cfa_io_start( processor * );
    120 extern void __cfa_io_drain( processor * );
     121extern bool __cfa_io_drain( processor * );
    121122extern void __cfa_io_flush( processor * );
    122123extern void __cfa_io_stop ( processor * );
    123 static inline void __maybe_io_drain( processor * );
     124static inline bool __maybe_io_drain( processor * );
    124125
    125126extern void __disable_interrupts_hard();
    126127extern void __enable_interrupts_hard();
     128
     129static inline void __disable_interrupts_checked() {
     130        /* paranoid */ verify( __preemption_enabled() );
     131        disable_interrupts();
     132        /* paranoid */ verify( ! __preemption_enabled() );
     133}
     134
     135static inline void __enable_interrupts_checked( bool poll = true ) {
     136        /* paranoid */ verify( ! __preemption_enabled() );
     137        enable_interrupts( poll );
     138        /* paranoid */ verify( __preemption_enabled() );
     139}
    127140
    128141//=============================================================================================
     
    336349                if(unlikely(thrd_dst->preempted != __NO_PREEMPTION)) {
    337350                        // The thread was preempted, reschedule it and reset the flag
    338                         __schedule_thread( thrd_dst );
     351                        schedule_thread$( thrd_dst );
    339352                        break RUNNING;
    340353                }
     
    426439        /* paranoid */ verify( ! __preemption_enabled() );
    427440        /* paranoid */ verify( kernelTLS().this_proc_id );
     441        /* paranoid */ verify( ready_schedule_islocked());
    428442        /* paranoid */ verify( thrd );
    429443        /* paranoid */ verify( thrd->state != Halted );
     
    444458        struct cluster * cl = thrd->curr_cluster;
    445459
    446         ready_schedule_lock();
    447                 // push the thread to the cluster ready-queue
    448                 push( cl, thrd );
    449 
    450                 // variable thrd is no longer safe to use
    451 
    452                 // wake the cluster using the save variable.
    453                 __wake_one( cl );
    454         ready_schedule_unlock();
     460        // push the thread to the cluster ready-queue
     461        push( cl, thrd );
     462
     463        // variable thrd is no longer safe to use
     464        thrd = 0xdeaddeaddeaddeadp;
     465
     466        // wake the cluster using the save variable.
     467        __wake_one( cl );
    455468
    456469        #if !defined(__CFA_NO_STATISTICS__)
     
    465478        #endif
    466479
    467         /* paranoid */ verify( ! __preemption_enabled() );
     480        /* paranoid */ verify( ready_schedule_islocked());
     481        /* paranoid */ verify( ! __preemption_enabled() );
     482}
     483
     484void schedule_thread$( $thread * thrd ) {
     485        ready_schedule_lock();
     486                __schedule_thread( thrd );
     487        ready_schedule_unlock();
    468488}
    469489
     
    496516}
    497517
    498 void unpark( $thread * thrd ) {
    499         if( !thrd ) return;
    500 
     518static inline bool __must_unpark( $thread * thrd ) {
    501519        int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST);
    502520        switch(old_ticket) {
    503521                case TICKET_RUNNING:
    504522                        // Wake won the race, the thread will reschedule/rerun itself
    505                         break;
     523                        return false;
    506524                case TICKET_BLOCKED:
    507525                        /* paranoid */ verify( ! thrd->preempted != __NO_PREEMPTION );
    508526                        /* paranoid */ verify( thrd->state == Blocked );
    509 
    510                         {
    511                                 /* paranoid */ verify( publicTLS_get(this_proc_id) );
    512                                 disable_interrupts();
    513 
    514                                 /* paranoid */ verify( ! __preemption_enabled() );
    515 
    516                                 // Wake lost the race,
    517                                 __schedule_thread( thrd );
    518 
    519                                 /* paranoid */ verify( ! __preemption_enabled() );
    520 
    521                                 enable_interrupts_noPoll();
    522                                 /* paranoid */ verify( publicTLS_get(this_proc_id) );
    523                         }
    524 
    525                         break;
     527                        return true;
    526528                default:
    527529                        // This makes no sense, something is wrong abort
     
    530532}
    531533
     534void unpark( $thread * thrd ) {
     535        if( !thrd ) return;
     536
     537        if(__must_unpark(thrd)) {
     538                disable_interrupts();
     539                        // Wake lost the race,
     540                        schedule_thread$( thrd );
     541                enable_interrupts(false);
     542        }
     543}
     544
    532545void park( void ) {
    533         /* paranoid */ verify( __preemption_enabled() );
    534         disable_interrupts();
    535         /* paranoid */ verify( ! __preemption_enabled() );
    536         /* paranoid */ verify( kernelTLS().this_thread->preempted == __NO_PREEMPTION );
    537 
    538         returnToKernel();
    539 
    540         /* paranoid */ verify( ! __preemption_enabled() );
    541         enable_interrupts( __cfaabi_dbg_ctx );
    542         /* paranoid */ verify( __preemption_enabled() );
     546        __disable_interrupts_checked();
     547                /* paranoid */ verify( kernelTLS().this_thread->preempted == __NO_PREEMPTION );
     548                returnToKernel();
     549        __enable_interrupts_checked();
    543550
    544551}
     
    580587// KERNEL ONLY
    581588bool force_yield( __Preemption_Reason reason ) {
    582         /* paranoid */ verify( __preemption_enabled() );
    583         disable_interrupts();
    584         /* paranoid */ verify( ! __preemption_enabled() );
    585 
    586         $thread * thrd = kernelTLS().this_thread;
    587         /* paranoid */ verify(thrd->state == Active);
    588 
    589         // SKULLDUGGERY: It is possible that we are preempting this thread just before
    590         // it was going to park itself. If that is the case and it is already using the
    591         // intrusive fields then we can't use them to preempt the thread
    592         // If that is the case, abandon the preemption.
    593         bool preempted = false;
    594         if(thrd->link.next == 0p) {
    595                 preempted = true;
    596                 thrd->preempted = reason;
    597                 returnToKernel();
    598         }
    599 
    600         /* paranoid */ verify( ! __preemption_enabled() );
    601         enable_interrupts_noPoll();
    602         /* paranoid */ verify( __preemption_enabled() );
    603 
     589        __disable_interrupts_checked();
     590                $thread * thrd = kernelTLS().this_thread;
     591                /* paranoid */ verify(thrd->state == Active);
     592
     593                // SKULLDUGGERY: It is possible that we are preempting this thread just before
     594                // it was going to park itself. If that is the case and it is already using the
     595                // intrusive fields then we can't use them to preempt the thread
     596                // If that is the case, abandon the preemption.
     597                bool preempted = false;
     598                if(thrd->link.next == 0p) {
     599                        preempted = true;
     600                        thrd->preempted = reason;
     601                        returnToKernel();
     602                }
     603        __enable_interrupts_checked( false );
    604604        return preempted;
    605605}
     
    646646        __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this);
    647647
    648         disable_interrupts();
     648        __disable_interrupts_checked();
    649649                /* paranoid */ verify( ! __preemption_enabled() );
    650650                eventfd_t val;
    651651                val = 1;
    652652                eventfd_write( this->idle, val );
    653         enable_interrupts( __cfaabi_dbg_ctx );
     653        __enable_interrupts_checked();
    654654}
    655655
     
    743743#endif
    744744
    745 static inline void __maybe_io_drain( processor * proc ) {
     745static inline bool __maybe_io_drain( processor * proc ) {
    746746        #if defined(CFA_HAVE_LINUX_IO_URING_H)
    747747                __cfadbg_print_safe(runtime_core, "Kernel : core %p checking io for ring %d\n", proc, proc->io.ctx->fd);
     
    751751                unsigned head = *ctx->cq.head;
    752752                unsigned tail = *ctx->cq.tail;
    753                 if(head != tail) __cfa_io_drain( proc );
     753                if(head == tail) return false;
     754                return __cfa_io_drain( proc );
    754755        #endif
    755756}
  • libcfa/src/concurrency/kernel/fwd.hfa

    r9b71679 raec68b6  
    108108
    109109        extern void disable_interrupts();
    110         extern void enable_interrupts_noPoll();
    111         extern void enable_interrupts( __cfaabi_dbg_ctx_param );
     110        extern void enable_interrupts( bool poll = false );
    112111
    113112        extern "Cforall" {
     
    220219                        // Mark as fulfilled, wake thread if needed
    221220                        // return true if a thread was unparked
    222                         bool post(oneshot & this) {
     221                        $thread * post(oneshot & this, bool do_unpark = true) {
    223222                                struct $thread * got = __atomic_exchange_n( &this.ptr, 1p, __ATOMIC_SEQ_CST);
    224                                 if( got == 0p ) return false;
    225                                 unpark( got );
    226                                 return true;
     223                                if( got == 0p ) return 0p;
     224                                if(do_unpark) unpark( got );
     225                                return got;
    227226                        }
    228227                }
     
    336335                        // from the server side, mark the future as fulfilled
    337336                        // delete it if needed
    338                         bool fulfil( future_t & this ) {
     337                        $thread * fulfil( future_t & this, bool do_unpark = true ) {
    339338                                for() {
    340339                                        struct oneshot * expected = this.ptr;
     
    344343                                                #pragma GCC diagnostic ignored "-Wfree-nonheap-object"
    345344                                        #endif
    346                                                 if( expected == 3p ) { free( &this ); return false; }
     345                                                if( expected == 3p ) { free( &this ); return 0p; }
    347346                                        #if defined(__GNUC__) && __GNUC__ >= 7
    348347                                                #pragma GCC diagnostic pop
     
    356355                                        struct oneshot * want = expected == 0p ? 1p : 2p;
    357356                                        if(__atomic_compare_exchange_n(&this.ptr, &expected, want, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    358                                                 if( expected == 0p ) { /* paranoid */ verify( this.ptr == 1p); return false; }
    359                                                 bool ret = post( *expected );
     357                                                if( expected == 0p ) { /* paranoid */ verify( this.ptr == 1p); return 0p; }
     358                                                $thread * ret = post( *expected, do_unpark );
    360359                                                __atomic_store_n( &this.ptr, 1p, __ATOMIC_SEQ_CST);
    361360                                                return ret;
     
    403402                                        __VA_ARGS__ \
    404403                                } \
    405                                 if( !(in_kernel) ) enable_interrupts( __cfaabi_dbg_ctx ); \
     404                                if( !(in_kernel) ) enable_interrupts(); \
    406405                        }
    407406                #else
  • libcfa/src/concurrency/kernel/startup.cfa

    r9b71679 raec68b6  
    225225        // Add the main thread to the ready queue
    226226        // once resume is called on mainProcessor->runner the mainThread needs to be scheduled like any normal thread
    227         __schedule_thread(mainThread);
     227        schedule_thread$(mainThread);
    228228
    229229        // SKULLDUGGERY: Force a context switch to the main processor to set the main thread's context to the current UNIX
     
    238238
    239239        /* paranoid */ verify( ! __preemption_enabled() );
    240         enable_interrupts( __cfaabi_dbg_ctx );
     240        enable_interrupts();
    241241        /* paranoid */ verify( __preemption_enabled() );
    242242
     
    530530        disable_interrupts();
    531531                init( this, name, _cltr, initT );
    532         enable_interrupts( __cfaabi_dbg_ctx );
     532        enable_interrupts();
    533533
    534534        __cfadbg_print_safe(runtime_core, "Kernel : Starting core %p\n", &this);
     
    557557        disable_interrupts();
    558558                deinit( this );
    559         enable_interrupts( __cfaabi_dbg_ctx );
     559        enable_interrupts();
    560560}
    561561
     
    595595        // Unlock the RWlock
    596596        ready_mutate_unlock( last_size );
    597         enable_interrupts_noPoll(); // Don't poll, could be in main cluster
     597        enable_interrupts( false ); // Don't poll, could be in main cluster
    598598}
    599599
     
    610610        // Unlock the RWlock
    611611        ready_mutate_unlock( last_size );
    612         enable_interrupts_noPoll(); // Don't poll, could be in main cluster
     612        enable_interrupts( false ); // Don't poll, could be in main cluster
    613613
    614614        #if !defined(__CFA_NO_STATISTICS__)
  • libcfa/src/concurrency/kernel_private.hfa

    r9b71679 raec68b6  
    2929extern "C" {
    3030        void disable_interrupts() OPTIONAL_THREAD;
    31         void enable_interrupts_noPoll();
    32         void enable_interrupts( __cfaabi_dbg_ctx_param );
    33 }
    34 
    35 void __schedule_thread( $thread * )
    36 #if defined(NDEBUG) || (!defined(__CFA_DEBUG__) && !defined(__CFA_VERIFY__))
    37         __attribute__((nonnull (1)))
    38 #endif
    39 ;
     31        void enable_interrupts( bool poll = true );
     32}
     33
     34void schedule_thread$( $thread * ) __attribute__((nonnull (1)));
    4035
    4136extern bool __preemption_enabled();
  • libcfa/src/concurrency/preemption.cfa

    r9b71679 raec68b6  
    315315        // Enable interrupts by decrementing the counter
    316316        // If counter reaches 0, execute any pending __cfactx_switch
    317         void enable_interrupts( __cfaabi_dbg_ctx_param ) {
     317        void enable_interrupts( bool poll ) {
    318318                // Cache the processor now since interrupts can start happening after the atomic store
    319319                processor   * proc = __cfaabi_tls.this_processor;
    320                 /* paranoid */ verify( proc );
     320                /* paranoid */ verify( !poll || proc );
    321321
    322322                with( __cfaabi_tls.preemption_state ){
     
    340340                                // Signal the compiler that a fence is needed but only for signal handlers
    341341                                __atomic_signal_fence(__ATOMIC_RELEASE);
    342                                 if( proc->pending_preemption ) {
     342                                if( poll && proc->pending_preemption ) {
    343343                                        proc->pending_preemption = false;
    344344                                        force_yield( __POLL_PREEMPTION );
    345345                                }
    346346                        }
    347                 }
    348 
    349                 // For debugging purposes : keep track of the last person to enable the interrupts
    350                 __cfaabi_dbg_debug_do( proc->last_enable = caller; )
    351         }
    352 
    353         // Disable interrupts by incrementint the counter
    354         // Don't execute any pending __cfactx_switch even if counter reaches 0
    355         void enable_interrupts_noPoll() {
    356                 unsigned short prev = __cfaabi_tls.preemption_state.disable_count;
    357                 __cfaabi_tls.preemption_state.disable_count -= 1;
    358                 // If this triggers someone is enabled already enabled interrupts
    359                 /* paranoid */ verifyf( prev != 0u, "Incremented from %u\n", prev );
    360                 if( prev == 1 ) {
    361                         #if GCC_VERSION > 50000
    362                                 static_assert(__atomic_always_lock_free(sizeof(__cfaabi_tls.preemption_state.enabled), &__cfaabi_tls.preemption_state.enabled), "Must be lock-free");
    363                         #endif
    364                         // Set enabled flag to true
    365                         // should be atomic to avoid preemption in the middle of the operation.
    366                         // use memory order RELAXED since there is no inter-thread on this variable requirements
    367                         __atomic_store_n(&__cfaabi_tls.preemption_state.enabled, true, __ATOMIC_RELAXED);
    368 
    369                         // Signal the compiler that a fence is needed but only for signal handlers
    370                         __atomic_signal_fence(__ATOMIC_RELEASE);
    371347                }
    372348        }
  • libcfa/src/concurrency/stats.cfa

    r9b71679 raec68b6  
    77#include "bits/locks.hfa"
    88#include "stats.hfa"
     9#include "strstream.hfa"
    910
    1011#if !defined(__CFA_NO_STATISTICS__)
     
    118119        }
    119120
     121        #define eng3(X) (ws(3, 3, unit(eng( X ))))
     122
    120123        void __print_stats( struct __stats_t * stats, int flags, const char * type, const char * name, void * id ) with( *stats ) {
    121124
     125                char buf[1024];
     126                strstream sstr = { buf, 1024 };
     127
    122128                if( flags & CFA_STATS_READY_Q ) {
    123                         double push_len = ((double)ready.push.local.attempt + ready.push.share.attempt + ready.push.extrn.attempt) / (ready.push.local.success + ready.push.share.success + ready.push.extrn.success);
     129
     130                        sstr | "----- " | type | "\"" | name | "\" (" | "" | id | "" | ") - Ready Q Stats -----";
     131
     132                        uint64_t totalR = ready.pop.local.success + ready.pop.help.success + ready.pop.steal.success + ready.pop.search.success;
     133                        uint64_t totalS = ready.push.local.success + ready.push.share.success + ready.push.extrn.success;
     134                        sstr | "- totals   : " | eng3(totalR) | "run," | eng3(totalS) | "schd (" | eng3(ready.push.extrn.success) | "ext," | eng3(ready.threads.migration) | "mig)";
     135
     136                        double push_len = ((double)ready.push.local.attempt + ready.push.share.attempt + ready.push.extrn.attempt) / totalS;
    124137                        double sLcl_len = ready.push.local.success ? ((double)ready.push.local.attempt) / ready.push.local.success : 0;
    125138                        double sOth_len = ready.push.share.success ? ((double)ready.push.share.attempt) / ready.push.share.success : 0;
    126139                        double sExt_len = ready.push.extrn.success ? ((double)ready.push.extrn.attempt) / ready.push.extrn.success : 0;
    127 
    128                         uint64_t total = ready.pop.local.success + ready.pop.help.success + ready.pop.steal.success + ready.pop.search.success;
    129                         double rLcl_pc = (100.0 * (double)ready.pop.local .success) / total;
    130                         double rHlp_pc = (100.0 * (double)ready.pop.help  .success) / total;
    131                         double rStl_pc = (100.0 * (double)ready.pop.steal .success) / total;
    132                         double rSch_pc = (100.0 * (double)ready.pop.search.success) / total;
    133 
    134                         __cfaabi_bits_print_safe( STDOUT_FILENO,
    135                                 "----- %s \"%s\" (%p) - Ready Q Stats -----\n"
    136                                 "- totals   : %'3" PRIu64 " run, %'3" PRIu64 " schd (%'" PRIu64 "ext, %'" PRIu64 "mig, %'" PRId64 " )\n"
    137                                 "- push avg : %'3.0lf (l: %'3.2lf/%'" PRIu64 ", s: %'3.2lf/%'" PRIu64 ", e: %'3.2lf : %'" PRIu64 "e)\n"
    138                                 "- local    : %'3.0lf%%: %'3" PRIu64 " (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"
    139                                 "- help     : %'3.0lf%%: %'3" PRIu64 " (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"
    140                                 "- steal    : %'3.0lf%%: %'3" PRIu64 " (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"
    141                                 "- search   : %'3.0lf%%: %'3" PRIu64 " (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"
    142                                 "- Idle Slp : %'3" PRIu64 "h, %'3" PRIu64 "c, %'3" PRIu64 "w, %'3" PRIu64 "e\n"
    143                                 "\n"
    144                                 , type, name, id
    145                                 , total
    146                                 , ready.push.local.success + ready.push.share.success + ready.push.extrn.success
    147                                 , ready.push.extrn.success, ready.threads.migration, ready.threads.threads
    148                                 , push_len, sLcl_len, ready.push.local.attempt, sOth_len, ready.push.share.attempt, sExt_len, ready.push.extrn.attempt
    149                                 , rLcl_pc, ready.pop.local .success, ready.pop.local .attempt, ready.pop.local .espec, ready.pop.local .elock, ready.pop.local .eempty
    150                                 , rHlp_pc, ready.pop.help  .success, ready.pop.help  .attempt, ready.pop.help  .espec, ready.pop.help  .elock, ready.pop.help  .eempty
    151                                 , rStl_pc, ready.pop.steal .success, ready.pop.steal .attempt, ready.pop.steal .espec, ready.pop.steal .elock, ready.pop.steal .eempty
    152                                 , rSch_pc, ready.pop.search.success, ready.pop.search.attempt, ready.pop.search.espec, ready.pop.search.elock, ready.pop.search.eempty
    153                                 , ready.sleep.halts, ready.sleep.cancels, ready.sleep.wakes, ready.sleep.exits
    154                         );
     140                        sstr | "- push avg : " | ws(3, 3, push_len)
     141                             | "- l: " | eng3(ready.push.local.attempt) | " (" | ws(3, 3, sLcl_len) | ")"
     142                             | ", s: " | eng3(ready.push.share.attempt) | " (" | ws(3, 3, sOth_len) | ")"
     143                             | ", e: " | eng3(ready.push.extrn.attempt) | " (" | ws(3, 3, sExt_len) | ")";
     144
     145                        double rLcl_pc = (100.0 * (double)ready.pop.local .success) / totalR;
     146                        sstr | "- local    : " | eng3(ready.pop.local .success) | "-"| ws(3, 3, rLcl_pc) | '%'
     147                             | " (" | eng3(ready.pop.local .attempt) | " try," | eng3(ready.pop.local .espec) | " spc," | eng3(ready.pop.local .elock) | " lck," | eng3(ready.pop.local .eempty) | " ept)";
     148                        double rHlp_pc = (100.0 * (double)ready.pop.help  .success) / totalR;
     149                        sstr | "- help     : " | eng3(ready.pop.help  .success) | "-"| ws(3, 3, rHlp_pc) | '%'
     150                             | " (" | eng3(ready.pop.help  .attempt) | " try," | eng3(ready.pop.help  .espec) | " spc," | eng3(ready.pop.help  .elock) | " lck," | eng3(ready.pop.help  .eempty) | " ept)";
     151                        double rStl_pc = (100.0 * (double)ready.pop.steal .success) / totalR;
     152                        sstr | "- steal    : " | eng3(ready.pop.steal .success) | "-"| ws(3, 3, rStl_pc) | '%'
     153                             | " (" | eng3(ready.pop.steal .attempt) | " try," | eng3(ready.pop.steal .espec) | " spc," | eng3(ready.pop.steal .elock) | " lck," | eng3(ready.pop.steal .eempty) | " ept)";
     154                        double rSch_pc = (100.0 * (double)ready.pop.search.success) / totalR;
     155                        sstr | "- search   : " | eng3(ready.pop.search.success) | "-"| ws(3, 3, rSch_pc) | '%'
     156                             | " (" | eng3(ready.pop.search.attempt) | " try," | eng3(ready.pop.search.espec) | " spc," | eng3(ready.pop.search.elock) | " lck," | eng3(ready.pop.search.eempty) | " ept)";
     157
     158                        sstr | "- Idle Slp : " | eng3(ready.sleep.halts) | "halt," | eng3(ready.sleep.cancels) | "cancel," | eng3(ready.sleep.wakes) | "wake," | eng3(ready.sleep.exits) | "exit";
     159                        sstr | nl;
    155160                }
    156161
    157162                #if defined(CFA_HAVE_LINUX_IO_URING_H)
    158163                        if( flags & CFA_STATS_IO ) {
     164                                sstr | "----- " | type | "\"" | name | "\" (" | "" | id | "" | ") - I/O Stats -----";
     165
    159166                                uint64_t total_allocs = io.alloc.fast + io.alloc.slow;
    160                                 double avgfasta = ((double)io.alloc.fast) / total_allocs;
     167                                double avgfasta = (100.0 * (double)io.alloc.fast) / total_allocs;
     168                                sstr | "- total allocations : " | eng3(io.alloc.fast) | "fast," | eng3(io.alloc.slow) | "slow (" | ws(3, 3, avgfasta) | "%)";
     169                                sstr | "-     failures      : " | eng3(io.alloc.fail) | "oom, " | eng3(io.alloc.revoke) | "rvk, " | eng3(io.alloc.block) | "blk";
    161170
    162171                                uint64_t total_submits = io.submit.fast + io.submit.slow;
    163                                 double avgfasts = ((double)io.submit.fast) / total_submits;
     172                                double avgfasts = (100.0 * (double)io.submit.fast) / total_submits;
     173                                sstr | "- total submits     : " | eng3(io.submit.fast) | "fast," | eng3(io.submit.slow) | "slow (" | ws(3, 3, avgfasts) | "%)";
     174                                sstr | "- flush external    : " | eng3(io.flush.external);
     175
     176                                sstr | "- io_uring_enter    : " | eng3(io.calls.flush) | " (" | eng3(io.calls.drain) | ", " | eng3(io.calls.errors.busy) | " EBUSY)";
    164177
    165178                                double avgsubs = ((double)io.calls.submitted) / io.calls.flush;
    166179                                double avgcomp = ((double)io.calls.completed) / io.calls.drain;
    167 
    168                                 __cfaabi_bits_print_safe( STDOUT_FILENO,
    169                                         "----- %s \"%s\" (%p) - I/O Stats -----\n"
    170                                         "- total allocations : %'" PRIu64 "f, %'" PRIu64 "s (%'2.2lff) \n"
    171                                         "-     failures      : %'" PRIu64 "oom, %'" PRIu64 "rvk, %'" PRIu64 "blk\n"
    172                                         "- total submits     : %'" PRIu64 "f, %'" PRIu64 "s (%'2.2lf) \n"
    173                                         "- flush external    : %'" PRIu64 "\n"
    174                                         "- io_uring_enter    : %'" PRIu64 " (%'" PRIu64 ", %'" PRIu64 " EBUSY)\n"
    175                                         "-     submits       : %'" PRIu64 " (%'.2lf) \n"
    176                                         "-     completes     : %'" PRIu64 " (%'.2lf) \n"
    177                                         "- poller sleeping   : %'" PRIu64 "\n"
    178                                         "\n"
    179                                         , type,  name, id
    180                                         , io.alloc.fast, io.alloc.slow, avgfasta
    181                                         , io.alloc.fail, io.alloc.revoke, io.alloc.block
    182                                         , io.submit.fast, io.submit.slow, avgfasts
    183                                         , io.flush.external
    184                                         , io.calls.flush, io.calls.drain, io.calls.errors.busy
    185                                         , io.calls.submitted, avgsubs
    186                                         , io.calls.completed, avgcomp
    187                                         , io.poller.sleeps
    188                                 );
     180                                sstr | "-     submits       : " | eng3(io.calls.submitted) | "(" | ws(3, 3, avgsubs) | "/flush)";
     181                                sstr | "-     completes     : " | eng3(io.calls.completed) | "(" | ws(3, 3, avgcomp) | "/drain)";
     182
     183                                sstr | "- poller sleeping   : " | eng3(io.poller.sleeps);
     184                                sstr | nl;
    189185                        }
    190186                #endif
     187
     188                if(flags) write( sstr, stdout );
    191189        }
    192190
  • libcfa/src/concurrency/thread.cfa

    r9b71679 raec68b6  
    134134        /* paranoid */ verify( this_thrd->context.SP );
    135135
    136         __schedule_thread( this_thrd );
    137         enable_interrupts( __cfaabi_dbg_ctx );
     136        schedule_thread$( this_thrd );
     137        enable_interrupts();
    138138}
    139139
     
    168168        disable_interrupts();
    169169        uint64_t ret = __tls_rand();
    170         enable_interrupts( __cfaabi_dbg_ctx );
     170        enable_interrupts();
    171171        return ret;
    172172}
  • libcfa/src/startup.cfa

    r9b71679 raec68b6  
    3939
    4040    void disable_interrupts() __attribute__(( weak )) {}
    41     void enable_interrupts_noPoll() __attribute__(( weak )) {}
     41    void enable_interrupts() __attribute__(( weak )) {}
    4242} // extern "C"
    4343
Note: See TracChangeset for help on using the changeset viewer.