Changeset 90c4df0
- Timestamp:
- Aug 22, 2017, 1:44:12 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 80c72a7
- Parents:
- e50e9ff
- Location:
- src
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/invoke.h
re50e9ff r90c4df0 28 28 #define thread_local _Thread_local 29 29 30 typedef void (*fptr_t)(); 31 30 32 struct spinlock { 31 33 volatile int lock; … … 50 52 void append( struct __thread_queue_t *, struct thread_desc * ); 51 53 struct thread_desc * pop_head( struct __thread_queue_t * ); 54 struct thread_desc * remove( struct __thread_queue_t *, struct thread_desc ** ); 52 55 53 56 void ?{}( struct __condition_stack_t * ); … … 91 94 unsigned short acceptable_count; // number of acceptable functions 92 95 short accepted_index; // the index of the accepted function, -1 if none 93 void (*pre_accept)(void);// function to run before an accept96 fptr_t pre_accept; // function to run before an accept 94 97 }; 95 98 96 99 struct thread_desc { 100 // Core threading fields 97 101 struct coroutine_desc cor; // coroutine body used to store context 98 102 struct monitor_desc mon; // monitor body used for mutual exclusion 103 104 // Link lists fields 99 105 struct thread_desc * next; // instrusive link field for threads 106 107 // Current status related to monitors 100 108 struct monitor_desc ** current_monitors; // currently held monitors 101 109 unsigned short current_monitor_count; // number of currently held monitors 110 fptr_t current_monitor_func; // last function that acquired monitors 102 111 }; 103 112 -
src/libcfa/concurrency/kernel.c
re50e9ff r90c4df0 668 668 } 669 669 670 thread_desc * remove( __thread_queue_t * this, thread_desc ** it ) { 671 thread_desc * thrd = *it; 672 verify( thrd ); 673 674 (*it) = thrd->next; 675 676 if( this->tail == &thrd->next ) { 677 this->tail = it; 678 } 679 680 thrd->next = NULL; 681 682 verify( (this->head == NULL) == (&this->head == this->tail) ); 683 verify( *this->tail == NULL ); 684 return thrd; 685 } 686 687 688 670 689 void ?{}( __condition_stack_t * this ) { 671 690 this->top = NULL; -
src/libcfa/concurrency/monitor
re50e9ff r90c4df0 39 39 monitor_desc ** prev_mntrs; 40 40 unsigned short prev_count; 41 fptr_t prev_func; 41 42 }; 42 43 … … 99 100 // External scheduling 100 101 101 typedef void (*void_fptr_t)(void);102 103 102 struct __acceptable_t { 104 void_fptr_t func;103 fptr_t func; 105 104 unsigned short count; 106 105 monitor_desc ** monitors; -
src/libcfa/concurrency/monitor.c
re50e9ff r90c4df0 73 73 thread_desc * thrd = this_thread; 74 74 75 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner); 76 75 77 this->accepted_index = -1; 76 78 if( !this->owner ) { 77 79 // No one has the monitor, just take it 78 80 set_owner( this, thrd ); 81 82 LIB_DEBUG_PRINT_SAFE("Kernel : mon is free \n"); 79 83 } 80 84 else if( this->owner == thrd) { … … 82 86 verify( this->recursion > 0 ); 83 87 this->recursion += 1; 88 89 LIB_DEBUG_PRINT_SAFE("Kernel : mon already owned \n"); 84 90 } 85 91 else if( (this->accepted_index = is_accepted( thrd, this, group, group_cnt, func)) >= 0 ) { 86 92 // Some one was waiting for us, enter 87 93 set_owner( this, thrd ); 94 95 LIB_DEBUG_PRINT_SAFE("Kernel : mon accepts \n"); 88 96 } 89 97 else { 98 LIB_DEBUG_PRINT_SAFE("Kernel : blocking \n"); 99 90 100 // Some one else has the monitor, wait in line for it 91 101 append( &this->entry_queue, thrd ); 92 102 BlockInternal( &this->lock ); 93 103 104 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entered mon %p\n", thrd, this); 105 94 106 // BlockInternal will unlock spinlock, no need to unlock ourselves 95 107 return; 96 108 } 109 110 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entered mon %p\n", thrd, this); 97 111 98 112 // Release the lock and leave … … 194 208 qsort(this->m, count); 195 209 196 // Enter the monitors in order197 enter( this->m, this->count, func );198 199 210 // Save previous thread context 200 211 this->prev_mntrs = this_thread->current_monitors; 201 212 this->prev_count = this_thread->current_monitor_count; 213 this->prev_func = this_thread->current_monitor_func; 202 214 203 215 // Update thread context (needed for conditions) 204 216 this_thread->current_monitors = m; 205 217 this_thread->current_monitor_count = count; 218 this_thread->current_monitor_func = func; 219 220 // Enter the monitors in order 221 enter( this->m, this->count, func ); 206 222 } 207 223 … … 214 230 this_thread->current_monitors = this->prev_mntrs; 215 231 this_thread->current_monitor_count = this->prev_count; 232 this_thread->current_monitor_func = this->prev_func; 216 233 } 217 234 … … 402 419 thread_desc * next = search_entry_queue( acceptables, acc_count, monitors, count ); 403 420 421 LIB_DEBUG_PRINT_SAFE("Owner(s) :"); 422 for(int i = 0; i < count; i++) { 423 LIB_DEBUG_PRINT_SAFE(" %p", monitors[i]->owner ); 424 } 425 LIB_DEBUG_PRINT_SAFE("\n"); 426 427 LIB_DEBUG_PRINT_SAFE("Passing mon to %p\n", next); 428 404 429 if( !next ) { 405 430 // Update acceptables on the current monitors … … 409 434 } 410 435 } 436 else { 437 for(int i = 0; i < count; i++) { 438 set_owner( monitors[i], next ); 439 } 440 } 441 411 442 412 443 save_recursion( monitors, recursions, count ); 444 413 445 414 446 // Everything is ready to go to sleep … … 602 634 } 603 635 636 static inline bool match( __acceptable_t * acc, thread_desc * thrd ) { 637 verify( thrd ); 638 verify( acc ); 639 if( acc->func != thrd->current_monitor_func ) return false; 640 641 return true; 642 } 643 604 644 static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count ) { 645 646 __thread_queue_t * entry_queue = &monitors[0]->entry_queue; 647 648 // For each thread in the entry-queue 649 for( thread_desc ** thrd_it = &entry_queue->head; 650 *thrd_it; 651 thrd_it = &(*thrd_it)->next) 652 { 653 // For each acceptable check if it matches 654 __acceptable_t * acc_end = acceptables + acc_count; 655 for( __acceptable_t * acc_it = acceptables; acc_it != acc_end; acc_it++ ) { 656 // Check if we have a match 657 if( match( acc_it, *thrd_it ) ) { 658 659 // If we have a match return it 660 // after removeing it from the entry queue 661 return remove( entry_queue, thrd_it ); 662 } 663 } 664 } 665 605 666 return NULL; 606 667 } -
src/libcfa/concurrency/preemption.c
re50e9ff r90c4df0 332 332 assertf(sig == SIGALRM, "Kernel Internal Error, sigwait: Unexpected signal %d (%d : %d)\n", sig, info.si_code, info.si_value.sival_int); 333 333 334 LIB_DEBUG_PRINT_SAFE("Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int );334 // LIB_DEBUG_PRINT_SAFE("Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int ); 335 335 // Switch on the code (a.k.a. the sender) to 336 336 switch( info.si_code ) … … 340 340 case SI_TIMER: 341 341 case SI_KERNEL: 342 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");342 // LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n"); 343 343 lock( &event_kernel->lock DEBUG_CTX2 ); 344 344 tick_preemption(); -
src/tests/sched-ext.c
re50e9ff r90c4df0 7 7 #include <time.h> 8 8 9 static const unsigned long N = 2_500ul;9 static const unsigned long N = 500ul; 10 10 11 11 #ifndef PREEMPTION_RATE … … 24 24 thread Acceptee {}; 25 25 26 volatile bool done; 27 28 unsigned rand10() { 29 return (unsigned)rand48() % 10; 30 } 31 26 32 //---------------------------------------------------------------------------------------------------- 27 33 // Acceptor … … 29 35 30 36 void do_wait( global_t * mutex a ) { 31 sout | "Preparing to wait" | endl; 37 sout | "Waiting to accept" | endl; 38 yield( rand10() ); 39 40 sout | "Accepting" | endl; 32 41 33 42 __acceptable_t acceptable; 34 acceptable.func = ( void_fptr_t)do_notify;43 acceptable.func = (fptr_t)do_notify; 35 44 acceptable.count = 1; 36 45 acceptable.monitors = &a; 37 46 acceptable.run_preaccept = false; 38 47 39 sout | "Waiting for notify" | endl;48 __accept_internal( 1, &acceptable ); 40 49 41 int ret = __accept_internal( 1, &acceptable );42 sout | "Back from wating, accepted" | ret | endl;50 sout | "Accepted" | endl; 51 yield( rand10() ); 43 52 } 44 53 45 54 void main( Acceptor* this ) { 46 do_wait( &globalA ); 55 for( int i = 0; i < N; i++ ) { 56 do_wait( &globalA ); 57 sout | i | endl; 58 } 59 60 done = true; 47 61 } 48 62 … … 50 64 // Acceptee 51 65 void do_notify( global_t * mutex a ) { 52 sout | "Notifying" | endl; 66 53 67 } 54 68 55 69 void main( Acceptee* this ) { 56 for( volatile int i = 0; i < N; i++ ); 57 58 sout | "Call Notify" | endl; 59 do_notify( &globalA ); 70 while( !done ) { 71 yield( rand10() ); 72 do_notify( &globalA ); 73 yield( rand10() ); 74 } 60 75 } 61 76 … … 63 78 // Main 64 79 int main(int argc, char* argv[]) { 65 processor p; 80 done = false; 81 rand48seed( time( NULL ) ); 82 printf("%p\n", &globalA); 66 83 sout | "Starting" | endl; 67 84 { 68 85 Acceptor r; 69 Acceptee e; 86 Acceptee e[13]; 87 70 88 } 71 89 sout | "Done" | endl;
Note: See TracChangeset
for help on using the changeset viewer.