Changes in / [7b28e4a:90cedbdd]
- Location:
- src
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/bits/locks.h
r7b28e4a r90cedbdd 126 126 127 127 struct __bin_sem_t { 128 bool signaled;129 pthread_mutex_t 130 pthread_cond_t 128 int_fast8_t counter; 129 pthread_mutex_t lock; 130 pthread_cond_t cond; 131 131 }; 132 132 133 133 static inline void ?{}(__bin_sem_t & this) with( this ) { 134 signaled = false;134 counter = 0; 135 135 pthread_mutex_init(&lock, NULL); 136 136 pthread_cond_init (&cond, NULL); … … 145 145 verify(__cfaabi_dbg_in_kernel()); 146 146 pthread_mutex_lock(&lock); 147 if(!signaled) { // this must be a loop, not if!148 149 150 signaled = false;147 if(counter != 0) { // this must be a loop, not if! 148 pthread_cond_wait(&cond, &lock); 149 } 150 counter = 1; 151 151 pthread_mutex_unlock(&lock); 152 152 } … … 154 154 static inline void post(__bin_sem_t & this) with( this ) { 155 155 verify(__cfaabi_dbg_in_kernel()); 156 157 156 pthread_mutex_lock(&lock); 158 bool needs_signal = !signaled;159 signaled = true;157 bool needs_signal = counter == 0; 158 counter = 1; 160 159 pthread_mutex_unlock(&lock); 161 162 if (needs_signal) 160 if (!needs_signal) 163 161 pthread_cond_signal(&cond); 164 }162 } 165 163 #endif -
src/libcfa/concurrency/kernel
r7b28e4a r90cedbdd 113 113 pthread_t kernel_thread; 114 114 115 // Termination 116 // Set to true to notify the processor should terminate 117 volatile bool do_terminate; 118 119 // Termination synchronisation 120 semaphore terminated; 121 115 122 // RunThread data 116 123 // Action to do after a thread is ran … … 125 132 126 133 // Idle lock 127 __bin_sem_t idleLock; 128 129 // Termination 130 // Set to true to notify the processor should terminate 131 volatile bool do_terminate; 132 133 // Termination synchronisation 134 semaphore terminated; 134 sem_t idleLock; 135 // __bin_sem_t idleLock; 135 136 136 137 // Link lists fields -
src/libcfa/concurrency/kernel.c
r7b28e4a r90cedbdd 147 147 runner.proc = &this; 148 148 149 idleLock{};149 sem_init(&idleLock, 0, 0); 150 150 151 151 start( &this ); … … 155 155 if( ! __atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE) ) { 156 156 __cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this); 157 158 __atomic_store_n(&do_terminate, true, __ATOMIC_RELAXED); 159 wake( &this ); 160 157 terminate(&this); 158 verify( __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) ); 159 verify( kernelTLS.this_processor != &this); 161 160 P( terminated ); 162 161 verify( kernelTLS.this_processor != &this); 163 } 164 165 pthread_join( kernel_thread, NULL ); 162 pthread_join( kernel_thread, NULL ); 163 } 164 165 sem_destroy(&idleLock); 166 166 } 167 167 … … 295 295 } 296 296 297 // Handles spinning logic 298 // TODO : find some strategy to put cores to sleep after some time 299 void spin(processor * this, unsigned int * spin_count) { 300 // (*spin_count)++; 301 halt(this); 302 } 303 297 304 // KERNEL_ONLY 298 305 // Context invoker for processors … … 401 408 unlock( ready_queue_lock ); 402 409 403 if( was_empty) {410 if( was_empty ) { 404 411 lock (proc_list_lock __cfaabi_dbg_ctx2); 405 412 if(idles) { 406 wake _fast(idles.head);413 wake(idles.head); 407 414 } 408 415 unlock (proc_list_lock); 409 416 } 410 else if( struct processor * idle = idles.head ) {411 wake_fast(idle);412 }413 414 417 } 415 418 … … 657 660 658 661 void halt(processor * this) with( *this ) { 659 //verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) );662 verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) ); 660 663 661 664 with( *cltr ) { … … 668 671 __cfaabi_dbg_print_safe("Kernel : Processor %p ready to sleep\n", this); 669 672 670 wait( idleLock ); 673 // #ifdef __CFA_WITH_VERIFY__ 674 // int sval = 0; 675 // sem_getvalue(&this->idleLock, &sval); 676 // verifyf(sval < 200, "Binary semaphore reached value %d : \n", sval); 677 // #endif 678 679 verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) ); 680 int __attribute__((unused)) ret = sem_wait(&idleLock); 681 // verifyf(ret >= 0 || errno == EINTR, "Sem_wait returned %d (errno %d : %s\n", ret, errno, strerror(errno)); 682 683 // wait( idleLock ); 671 684 672 685 __cfaabi_dbg_print_safe("Kernel : Processor %p woke up and ready to run\n", this); … … 678 691 unlock (proc_list_lock); 679 692 } 693 } 694 695 void wake(processor * this) { 696 __cfaabi_dbg_print_safe("Kernel : Waking up processor %p\n", this); 697 int __attribute__((unused)) ret = sem_post(&this->idleLock); 698 // verifyf(ret >= 0 || errno == EINTR, "Sem_post returned %d (errno %d : %s\n", ret, errno, strerror(errno)); 699 700 // #ifdef __CFA_WITH_VERIFY__ 701 // int sval = 0; 702 // sem_getvalue(&this->idleLock, &sval); 703 // verifyf(sval < 200, "Binary semaphore reached value %d\n", sval); 704 // #endif 705 706 // post( this->idleLock ); 680 707 } 681 708 -
src/libcfa/concurrency/kernel_private.h
r7b28e4a r90cedbdd 58 58 void finishRunning(processor * this); 59 59 void halt(processor * this); 60 61 static inline void wake_fast(processor * this) { 62 __cfaabi_dbg_print_safe("Kernel : Waking up processor %p\n", this); 63 post( this->idleLock ); 64 } 65 66 static inline void wake(processor * this) { 67 disable_interrupts(); 68 wake_fast(this); 69 enable_interrupts( __cfaabi_dbg_ctx ); 70 } 60 void wake(processor * this); 61 void terminate(processor * this); 62 void spin(processor * this, unsigned int * spin_count); 71 63 72 64 struct event_kernel_t { … … 76 68 77 69 extern event_kernel_t * event_kernel; 70 71 //extern thread_local coroutine_desc * volatile this_coroutine; 72 //extern thread_local thread_desc * volatile this_thread; 73 //extern thread_local processor * volatile this_processor; 74 75 // extern volatile thread_local bool preemption_in_progress; 76 // extern volatile thread_local bool preemption_enabled; 77 // extern volatile thread_local unsigned short disable_preempt_count; 78 78 79 79 struct __cfa_kernel_preemption_state_t { -
src/libcfa/concurrency/preemption.c
r7b28e4a r90cedbdd 260 260 static void preempt( processor * this ) { 261 261 sigval_t value = { PREEMPT_NORMAL }; 262 pthread_sigqueue( this->kernel_thread, SIGUSR1, value ); 263 } 264 265 // kill wrapper : signal a processor 266 void terminate(processor * this) { 267 disable_interrupts(); 268 __atomic_store_n(&this->do_terminate, true, __ATOMIC_SEQ_CST); 269 wake( this ); 270 sigval_t value = { PREEMPT_TERMINATE }; 271 enable_interrupts( __cfaabi_dbg_ctx ); 262 272 pthread_sigqueue( this->kernel_thread, SIGUSR1, value ); 263 273 } -
src/tests/preempt_longrun/Makefile.am
r7b28e4a r90cedbdd 34 34 35 35 clean-local: 36 rm -f ${TESTS} core* out.log36 rm -f ${TESTS} 37 37 38 38 % : %.c ${CC} -
src/tests/preempt_longrun/Makefile.in
r7b28e4a r90cedbdd 878 878 879 879 clean-local: 880 rm -f ${TESTS} core* out.log880 rm -f ${TESTS} 881 881 882 882 % : %.c ${CC} -
src/tests/preempt_longrun/enter.c
r7b28e4a r90cedbdd 15 15 16 16 monitor mon_t {}; 17 18 mon_t mon; 19 17 20 void foo( mon_t & mutex this ) {} 18 21 19 mon_t mon;20 22 thread worker_t {}; 23 21 24 void main( worker_t & this ) { 22 25 for( unsigned long i = 0; i < N; i++ ) { … … 25 28 } 26 29 30 extern "C" { 31 static worker_t * workers; 32 } 33 27 34 int main(int argc, char * argv[] ) { 28 35 processor p; 29 36 { 30 37 worker_t w[7]; 38 workers = w; 31 39 } 32 40 } -
src/tests/preempt_longrun/processor.c
r7b28e4a r90cedbdd 13 13 } 14 14 15 static const unsigned long N = 5 0_000ul;15 static const unsigned long N = 5_000ul; 16 16 17 17 int main(int argc, char* argv[]) { 18 18 processor * p[15]; 19 write(STD OUT_FILENO, "Preparing\n", sizeof("Preparing\n"));19 write(STDERR_FILENO, "Preparing\n", sizeof("Preparing\n")); 20 20 for ( int pi = 0; pi < 15; pi++ ) { 21 21 p[pi] = new(); 22 22 } 23 write(STD OUT_FILENO, "Starting\n", sizeof("Starting\n"));23 write(STDERR_FILENO, "Starting\n", sizeof("Starting\n")); 24 24 for ( int i = 0; i < N; i++) { 25 25 int pi = i % 15; … … 27 27 p[pi] = new(); 28 28 } 29 write(STD OUT_FILENO, "Stopping\n", sizeof("Stopping\n"));29 write(STDERR_FILENO, "Stopping\n", sizeof("Stopping\n")); 30 30 for ( int pi = 0; pi < 15; pi++ ) { 31 31 delete( p[pi] ); 32 32 } 33 write(STD OUT_FILENO, "Done\n", sizeof("Done\n"));33 write(STDERR_FILENO, "Done\n", sizeof("Done\n")); 34 34 }
Note: See TracChangeset
for help on using the changeset viewer.