- File:
-
- 1 edited
-
libcfa/src/concurrency/kernel.cfa (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel.cfa
r34b8cb7 r5f5a729 124 124 static void __wake_one(cluster * cltr); 125 125 126 static voidmark_idle (__cluster_proc_list & idles, processor & proc);126 static bool mark_idle (__cluster_proc_list & idles, processor & proc); 127 127 static void mark_awake(__cluster_proc_list & idles, processor & proc); 128 static [unsigned idle, unsigned total, * processor] query_idles( & __cluster_proc_list idles ); 128 129 129 130 extern void __cfa_io_start( processor * ); … … 212 213 213 214 // Push self to idle stack 214 mark_idle(this->cltr->procs, * this);215 if(!mark_idle(this->cltr->procs, * this)) continue MAIN_LOOP; 215 216 216 217 // Confirm the ready-queue is empty … … 330 331 // Push self to idle stack 331 332 ready_schedule_unlock(); 332 mark_idle(this->cltr->procs, * this);333 if(!mark_idle(this->cltr->procs, * this)) goto SEARCH; 333 334 ready_schedule_lock(); 334 335 … … 765 766 766 767 // Check if there is a sleeping processor 767 int fd = __atomic_load_n(&this->procs.fd, __ATOMIC_SEQ_CST); 768 processor * p; 769 unsigned idle; 770 unsigned total; 771 [idle, total, p] = query_idles(this->procs); 768 772 769 773 // If no one is sleeping, we are done 770 if( fd== 0 ) return;774 if( idle == 0 ) return; 771 775 772 776 // We found a processor, wake it up 773 777 eventfd_t val; 774 778 val = 1; 775 eventfd_write( fd, val );779 eventfd_write( p->idle, val ); 776 780 777 781 #if !defined(__CFA_NO_STATISTICS__) … … 802 806 } 803 807 804 static voidmark_idle(__cluster_proc_list & this, processor & proc) {805 /* paranoid */ verify( ! __preemption_enabled() ); 806 lock( this );808 static bool mark_idle(__cluster_proc_list & this, processor & proc) { 809 /* paranoid */ verify( ! __preemption_enabled() ); 810 if(!try_lock( this )) return false; 807 811 this.idle++; 808 812 /* paranoid */ verify( this.idle <= this.total ); 809 813 remove(proc); 810 814 insert_first(this.idles, proc); 811 812 __atomic_store_n(&this.fd, proc.idle, __ATOMIC_SEQ_CST);813 815 unlock( this ); 814 816 /* paranoid */ verify( ! __preemption_enabled() ); 817 818 return true; 815 819 } 816 820 … … 822 826 remove(proc); 823 827 insert_last(this.actives, proc); 824 825 __atomic_store_n(&this.fd, this.idles`first.idle, __ATOMIC_SEQ_CST);826 828 unlock( this ); 829 /* paranoid */ verify( ! __preemption_enabled() ); 830 } 831 832 static [unsigned idle, unsigned total, * processor] query_idles( & __cluster_proc_list this ) { 833 /* paranoid */ verify( ! __preemption_enabled() ); 834 /* paranoid */ verify( ready_schedule_islocked() ); 835 836 for() { 837 uint64_t l = __atomic_load_n(&this.lock, __ATOMIC_SEQ_CST); 838 if( 1 == (l % 2) ) { Pause(); continue; } 839 unsigned idle = this.idle; 840 unsigned total = this.total; 841 processor * proc = &this.idles`first; 842 // Compiler fence is unnecessary, but gcc-8 and older incorrectly reorder code without it 843 asm volatile("": : :"memory"); 844 if(l != __atomic_load_n(&this.lock, __ATOMIC_SEQ_CST)) { Pause(); continue; } 845 return [idle, total, proc]; 846 } 847 848 /* paranoid */ verify( ready_schedule_islocked() ); 827 849 /* paranoid */ verify( ! __preemption_enabled() ); 828 850 } … … 886 908 if(head == tail) return false; 887 909 #if OLD_MAIN 888 ready_schedule_lock();889 ret = __cfa_io_drain( proc );890 ready_schedule_unlock();910 ready_schedule_lock(); 911 ret = __cfa_io_drain( proc ); 912 ready_schedule_unlock(); 891 913 #else 892 914 ret = __cfa_io_drain( proc ); 893 #endif915 #endif 894 916 #endif 895 917 return ret;
Note:
See TracChangeset
for help on using the changeset viewer.