- File:
-
- 1 edited
-
libcfa/src/concurrency/kernel.cfa (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel.cfa
r5f5a729 r34b8cb7 124 124 static void __wake_one(cluster * cltr); 125 125 126 static boolmark_idle (__cluster_proc_list & idles, processor & proc);126 static void 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 );129 128 130 129 extern void __cfa_io_start( processor * ); … … 213 212 214 213 // Push self to idle stack 215 if(!mark_idle(this->cltr->procs, * this)) continue MAIN_LOOP;214 mark_idle(this->cltr->procs, * this); 216 215 217 216 // Confirm the ready-queue is empty … … 331 330 // Push self to idle stack 332 331 ready_schedule_unlock(); 333 if(!mark_idle(this->cltr->procs, * this)) goto SEARCH;332 mark_idle(this->cltr->procs, * this); 334 333 ready_schedule_lock(); 335 334 … … 766 765 767 766 // Check if there is a sleeping processor 768 processor * p; 769 unsigned idle; 770 unsigned total; 771 [idle, total, p] = query_idles(this->procs); 767 int fd = __atomic_load_n(&this->procs.fd, __ATOMIC_SEQ_CST); 772 768 773 769 // If no one is sleeping, we are done 774 if( idle== 0 ) return;770 if( fd == 0 ) return; 775 771 776 772 // We found a processor, wake it up 777 773 eventfd_t val; 778 774 val = 1; 779 eventfd_write( p->idle, val );775 eventfd_write( fd, val ); 780 776 781 777 #if !defined(__CFA_NO_STATISTICS__) … … 806 802 } 807 803 808 static boolmark_idle(__cluster_proc_list & this, processor & proc) {809 /* paranoid */ verify( ! __preemption_enabled() ); 810 if(!try_lock( this )) return false;804 static void mark_idle(__cluster_proc_list & this, processor & proc) { 805 /* paranoid */ verify( ! __preemption_enabled() ); 806 lock( this ); 811 807 this.idle++; 812 808 /* paranoid */ verify( this.idle <= this.total ); 813 809 remove(proc); 814 810 insert_first(this.idles, proc); 811 812 __atomic_store_n(&this.fd, proc.idle, __ATOMIC_SEQ_CST); 815 813 unlock( this ); 816 814 /* paranoid */ verify( ! __preemption_enabled() ); 817 818 return true;819 815 } 820 816 … … 826 822 remove(proc); 827 823 insert_last(this.actives, proc); 824 825 __atomic_store_n(&this.fd, this.idles`first.idle, __ATOMIC_SEQ_CST); 828 826 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 it843 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() );849 827 /* paranoid */ verify( ! __preemption_enabled() ); 850 828 } … … 908 886 if(head == tail) return false; 909 887 #if OLD_MAIN 910 ready_schedule_lock();911 ret = __cfa_io_drain( proc );912 ready_schedule_unlock();888 ready_schedule_lock(); 889 ret = __cfa_io_drain( proc ); 890 ready_schedule_unlock(); 913 891 #else 914 892 ret = __cfa_io_drain( proc ); 915 #endif893 #endif 916 894 #endif 917 895 return ret;
Note:
See TracChangeset
for help on using the changeset viewer.