Changeset cfff639 for libcfa/src/concurrency/kernel.cfa
- Timestamp:
- Apr 24, 2021, 7:45:02 PM (3 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- fb0be05
- Parents:
- 89eff25 (diff), 254ad1b (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel.cfa
r89eff25 rcfff639 115 115 static $thread * __next_thread(cluster * this); 116 116 static $thread * __next_thread_slow(cluster * this); 117 static inline bool __must_unpark( $thread * thrd ) __attribute((nonnull(1))); 117 118 static void __run_thread(processor * this, $thread * dst); 118 119 static void __wake_one(cluster * cltr); … … 130 131 extern void __disable_interrupts_hard(); 131 132 extern void __enable_interrupts_hard(); 133 134 static inline void __disable_interrupts_checked() { 135 /* paranoid */ verify( __preemption_enabled() ); 136 disable_interrupts(); 137 /* paranoid */ verify( ! __preemption_enabled() ); 138 } 139 140 static inline void __enable_interrupts_checked( bool poll = true ) { 141 /* paranoid */ verify( ! __preemption_enabled() ); 142 enable_interrupts( poll ); 143 /* paranoid */ verify( __preemption_enabled() ); 144 } 132 145 133 146 //============================================================================================= … … 452 465 if(unlikely(thrd_dst->preempted != __NO_PREEMPTION)) { 453 466 // The thread was preempted, reschedule it and reset the flag 454 __schedule_thread( thrd_dst );467 schedule_thread$( thrd_dst ); 455 468 break RUNNING; 456 469 } … … 541 554 /* paranoid */ verify( ! __preemption_enabled() ); 542 555 /* paranoid */ verify( kernelTLS().this_proc_id ); 556 /* paranoid */ verify( ready_schedule_islocked()); 543 557 /* paranoid */ verify( thrd ); 544 558 /* paranoid */ verify( thrd->state != Halted ); … … 560 574 __STATS(bool outside = thrd->last_proc && thrd->last_proc != kernelTLS().this_processor; ) 561 575 562 ready_schedule_lock(); 563 // push the thread to the cluster ready-queue 564 push( cl, thrd ); 565 566 // variable thrd is no longer safe to use 567 568 // wake the cluster using the save variable. 569 __wake_one( cl ); 570 ready_schedule_unlock(); 576 // push the thread to the cluster ready-queue 577 push( cl, thrd ); 578 579 // variable thrd is no longer safe to use 580 thrd = 0xdeaddeaddeaddeadp; 581 582 // wake the cluster using the save variable. 583 __wake_one( cl ); 571 584 572 585 #if !defined(__CFA_NO_STATISTICS__) … … 585 598 #endif 586 599 587 /* paranoid */ verify( ! __preemption_enabled() ); 600 /* paranoid */ verify( ready_schedule_islocked()); 601 /* paranoid */ verify( ! __preemption_enabled() ); 602 } 603 604 void schedule_thread$( $thread * thrd ) { 605 ready_schedule_lock(); 606 __schedule_thread( thrd ); 607 ready_schedule_unlock(); 588 608 } 589 609 … … 623 643 } 624 644 625 void unpark( $thread * thrd ) { 626 if( !thrd ) return; 627 645 static inline bool __must_unpark( $thread * thrd ) { 628 646 int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST); 629 647 switch(old_ticket) { 630 648 case TICKET_RUNNING: 631 649 // Wake won the race, the thread will reschedule/rerun itself 632 break;650 return false; 633 651 case TICKET_BLOCKED: 634 652 /* paranoid */ verify( ! thrd->preempted != __NO_PREEMPTION ); 635 653 /* paranoid */ verify( thrd->state == Blocked ); 636 637 { 638 /* paranoid */ verify( publicTLS_get(this_proc_id) ); 639 disable_interrupts(); 640 641 /* paranoid */ verify( ! __preemption_enabled() ); 642 643 // Wake lost the race, 644 __schedule_thread( thrd ); 645 646 /* paranoid */ verify( ! __preemption_enabled() ); 647 648 enable_interrupts_noPoll(); 649 /* paranoid */ verify( publicTLS_get(this_proc_id) ); 650 } 651 652 break; 654 return true; 653 655 default: 654 656 // This makes no sense, something is wrong abort … … 657 659 } 658 660 661 void unpark( $thread * thrd ) { 662 if( !thrd ) return; 663 664 if(__must_unpark(thrd)) { 665 disable_interrupts(); 666 // Wake lost the race, 667 schedule_thread$( thrd ); 668 enable_interrupts(false); 669 } 670 } 671 659 672 void park( void ) { 660 /* paranoid */ verify( __preemption_enabled() ); 661 disable_interrupts(); 662 /* paranoid */ verify( ! __preemption_enabled() ); 663 /* paranoid */ verify( kernelTLS().this_thread->preempted == __NO_PREEMPTION ); 664 665 returnToKernel(); 666 667 /* paranoid */ verify( ! __preemption_enabled() ); 668 enable_interrupts( __cfaabi_dbg_ctx ); 669 /* paranoid */ verify( __preemption_enabled() ); 673 __disable_interrupts_checked(); 674 /* paranoid */ verify( kernelTLS().this_thread->preempted == __NO_PREEMPTION ); 675 returnToKernel(); 676 __enable_interrupts_checked(); 670 677 671 678 } … … 707 714 // KERNEL ONLY 708 715 bool force_yield( __Preemption_Reason reason ) { 709 /* paranoid */ verify( __preemption_enabled() ); 710 disable_interrupts(); 711 /* paranoid */ verify( ! __preemption_enabled() ); 712 713 $thread * thrd = kernelTLS().this_thread; 714 /* paranoid */ verify(thrd->state == Active); 715 716 // SKULLDUGGERY: It is possible that we are preempting this thread just before 717 // it was going to park itself. If that is the case and it is already using the 718 // intrusive fields then we can't use them to preempt the thread 719 // If that is the case, abandon the preemption. 720 bool preempted = false; 721 if(thrd->link.next == 0p) { 722 preempted = true; 723 thrd->preempted = reason; 724 returnToKernel(); 725 } 726 727 /* paranoid */ verify( ! __preemption_enabled() ); 728 enable_interrupts_noPoll(); 729 /* paranoid */ verify( __preemption_enabled() ); 730 716 __disable_interrupts_checked(); 717 $thread * thrd = kernelTLS().this_thread; 718 /* paranoid */ verify(thrd->state == Active); 719 720 // SKULLDUGGERY: It is possible that we are preempting this thread just before 721 // it was going to park itself. If that is the case and it is already using the 722 // intrusive fields then we can't use them to preempt the thread 723 // If that is the case, abandon the preemption. 724 bool preempted = false; 725 if(thrd->link.next == 0p) { 726 preempted = true; 727 thrd->preempted = reason; 728 returnToKernel(); 729 } 730 __enable_interrupts_checked( false ); 731 731 return preempted; 732 732 } … … 773 773 __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this); 774 774 775 disable_interrupts();775 __disable_interrupts_checked(); 776 776 /* paranoid */ verify( ! __preemption_enabled() ); 777 777 eventfd_t val; 778 778 val = 1; 779 779 eventfd_write( this->idle, val ); 780 enable_interrupts( __cfaabi_dbg_ctx);780 __enable_interrupts_checked(); 781 781 } 782 782
Note: See TracChangeset
for help on using the changeset viewer.