Changes in / [95487027:8551b859]
- Location:
- src
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/bits/locks.h
r95487027 r8551b859 18 18 #include "bits/debug.h" 19 19 #include "bits/defs.h" 20 #include <assert.h>21 22 #ifdef __cforall23 extern "C" {24 #include <pthread.h>25 }26 #endif27 20 28 21 // pause to prevent excess processor bus usage … … 119 112 __atomic_clear( &this.lock, __ATOMIC_RELEASE ); 120 113 } 121 122 123 #ifdef __CFA_WITH_VERIFY__124 extern bool __cfaabi_dbg_in_kernel();125 #endif126 127 struct __bin_sem_t {128 int_fast8_t counter;129 pthread_mutex_t lock;130 pthread_cond_t cond;131 };132 133 static inline void ?{}(__bin_sem_t & this) with( this ) {134 counter = 0;135 pthread_mutex_init(&lock, NULL);136 pthread_cond_init (&cond, NULL);137 }138 139 static inline void ^?{}(__bin_sem_t & this) with( this ) {140 pthread_mutex_destroy(&lock);141 pthread_cond_destroy (&cond);142 }143 144 static inline void wait(__bin_sem_t & this) with( this ) {145 verify(__cfaabi_dbg_in_kernel());146 pthread_mutex_lock(&lock);147 if(counter != 0) { // this must be a loop, not if!148 pthread_cond_wait(&cond, &lock);149 }150 counter = 1;151 pthread_mutex_unlock(&lock);152 }153 154 static inline void post(__bin_sem_t & this) with( this ) {155 verify(__cfaabi_dbg_in_kernel());156 pthread_mutex_lock(&lock);157 bool needs_signal = counter == 0;158 counter = 1;159 pthread_mutex_unlock(&lock);160 if (!needs_signal)161 pthread_cond_signal(&cond);162 }163 114 #endif -
src/libcfa/concurrency/kernel
r95487027 r8551b859 133 133 // Idle lock 134 134 sem_t idleLock; 135 // __bin_sem_t idleLock;136 135 137 136 // Link lists fields 138 struct __dbg_node_proc{137 struct { 139 138 struct processor * next; 140 139 struct processor * prev; … … 183 182 184 183 // Link lists fields 185 struct __dbg_node_cltr{184 struct { 186 185 cluster * next; 187 186 cluster * prev; -
src/libcfa/concurrency/kernel.c
r95487027 r8551b859 17 17 #include <stddef.h> 18 18 #include <errno.h> 19 #include <string.h>20 19 extern "C" { 21 20 #include <stdio.h> … … 51 50 thread_desc * mainThread; 52 51 53 extern "C" { 54 struct { __dllist_t(cluster) list; __spinlock_t lock; } __cfa_dbg_global_clusters; 55 } 52 struct { __dllist_t(cluster) list; __spinlock_t lock; } global_clusters; 56 53 57 54 //----------------------------------------------------------------------------- … … 153 150 154 151 void ^?{}(processor & this) with( this ){ 155 if( ! __atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE)) {152 if( ! do_terminate ) { 156 153 __cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this); 157 154 terminate(&this); 158 verify( __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST));155 verify(this.do_terminate); 159 156 verify( kernelTLS.this_processor != &this); 160 157 P( terminated ); … … 202 199 203 200 thread_desc * readyThread = NULL; 204 for( unsigned int spin_count = 0; ! __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST); spin_count++ )201 for( unsigned int spin_count = 0; ! this->do_terminate; spin_count++ ) 205 202 { 206 203 readyThread = nextThread( this->cltr ); … … 221 218 else 222 219 { 223 // spin(this, &spin_count); 224 halt(this); 220 spin(this, &spin_count); 225 221 } 226 222 } … … 549 545 __cfaabi_dbg_print_safe("Kernel : Starting\n"); 550 546 551 __cfa_dbg_global_clusters.list{ __get };552 __cfa_dbg_global_clusters.lock{};547 global_clusters.list{ __get }; 548 global_clusters.lock{}; 553 549 554 550 // Initialize the main cluster … … 631 627 // When its coroutine terminates, it return control to the mainThread 632 628 // which is currently here 633 __atomic_store_n(&mainProcessor->do_terminate, true, __ATOMIC_RELEASE);629 mainProcessor->do_terminate = true; 634 630 returnToKernel(); 635 mainThread->self_cor.state = Halted;636 631 637 632 // THE SYSTEM IS NOW COMPLETELY STOPPED … … 649 644 ^(mainThread){}; 650 645 651 ^( __cfa_dbg_global_clusters.list){};652 ^( __cfa_dbg_global_clusters.lock){};646 ^(global_clusters.list){}; 647 ^(global_clusters.lock){}; 653 648 654 649 __cfaabi_dbg_print_safe("Kernel : Shutdown complete\n"); … … 660 655 661 656 void halt(processor * this) with( *this ) { 662 verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) );663 664 657 with( *cltr ) { 665 658 lock (proc_list_lock __cfaabi_dbg_ctx2); … … 671 664 __cfaabi_dbg_print_safe("Kernel : Processor %p ready to sleep\n", this); 672 665 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) ); 666 verify( ({int sval = 0; sem_getvalue(&this->idleLock, &sval); sval; }) < 200); 680 667 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 ); 668 verify(ret > 0 || errno == EINTR); 684 669 685 670 __cfaabi_dbg_print_safe("Kernel : Processor %p woke up and ready to run\n", this); … … 696 681 __cfaabi_dbg_print_safe("Kernel : Waking up processor %p\n", this); 697 682 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 ); 683 verify(ret > 0 || errno == EINTR); 684 verify( ({int sval = 0; sem_getvalue(&this->idleLock, &sval); sval; }) < 200); 707 685 } 708 686 … … 820 798 // Global Queues 821 799 void doregister( cluster & cltr ) { 822 lock ( __cfa_dbg_global_clusters.lock __cfaabi_dbg_ctx2);823 push_front( __cfa_dbg_global_clusters.list, cltr );824 unlock ( __cfa_dbg_global_clusters.lock );800 lock ( global_clusters.lock __cfaabi_dbg_ctx2); 801 push_front( global_clusters.list, cltr ); 802 unlock ( global_clusters.lock ); 825 803 } 826 804 827 805 void unregister( cluster & cltr ) { 828 lock ( __cfa_dbg_global_clusters.lock __cfaabi_dbg_ctx2);829 remove( __cfa_dbg_global_clusters.list, cltr );830 unlock( __cfa_dbg_global_clusters.lock );806 lock ( global_clusters.lock __cfaabi_dbg_ctx2); 807 remove( global_clusters.list, cltr ); 808 unlock( global_clusters.lock ); 831 809 } 832 810 -
src/libcfa/concurrency/preemption.c
r95487027 r8551b859 265 265 // kill wrapper : signal a processor 266 266 void terminate(processor * this) { 267 disable_interrupts(); 268 __atomic_store_n(&this->do_terminate, true, __ATOMIC_SEQ_CST); 269 wake( this ); 267 this->do_terminate = true; 268 wake(this); 270 269 sigval_t value = { PREEMPT_TERMINATE }; 271 enable_interrupts( __cfaabi_dbg_ctx );272 270 pthread_sigqueue( this->kernel_thread, SIGUSR1, value ); 273 271 } … … 371 369 choose(sfp->si_value.sival_int) { 372 370 case PREEMPT_NORMAL : ;// Normal case, nothing to do here 373 case PREEMPT_TERMINATE: verify( __atomic_load_n( &kernelTLS.this_processor->do_terminate, __ATOMIC_SEQ_CST ));371 case PREEMPT_TERMINATE: verify( kernelTLS.this_processor->do_terminate); 374 372 default: 375 373 abort( "internal error, signal value is %d", sfp->si_value.sival_int ); … … 490 488 } 491 489 492 #ifdef __CFA_WITH_VERIFY__493 bool __cfaabi_dbg_in_kernel() {494 return !kernelTLS.preemption_state.enabled;495 }496 #endif497 498 490 // Local Variables: // 499 491 // mode: c // -
src/libcfa/stdhdr/assert.h
r95487027 r8551b859 33 33 #define verify(x) assert(x) 34 34 #define verifyf(x, ...) assertf(x, __VA_ARGS__) 35 #define __CFA_WITH_VERIFY__36 35 #else 37 36 #define verify(x) -
src/prelude/sync-builtins.cf
r95487027 r8551b859 248 248 #endif 249 249 250 _Bool __atomic_load_n(const volatile _Bool *, int);251 void __atomic_load(const volatile _Bool *, volatile _Bool *, int);252 250 char __atomic_load_n(const volatile char *, int); 253 251 char __atomic_load_1(const volatile char *, int); … … 287 285 288 286 void __atomic_store_n(volatile _Bool *, _Bool, int); 287 void __atomic_store_1(volatile _Bool *, _Bool, int); 289 288 void __atomic_store(volatile _Bool *, _Bool *, int); 290 289 void __atomic_store_n(volatile char *, char, int); -
src/tests/preempt_longrun/processor.c
r95487027 r8551b859 2 2 #include <thread> 3 3 #include <time> 4 5 #include <unistd.h>6 4 7 5 #ifndef PREEMPTION_RATE … … 17 15 int main(int argc, char* argv[]) { 18 16 processor * p[15]; 19 write(STDERR_FILENO, "Preparing\n", sizeof("Preparing\n"));20 17 for ( int pi = 0; pi < 15; pi++ ) { 21 18 p[pi] = new(); 22 19 } 23 write(STDERR_FILENO, "Starting\n", sizeof("Starting\n"));24 20 for ( int i = 0; i < N; i++) { 25 21 int pi = i % 15; … … 27 23 p[pi] = new(); 28 24 } 29 write(STDERR_FILENO, "Stopping\n", sizeof("Stopping\n"));30 25 for ( int pi = 0; pi < 15; pi++ ) { 31 26 delete( p[pi] ); 32 27 } 33 write(STDERR_FILENO, "Done\n", sizeof("Done\n"));34 28 }
Note: See TracChangeset
for help on using the changeset viewer.