Changes in / [aec68b6:9b71679]
- Location:
- libcfa/src
- Files:
-
- 15 edited
-
bits/locks.hfa (modified) (3 diffs)
-
concurrency/alarm.cfa (modified) (2 diffs)
-
concurrency/clib/cfathread.cfa (modified) (1 diff)
-
concurrency/future.hfa (modified) (2 diffs)
-
concurrency/invoke.c (modified) (2 diffs)
-
concurrency/io.cfa (modified) (7 diffs)
-
concurrency/io/types.hfa (modified) (1 diff)
-
concurrency/kernel.cfa (modified) (12 diffs)
-
concurrency/kernel/fwd.hfa (modified) (6 diffs)
-
concurrency/kernel/startup.cfa (modified) (6 diffs)
-
concurrency/kernel_private.hfa (modified) (1 diff)
-
concurrency/preemption.cfa (modified) (2 diffs)
-
concurrency/stats.cfa (modified) (2 diffs)
-
concurrency/thread.cfa (modified) (2 diffs)
-
startup.cfa (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/bits/locks.hfa
raec68b6 r9b71679 37 37 extern "C" { 38 38 extern void disable_interrupts() OPTIONAL_THREAD; 39 extern void enable_interrupts ( bool poll = true) OPTIONAL_THREAD;39 extern void enable_interrupts_noPoll() OPTIONAL_THREAD; 40 40 41 41 #ifdef __CFA_DEBUG__ … … 57 57 __cfaabi_dbg_record_lock( this, caller ); 58 58 } else { 59 enable_interrupts ( false);59 enable_interrupts_noPoll(); 60 60 } 61 61 return result; … … 90 90 static inline void unlock( __spinlock_t & this ) { 91 91 __atomic_clear( &this.lock, __ATOMIC_RELEASE ); 92 enable_interrupts ( false);92 enable_interrupts_noPoll(); 93 93 } 94 94 #endif -
libcfa/src/concurrency/alarm.cfa
raec68b6 r9b71679 116 116 unlock( event_kernel->lock ); 117 117 this->set = true; 118 enable_interrupts( );118 enable_interrupts( __cfaabi_dbg_ctx ); 119 119 } 120 120 … … 127 127 } 128 128 unlock( event_kernel->lock ); 129 enable_interrupts( );129 enable_interrupts( __cfaabi_dbg_ctx ); 130 130 this->set = false; 131 131 } -
libcfa/src/concurrency/clib/cfathread.cfa
raec68b6 r9b71679 117 117 118 118 this_thrd->state = Ready; 119 enable_interrupts( );119 enable_interrupts( __cfaabi_dbg_ctx ); 120 120 } 121 121 -
libcfa/src/concurrency/future.hfa
raec68b6 r9b71679 37 37 38 38 // Fulfil the future, returns whether or not someone was unblocked 39 $thread *fulfil( future(T) & this, T result ) {39 bool fulfil( future(T) & this, T result ) { 40 40 this.result = result; 41 41 return fulfil( (future_t&)this ); … … 96 96 bool fulfil( multi_future(T) & this, T result ) { 97 97 this.result = result; 98 return fulfil( (future_t&)this ) != 0p;98 return fulfil( (future_t&)this ); 99 99 } 100 100 -
libcfa/src/concurrency/invoke.c
raec68b6 r9b71679 34 34 35 35 extern void disable_interrupts() OPTIONAL_THREAD; 36 extern void enable_interrupts( _ Bool poll);36 extern void enable_interrupts( __cfaabi_dbg_ctx_param ); 37 37 38 38 void __cfactx_invoke_coroutine( … … 82 82 ) { 83 83 // Officially start the thread by enabling preemption 84 enable_interrupts( true);84 enable_interrupts( __cfaabi_dbg_ctx ); 85 85 86 86 // Call the main of the thread -
libcfa/src/concurrency/io.cfa
raec68b6 r9b71679 90 90 static inline __u32 __release_sqes( struct $io_context & ); 91 91 92 bool__cfa_io_drain( processor * proc ) {92 void __cfa_io_drain( processor * proc ) { 93 93 /* paranoid */ verify( ! __preemption_enabled() ); 94 94 /* paranoid */ verify( proc ); … … 104 104 __STATS__( false, io.calls.drain++; io.calls.completed += count; ) 105 105 106 if(count == 0) return false;107 108 106 for(i; count) { 109 107 unsigned idx = (head + i) & mask; … … 126 124 /* paranoid */ verify( ! __preemption_enabled() ); 127 125 128 return true;126 return; 129 127 } 130 128 … … 244 242 // Allocation was successful 245 243 __STATS__( true, io.alloc.fast += 1; ) 246 enable_interrupts( );244 enable_interrupts( __cfaabi_dbg_ctx ); 247 245 248 246 __cfadbg_print_safe(io, "Kernel I/O : fast allocation successful from ring %d\n", ctx->fd); … … 256 254 // Fast path failed, fallback on arbitration 257 255 __STATS__( true, io.alloc.slow += 1; ) 258 enable_interrupts( );256 enable_interrupts( __cfaabi_dbg_ctx ); 259 257 260 258 $io_arbiter * ioarb = proc->cltr->io.arbiter; … … 314 312 // Mark the instance as no longer in-use, re-enable interrupts and return 315 313 __STATS__( true, io.submit.fast += 1; ) 316 enable_interrupts( );314 enable_interrupts( __cfaabi_dbg_ctx ); 317 315 318 316 __cfadbg_print_safe(io, "Kernel I/O : submitted on fast path\n"); … … 322 320 // Fast path failed, fallback on arbitration 323 321 __STATS__( true, io.submit.slow += 1; ) 324 enable_interrupts( );322 enable_interrupts( __cfaabi_dbg_ctx ); 325 323 326 324 __cfadbg_print_safe(io, "Kernel I/O : falling back on arbiter for submission\n"); -
libcfa/src/concurrency/io/types.hfa
raec68b6 r9b71679 179 179 180 180 static inline { 181 $thread * fulfil( io_future_t & this, __s32 result, bool do_unpark = true) {181 bool fulfil( io_future_t & this, __s32 result ) { 182 182 this.result = result; 183 return fulfil(this.self , do_unpark);183 return fulfil(this.self); 184 184 } 185 185 -
libcfa/src/concurrency/kernel.cfa
raec68b6 r9b71679 110 110 static $thread * __next_thread(cluster * this); 111 111 static $thread * __next_thread_slow(cluster * this); 112 static inline bool __must_unpark( $thread * thrd ) __attribute((nonnull(1)));113 112 static void __run_thread(processor * this, $thread * dst); 114 113 static void __wake_one(cluster * cltr); … … 119 118 120 119 extern void __cfa_io_start( processor * ); 121 extern bool__cfa_io_drain( processor * );120 extern void __cfa_io_drain( processor * ); 122 121 extern void __cfa_io_flush( processor * ); 123 122 extern void __cfa_io_stop ( processor * ); 124 static inline bool__maybe_io_drain( processor * );123 static inline void __maybe_io_drain( processor * ); 125 124 126 125 extern void __disable_interrupts_hard(); 127 126 extern void __enable_interrupts_hard(); 128 129 static inline void __disable_interrupts_checked() {130 /* paranoid */ verify( __preemption_enabled() );131 disable_interrupts();132 /* paranoid */ verify( ! __preemption_enabled() );133 }134 135 static inline void __enable_interrupts_checked( bool poll = true ) {136 /* paranoid */ verify( ! __preemption_enabled() );137 enable_interrupts( poll );138 /* paranoid */ verify( __preemption_enabled() );139 }140 127 141 128 //============================================================================================= … … 349 336 if(unlikely(thrd_dst->preempted != __NO_PREEMPTION)) { 350 337 // The thread was preempted, reschedule it and reset the flag 351 schedule_thread$( thrd_dst );338 __schedule_thread( thrd_dst ); 352 339 break RUNNING; 353 340 } … … 439 426 /* paranoid */ verify( ! __preemption_enabled() ); 440 427 /* paranoid */ verify( kernelTLS().this_proc_id ); 441 /* paranoid */ verify( ready_schedule_islocked());442 428 /* paranoid */ verify( thrd ); 443 429 /* paranoid */ verify( thrd->state != Halted ); … … 458 444 struct cluster * cl = thrd->curr_cluster; 459 445 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 ); 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(); 468 455 469 456 #if !defined(__CFA_NO_STATISTICS__) … … 478 465 #endif 479 466 480 /* paranoid */ verify( ready_schedule_islocked()); 481 /* paranoid */ verify( ! __preemption_enabled() ); 482 } 483 484 void schedule_thread$( $thread * thrd ) { 485 ready_schedule_lock(); 486 __schedule_thread( thrd ); 487 ready_schedule_unlock(); 467 /* paranoid */ verify( ! __preemption_enabled() ); 488 468 } 489 469 … … 516 496 } 517 497 518 static inline bool __must_unpark( $thread * thrd ) { 498 void unpark( $thread * thrd ) { 499 if( !thrd ) return; 500 519 501 int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST); 520 502 switch(old_ticket) { 521 503 case TICKET_RUNNING: 522 504 // Wake won the race, the thread will reschedule/rerun itself 523 return false;505 break; 524 506 case TICKET_BLOCKED: 525 507 /* paranoid */ verify( ! thrd->preempted != __NO_PREEMPTION ); 526 508 /* paranoid */ verify( thrd->state == Blocked ); 527 return true; 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; 528 526 default: 529 527 // This makes no sense, something is wrong abort … … 532 530 } 533 531 534 void 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 545 532 void park( void ) { 546 __disable_interrupts_checked(); 547 /* paranoid */ verify( kernelTLS().this_thread->preempted == __NO_PREEMPTION ); 548 returnToKernel(); 549 __enable_interrupts_checked(); 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() ); 550 543 551 544 } … … 587 580 // KERNEL ONLY 588 581 bool force_yield( __Preemption_Reason reason ) { 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 ); 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 604 604 return preempted; 605 605 } … … 646 646 __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this); 647 647 648 __disable_interrupts_checked();648 disable_interrupts(); 649 649 /* paranoid */ verify( ! __preemption_enabled() ); 650 650 eventfd_t val; 651 651 val = 1; 652 652 eventfd_write( this->idle, val ); 653 __enable_interrupts_checked();653 enable_interrupts( __cfaabi_dbg_ctx ); 654 654 } 655 655 … … 743 743 #endif 744 744 745 static inline bool__maybe_io_drain( processor * proc ) {745 static inline void __maybe_io_drain( processor * proc ) { 746 746 #if defined(CFA_HAVE_LINUX_IO_URING_H) 747 747 __cfadbg_print_safe(runtime_core, "Kernel : core %p checking io for ring %d\n", proc, proc->io.ctx->fd); … … 751 751 unsigned head = *ctx->cq.head; 752 752 unsigned tail = *ctx->cq.tail; 753 if(head == tail) return false; 754 return __cfa_io_drain( proc ); 753 if(head != tail) __cfa_io_drain( proc ); 755 754 #endif 756 755 } -
libcfa/src/concurrency/kernel/fwd.hfa
raec68b6 r9b71679 108 108 109 109 extern void disable_interrupts(); 110 extern void enable_interrupts( bool poll = false ); 110 extern void enable_interrupts_noPoll(); 111 extern void enable_interrupts( __cfaabi_dbg_ctx_param ); 111 112 112 113 extern "Cforall" { … … 219 220 // Mark as fulfilled, wake thread if needed 220 221 // return true if a thread was unparked 221 $thread * post(oneshot & this, bool do_unpark = true) {222 bool post(oneshot & this) { 222 223 struct $thread * got = __atomic_exchange_n( &this.ptr, 1p, __ATOMIC_SEQ_CST); 223 if( got == 0p ) return 0p;224 if(do_unpark)unpark( got );225 return got;224 if( got == 0p ) return false; 225 unpark( got ); 226 return true; 226 227 } 227 228 } … … 335 336 // from the server side, mark the future as fulfilled 336 337 // delete it if needed 337 $thread * fulfil( future_t & this, bool do_unpark = true) {338 bool fulfil( future_t & this ) { 338 339 for() { 339 340 struct oneshot * expected = this.ptr; … … 343 344 #pragma GCC diagnostic ignored "-Wfree-nonheap-object" 344 345 #endif 345 if( expected == 3p ) { free( &this ); return 0p; }346 if( expected == 3p ) { free( &this ); return false; } 346 347 #if defined(__GNUC__) && __GNUC__ >= 7 347 348 #pragma GCC diagnostic pop … … 355 356 struct oneshot * want = expected == 0p ? 1p : 2p; 356 357 if(__atomic_compare_exchange_n(&this.ptr, &expected, want, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 357 if( expected == 0p ) { /* paranoid */ verify( this.ptr == 1p); return 0p; }358 $thread * ret = post( *expected, do_unpark);358 if( expected == 0p ) { /* paranoid */ verify( this.ptr == 1p); return false; } 359 bool ret = post( *expected ); 359 360 __atomic_store_n( &this.ptr, 1p, __ATOMIC_SEQ_CST); 360 361 return ret; … … 402 403 __VA_ARGS__ \ 403 404 } \ 404 if( !(in_kernel) ) enable_interrupts( ); \405 if( !(in_kernel) ) enable_interrupts( __cfaabi_dbg_ctx ); \ 405 406 } 406 407 #else -
libcfa/src/concurrency/kernel/startup.cfa
raec68b6 r9b71679 225 225 // Add the main thread to the ready queue 226 226 // 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); 228 228 229 229 // SKULLDUGGERY: Force a context switch to the main processor to set the main thread's context to the current UNIX … … 238 238 239 239 /* paranoid */ verify( ! __preemption_enabled() ); 240 enable_interrupts( );240 enable_interrupts( __cfaabi_dbg_ctx ); 241 241 /* paranoid */ verify( __preemption_enabled() ); 242 242 … … 530 530 disable_interrupts(); 531 531 init( this, name, _cltr, initT ); 532 enable_interrupts( );532 enable_interrupts( __cfaabi_dbg_ctx ); 533 533 534 534 __cfadbg_print_safe(runtime_core, "Kernel : Starting core %p\n", &this); … … 557 557 disable_interrupts(); 558 558 deinit( this ); 559 enable_interrupts( );559 enable_interrupts( __cfaabi_dbg_ctx ); 560 560 } 561 561 … … 595 595 // Unlock the RWlock 596 596 ready_mutate_unlock( last_size ); 597 enable_interrupts ( false); // Don't poll, could be in main cluster597 enable_interrupts_noPoll(); // Don't poll, could be in main cluster 598 598 } 599 599 … … 610 610 // Unlock the RWlock 611 611 ready_mutate_unlock( last_size ); 612 enable_interrupts ( false); // Don't poll, could be in main cluster612 enable_interrupts_noPoll(); // Don't poll, could be in main cluster 613 613 614 614 #if !defined(__CFA_NO_STATISTICS__) -
libcfa/src/concurrency/kernel_private.hfa
raec68b6 r9b71679 29 29 extern "C" { 30 30 void disable_interrupts() OPTIONAL_THREAD; 31 void enable_interrupts( bool poll = true ); 32 } 33 34 void schedule_thread$( $thread * ) __attribute__((nonnull (1))); 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 ; 35 40 36 41 extern bool __preemption_enabled(); -
libcfa/src/concurrency/preemption.cfa
raec68b6 r9b71679 315 315 // Enable interrupts by decrementing the counter 316 316 // If counter reaches 0, execute any pending __cfactx_switch 317 void enable_interrupts( bool poll) {317 void enable_interrupts( __cfaabi_dbg_ctx_param ) { 318 318 // Cache the processor now since interrupts can start happening after the atomic store 319 319 processor * proc = __cfaabi_tls.this_processor; 320 /* paranoid */ verify( !poll ||proc );320 /* paranoid */ verify( proc ); 321 321 322 322 with( __cfaabi_tls.preemption_state ){ … … 340 340 // Signal the compiler that a fence is needed but only for signal handlers 341 341 __atomic_signal_fence(__ATOMIC_RELEASE); 342 if( p oll && proc->pending_preemption ) {342 if( proc->pending_preemption ) { 343 343 proc->pending_preemption = false; 344 344 force_yield( __POLL_PREEMPTION ); 345 345 } 346 346 } 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); 347 371 } 348 372 } -
libcfa/src/concurrency/stats.cfa
raec68b6 r9b71679 7 7 #include "bits/locks.hfa" 8 8 #include "stats.hfa" 9 #include "strstream.hfa"10 9 11 10 #if !defined(__CFA_NO_STATISTICS__) … … 119 118 } 120 119 121 #define eng3(X) (ws(3, 3, unit(eng( X ))))122 123 120 void __print_stats( struct __stats_t * stats, int flags, const char * type, const char * name, void * id ) with( *stats ) { 124 121 125 char buf[1024];126 strstream sstr = { buf, 1024 };127 128 122 if( flags & CFA_STATS_READY_Q ) { 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; 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); 137 124 double sLcl_len = ready.push.local.success ? ((double)ready.push.local.attempt) / ready.push.local.success : 0; 138 125 double sOth_len = ready.push.share.success ? ((double)ready.push.share.attempt) / ready.push.share.success : 0; 139 126 double sExt_len = ready.push.extrn.success ? ((double)ready.push.extrn.attempt) / ready.push.extrn.success : 0; 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; 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 ); 160 155 } 161 156 162 157 #if defined(CFA_HAVE_LINUX_IO_URING_H) 163 158 if( flags & CFA_STATS_IO ) { 164 sstr | "----- " | type | "\"" | name | "\" (" | "" | id | "" | ") - I/O Stats -----";165 166 159 uint64_t total_allocs = io.alloc.fast + io.alloc.slow; 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"; 160 double avgfasta = ((double)io.alloc.fast) / total_allocs; 170 161 171 162 uint64_t total_submits = io.submit.fast + io.submit.slow; 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)"; 163 double avgfasts = ((double)io.submit.fast) / total_submits; 177 164 178 165 double avgsubs = ((double)io.calls.submitted) / io.calls.flush; 179 166 double avgcomp = ((double)io.calls.completed) / io.calls.drain; 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; 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 ); 185 189 } 186 190 #endif 187 188 if(flags) write( sstr, stdout );189 191 } 190 192 -
libcfa/src/concurrency/thread.cfa
raec68b6 r9b71679 134 134 /* paranoid */ verify( this_thrd->context.SP ); 135 135 136 schedule_thread$( this_thrd );137 enable_interrupts( );136 __schedule_thread( this_thrd ); 137 enable_interrupts( __cfaabi_dbg_ctx ); 138 138 } 139 139 … … 168 168 disable_interrupts(); 169 169 uint64_t ret = __tls_rand(); 170 enable_interrupts( );170 enable_interrupts( __cfaabi_dbg_ctx ); 171 171 return ret; 172 172 } -
libcfa/src/startup.cfa
raec68b6 r9b71679 39 39 40 40 void disable_interrupts() __attribute__(( weak )) {} 41 void enable_interrupts () __attribute__(( weak )) {}41 void enable_interrupts_noPoll() __attribute__(( weak )) {} 42 42 } // extern "C" 43 43
Note:
See TracChangeset
for help on using the changeset viewer.