Changes in / [72dc82a:936a287]
- Files:
-
- 5 edited
-
doc/proposals/concurrency/thePlan.md (modified) (1 diff)
-
src/libcfa/concurrency/invoke.h (modified) (3 diffs)
-
src/libcfa/concurrency/kernel.c (modified) (2 diffs)
-
src/libcfa/concurrency/monitor (modified) (2 diffs)
-
src/libcfa/concurrency/monitor.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/proposals/concurrency/thePlan.md
r72dc82a r936a287 10 10 done - Multi monitors calls, 11 11 done - Monitors as a language feature (not calling enter/leave by hand) 12 Internal scheduling 12 13 13 _Phase 3_ : Monitor features 14 Internal scheduling 15 External scheduling 16 17 _Phase 4_ : Kernel features 14 _Phase 3_ : Kernel features 18 15 Preemption 19 16 Detach thread 20 17 Cluster migration 18 19 _Phase 4_ : Monitor features 20 External scheduling 21 21 22 22 _Phase 5_ : Performance -
src/libcfa/concurrency/invoke.h
r72dc82a r936a287 38 38 }; 39 39 40 struct simple_thread_stack {41 struct thread_desc * top;42 };43 44 40 #ifdef __CFORALL__ 45 41 extern "Cforall" { … … 47 43 void append( struct simple_thread_list *, struct thread_desc * ); 48 44 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 * );53 45 54 46 void ?{}(spinlock * this); … … 82 74 struct thread_desc * owner; 83 75 struct simple_thread_list entry_queue; 84 struct simple_thread_stack signal_stack;85 struct monitor_desc * stack_owner;86 76 unsigned int recursion; 87 77 }; -
src/libcfa/concurrency/kernel.c
r72dc82a r936a287 294 294 // Scheduler routines 295 295 void ScheduleThread( thread_desc * thrd ) { 296 if( !thrd ) return;297 298 296 assertf( thrd->next == NULL, "Expected null got %p", thrd->next ); 299 297 … … 470 468 return head; 471 469 } 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 }491 470 // Local Variables: // 492 471 // mode: c // -
src/libcfa/concurrency/monitor
r72dc82a r936a287 18 18 #define MONITOR_H 19 19 20 #include <stddef.h>21 22 20 #include "assert" 23 21 #include "invoke.h" … … 25 23 26 24 static inline void ?{}(monitor_desc * this) { 27 this->owner = NULL; 28 this->stack_owner = NULL; 25 this->owner = 0; 29 26 this->recursion = 0; 30 27 } -
src/libcfa/concurrency/monitor.c
r72dc82a r936a287 18 18 19 19 #include "kernel_private.h" 20 21 void set_owner( monitor_desc * this, thread_desc * owner ) {22 //Pass the monitor appropriately23 this->owner = owner;24 25 //We are passing the monitor to someone else, which means recursion level is not 026 this->recursion = owner ? 1 : 0;27 }28 20 29 21 extern "C" { … … 54 46 } 55 47 56 // leave pseudo code :57 // decrement level58 // leve == 0 ?59 // no : done60 // yes :61 // signal stack empty ?62 // has leader :63 // bulk acquiring means we don't own the signal stack64 // ignore it but don't release the monitor65 // yes :66 // next in entry queue is new owner67 // no :68 // top of the signal stack is the owner69 // context switch to him right away70 //71 48 void __leave_monitor_desc(monitor_desc * this) { 72 49 lock( &this->lock ); … … 78 55 this->recursion -= 1; 79 56 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 } 57 //If we left the last level of recursion it means we are changing who owns the monitor 58 thread_desc * new_owner = 0; 59 if( this->recursion == 0) { 60 //Get the next thread in the list 61 new_owner = this->owner = pop_head( &this->entry_queue ); 93 62 94 //We are the stack owner and have left the last recursion level.95 //We are in charge of passing the monitor96 thread_desc * new_owner = 0;63 //We are passing the monitor to someone else, which means recursion level is not 0 64 this->recursion = new_owner ? 1 : 0; 65 } 97 66 98 //Check the signaller stack99 new_owner = pop( &this->signal_stack );100 if( new_owner ) {101 //The signaller stack is not empty,102 //transfer control immediately103 set_owner( this, new_owner );104 ScheduleInternal( &this->lock, new_owner );105 return;106 }107 108 // No signaller thread109 // Get the next thread in the entry_queue110 new_owner = pop_head( &this->entry_queue );111 set_owner( this, new_owner );112 113 //We can now let other threads in safely114 67 unlock( &this->lock ); 115 68 116 //We need to wake-up the thread 117 ScheduleThread( new_owner ); 69 //If we have a new owner, we need to wake-up the thread 70 if( new_owner ) { 71 ScheduleThread( new_owner ); 72 } 118 73 } 119 74 }
Note:
See TracChangeset
for help on using the changeset viewer.