- Timestamp:
- Mar 28, 2017, 1:03:01 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:
- 72dc82a
- Parents:
- f32a013
- Location:
- src/libcfa/concurrency
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/invoke.h
rf32a013 r690f13c 38 38 }; 39 39 40 struct simple_thread_stack { 41 struct thread_desc * top; 42 }; 43 40 44 #ifdef __CFORALL__ 41 45 extern "Cforall" { … … 43 47 void append( struct simple_thread_list *, struct thread_desc * ); 44 48 struct thread_desc * pop_head( struct simple_thread_list * ); 49 50 void ?{}( struct simple_thread_stack * ); 51 void push( struct simple_thread_stack *, struct thread_desc * ); 52 struct thread_desc * pop( struct simple_thread_stack * ); 45 53 46 54 void ?{}(spinlock * this); … … 74 82 struct thread_desc * owner; 75 83 struct simple_thread_list entry_queue; 84 struct simple_thread_stack signal_stack; 85 struct monitor_desc * stack_owner; 76 86 unsigned int recursion; 77 87 }; -
src/libcfa/concurrency/kernel.c
rf32a013 r690f13c 294 294 // Scheduler routines 295 295 void ScheduleThread( thread_desc * thrd ) { 296 if( !thrd ) return; 297 296 298 assertf( thrd->next == NULL, "Expected null got %p", thrd->next ); 297 299 … … 468 470 return head; 469 471 } 472 473 void ?{}( simple_thread_stack * this ) { 474 this->top = NULL; 475 } 476 477 void push( simple_thread_stack * this, thread_desc * t ) { 478 assert(t->next != NULL); 479 t->next = this->top; 480 this->top = t; 481 } 482 483 thread_desc * pop( simple_thread_stack * this ) { 484 thread_desc * top = this->top; 485 if( top ) { 486 this->top = top->next; 487 top->next = NULL; 488 } 489 return top; 490 } 470 491 // Local Variables: // 471 492 // mode: c // -
src/libcfa/concurrency/monitor
rf32a013 r690f13c 18 18 #define MONITOR_H 19 19 20 #include <stddef.h> 21 20 22 #include "assert" 21 23 #include "invoke.h" … … 23 25 24 26 static inline void ?{}(monitor_desc * this) { 25 this->owner = 0; 27 this->owner = NULL; 28 this->stack_owner = NULL; 26 29 this->recursion = 0; 27 30 } -
src/libcfa/concurrency/monitor.c
rf32a013 r690f13c 18 18 19 19 #include "kernel_private.h" 20 21 void set_owner( monitor_desc * this, thread_desc * owner ) { 22 //Pass the monitor appropriately 23 this->owner = owner; 24 25 //We are passing the monitor to someone else, which means recursion level is not 0 26 this->recursion = owner ? 1 : 0; 27 } 20 28 21 29 extern "C" { … … 46 54 } 47 55 56 // leave pseudo code : 57 // decrement level 58 // leve == 0 ? 59 // no : done 60 // yes : 61 // signal stack empty ? 62 // has leader : 63 // bulk acquiring means we don't own the signal stack 64 // ignore it but don't release the monitor 65 // yes : 66 // next in entry queue is new owner 67 // no : 68 // top of the signal stack is the owner 69 // context switch to him right away 70 // 48 71 void __leave_monitor_desc(monitor_desc * this) { 49 72 lock( &this->lock ); … … 55 78 this->recursion -= 1; 56 79 57 //If we left the last level of recursion it means we are changing who owns the monitor 80 //If we haven't left the last level of recursion 81 //it means we don't need to do anything 82 if( this->recursion != 0) { 83 unlock( &this->lock ); 84 return; 85 } 86 87 //If we don't own the signal stack then just leave it to the owner 88 if( this->stack_owner ) { 89 assert( this->owner == this->stack_owner ); 90 unlock( &this->lock ); 91 return; 92 } 93 94 //We are the stack owner and have left the last recursion level. 95 //We are in charge of passing the monitor 58 96 thread_desc * new_owner = 0; 59 if( this->recursion == 0) {60 //Get the next thread in the list61 new_owner = this->owner = pop_head( &this->entry_queue );62 97 63 //We are passing the monitor to someone else, which means recursion level is not 0 64 this->recursion = new_owner ? 1 : 0; 65 } 98 //Check the signaller stack 99 new_owner = pop( &this->signal_stack ); 100 if( new_owner ) { 101 //The signaller stack is not empty, 102 //transfer control immediately 103 set_owner( this, new_owner ); 104 ScheduleInternal( &this->lock, new_owner ); 105 return; 106 } 107 108 // No signaller thread 109 // Get the next thread in the entry_queue 110 new_owner = pop_head( &this->entry_queue ); 111 set_owner( this, new_owner ); 66 112 113 //We can now let other threads in safely 67 114 unlock( &this->lock ); 68 115 69 //If we have a new owner, we need to wake-up the thread 70 if( new_owner ) { 71 ScheduleThread( new_owner ); 72 } 116 //We need to wake-up the thread 117 ScheduleThread( new_owner ); 73 118 } 74 119 }
Note: See TracChangeset
for help on using the changeset viewer.