- File:
-
- 1 edited
-
libcfa/src/concurrency/kernel.cfa (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel.cfa
r431cd4f r254ad1b 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))); 112 113 static void __run_thread(processor * this, $thread * dst); 113 114 static void __wake_one(cluster * cltr); … … 118 119 119 120 extern void __cfa_io_start( processor * ); 120 extern void__cfa_io_drain( processor * );121 extern bool __cfa_io_drain( processor * ); 121 122 extern void __cfa_io_flush( processor * ); 122 123 extern void __cfa_io_stop ( processor * ); 123 static inline void__maybe_io_drain( processor * );124 static inline bool __maybe_io_drain( processor * ); 124 125 125 126 extern void __disable_interrupts_hard(); 126 127 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 } 127 140 128 141 //============================================================================================= … … 336 349 if(unlikely(thrd_dst->preempted != __NO_PREEMPTION)) { 337 350 // The thread was preempted, reschedule it and reset the flag 338 __schedule_thread( thrd_dst );351 schedule_thread$( thrd_dst ); 339 352 break RUNNING; 340 353 } … … 426 439 /* paranoid */ verify( ! __preemption_enabled() ); 427 440 /* paranoid */ verify( kernelTLS().this_proc_id ); 441 /* paranoid */ verify( ready_schedule_islocked()); 428 442 /* paranoid */ verify( thrd ); 429 443 /* paranoid */ verify( thrd->state != Halted ); … … 444 458 struct cluster * cl = thrd->curr_cluster; 445 459 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 ); 455 468 456 469 #if !defined(__CFA_NO_STATISTICS__) … … 465 478 #endif 466 479 467 /* paranoid */ verify( ! __preemption_enabled() ); 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(); 468 488 } 469 489 … … 496 516 } 497 517 498 void unpark( $thread * thrd ) { 499 if( !thrd ) return; 500 518 static inline bool __must_unpark( $thread * thrd ) { 501 519 int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST); 502 520 switch(old_ticket) { 503 521 case TICKET_RUNNING: 504 522 // Wake won the race, the thread will reschedule/rerun itself 505 break;523 return false; 506 524 case TICKET_BLOCKED: 507 525 /* paranoid */ verify( ! thrd->preempted != __NO_PREEMPTION ); 508 526 /* 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; 526 528 default: 527 529 // This makes no sense, something is wrong abort … … 530 532 } 531 533 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 532 545 void 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(); 543 550 544 551 } … … 580 587 // KERNEL ONLY 581 588 bool 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 ); 604 604 return preempted; 605 605 } … … 646 646 __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this); 647 647 648 disable_interrupts();648 __disable_interrupts_checked(); 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( __cfaabi_dbg_ctx);653 __enable_interrupts_checked(); 654 654 } 655 655 … … 743 743 #endif 744 744 745 static inline void__maybe_io_drain( processor * proc ) {745 static inline bool __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) __cfa_io_drain( proc ); 753 if(head == tail) return false; 754 return __cfa_io_drain( proc ); 754 755 #endif 755 756 }
Note:
See TracChangeset
for help on using the changeset viewer.