- Timestamp:
- Mar 22, 2017, 11:28:47 AM (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:
- 9c14ae9
- Parents:
- 597db97 (diff), a53e10a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Keywords.cc
r597db97 r349b2cb 331 331 ), 332 332 new ListInit( 333 map_range < std::list<Initializer*> > ( args, [](DeclarationWithType * var ){ 333 map_range < std::list<Initializer*> > ( args, [this](DeclarationWithType * var ){ 334 Type * type = var->get_type()->clone(); 335 type->set_mutex( false ); 334 336 return new SingleInit( new UntypedExpr( 335 337 new NameExpr( "get_monitor" ), 336 { new VariableExpr( var) }338 { new CastExpr( new VariableExpr( var ), type ) } 337 339 ) ); 338 340 }) -
src/libcfa/concurrency/invoke.c
r597db97 r349b2cb 29 29 30 30 extern void __suspend_internal(void); 31 extern void __ thread_signal_termination(struct thread_desc*);31 extern void __leave_monitor_desc( struct monitor_desc * this ); 32 32 33 33 void CtxInvokeCoroutine( … … 65 65 struct thread_desc* thrd = get_thread( this ); 66 66 struct coroutine_desc* cor = &thrd->cor; 67 struct monitor_desc* mon = &thrd->mon; 67 68 cor->state = Active; 68 69 … … 70 71 main( this ); 71 72 72 __ thread_signal_termination(thrd);73 __leave_monitor_desc( mon ); 73 74 74 75 //Final suspend, should never return -
src/libcfa/concurrency/invoke.h
r597db97 r349b2cb 38 38 }; 39 39 40 struct signal_once {41 volatile bool condition;42 struct spinlock lock;43 struct simple_thread_list blocked;44 };45 46 40 #ifdef __CFORALL__ 47 41 extern "Cforall" { … … 52 46 void ?{}(spinlock * this); 53 47 void ^?{}(spinlock * this); 54 55 void ?{}(signal_once * this);56 void ^?{}(signal_once * this);57 48 } 58 49 #endif … … 79 70 }; 80 71 72 struct monitor_desc { 73 struct spinlock lock; 74 struct thread_desc * owner; 75 struct simple_thread_list entry_queue; 76 unsigned int recursion; 77 }; 78 81 79 struct thread_desc { 82 struct coroutine_desc cor; 83 struct signal_once terminated; // indicate if execuation state is not halted80 struct coroutine_desc cor; // coroutine body used to store context 81 struct monitor_desc mon; // monitor body used for mutual exclusion 84 82 struct thread_desc * next; // instrusive link field for threads 85 83 }; -
src/libcfa/concurrency/kernel
r597db97 r349b2cb 30 30 void lock( spinlock * ); 31 31 void unlock( spinlock * ); 32 33 struct signal_once { 34 volatile bool condition; 35 struct spinlock lock; 36 struct simple_thread_list blocked; 37 }; 38 39 void ?{}(signal_once * this); 40 void ^?{}(signal_once * this); 32 41 33 42 void wait( signal_once * ); -
src/libcfa/concurrency/monitor
r597db97 r349b2cb 21 21 #include "invoke.h" 22 22 #include "stdlib" 23 24 struct monitor_desc {25 spinlock lock;26 thread_desc * owner;27 simple_thread_list entry_queue;28 unsigned int recursion;29 };30 23 31 24 static inline void ?{}(monitor_desc * this) { -
src/libcfa/concurrency/monitor.c
r597db97 r349b2cb 19 19 #include "kernel_private.h" 20 20 21 void enter(monitor_desc * this) { 22 lock( &this->lock ); 23 thread_desc * thrd = this_thread(); 21 extern "C" { 22 void __enter_monitor_desc(monitor_desc * this) { 23 lock( &this->lock ); 24 thread_desc * thrd = this_thread(); 24 25 25 if( !this->owner ) {26 //No one has the monitor, just take it27 this->owner = thrd;28 this->recursion = 1;29 }30 else if( this->owner == thrd) {31 //We already have the monitor, just not how many times we took it32 assert( this->recursion > 0 );33 this->recursion += 1;34 }35 else {36 //Some one else has the monitor, wait in line for it37 append( &this->entry_queue, thrd );38 ScheduleInternal( &this->lock );26 if( !this->owner ) { 27 //No one has the monitor, just take it 28 this->owner = thrd; 29 this->recursion = 1; 30 } 31 else if( this->owner == thrd) { 32 //We already have the monitor, just not how many times we took it 33 assert( this->recursion > 0 ); 34 this->recursion += 1; 35 } 36 else { 37 //Some one else has the monitor, wait in line for it 38 append( &this->entry_queue, thrd ); 39 ScheduleInternal( &this->lock ); 39 40 40 //ScheduleInternal will unlock spinlock, no need to unlock ourselves 41 return; 41 //ScheduleInternal will unlock spinlock, no need to unlock ourselves 42 return; 43 } 44 45 unlock( &this->lock ); 42 46 } 43 47 44 unlock( &this->lock );45 } 48 void __leave_monitor_desc(monitor_desc * this) { 49 lock( &this->lock ); 46 50 47 void leave(monitor_desc * this) { 48 lock( &this->lock);51 thread_desc * thrd = this_thread(); 52 assert( thrd == this->owner ); 49 53 50 thread_desc * thrd = this_thread();51 assert( thrd == this->owner );54 //Leaving a recursion level, decrement the counter 55 this->recursion -= 1; 52 56 53 //Leaving a recursion level, decrement the counter 54 this->recursion -= 1; 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 ); 55 62 56 //If we left the last level of recursion it means we are changing who owns the monitor 57 thread_desc * new_owner = 0; 58 if( this->recursion == 0) { 59 //Get the next thread in the list 60 new_owner = this->owner = pop_head( &this->entry_queue ); 63 //We are passing the monitor to someone else, which means recursion level is not 0 64 this->recursion = new_owner ? 1 : 0; 65 } 61 66 62 //We are passing the monitor to someone else, which means recursion level is not 0 63 this->recursion = new_owner ? 1 : 0; 64 } 67 unlock( &this->lock ); 65 68 66 unlock( &this->lock ); 67 68 //If we have a new owner, we need to wake-up the thread 69 if( new_owner ) { 70 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 } 71 73 } 72 74 } … … 74 76 void enter(monitor_desc ** monitors, int count) { 75 77 for(int i = 0; i < count; i++) { 76 enter( monitors[i] );78 __enter_monitor_desc( monitors[i] ); 77 79 } 78 80 } … … 80 82 void leave(monitor_desc ** monitors, int count) { 81 83 for(int i = count - 1; i >= 0; i--) { 82 leave( monitors[i] );84 __leave_monitor_desc( monitors[i] ); 83 85 } 84 86 } -
src/libcfa/concurrency/thread
r597db97 r349b2cb 22 22 23 23 #include "coroutine" 24 #include "monitor" 24 25 25 26 //----------------------------------------------------------------------------- … … 28 29 // Anything that is resumed is a coroutine. 29 30 trait is_thread(dtype T) { 30 void ^?{}(T* this);31 void ^?{}(T* mutex this); 31 32 void main(T* this); 32 33 thread_desc* get_thread(T* this); … … 40 41 } 41 42 42 static inline coroutine_desc* get_coroutine(thread_desc* this) { 43 forall( dtype T | is_thread(T) ) 44 static inline monitor_desc* get_monitor(T * this) { 45 return &get_thread(this)->mon; 46 } 47 48 static inline coroutine_desc* get_coroutine(thread_desc * this) { 43 49 return &this->cor; 50 } 51 52 static inline monitor_desc* get_monitor(thread_desc * this) { 53 return &this->mon; 44 54 } 45 55 -
src/libcfa/concurrency/thread.c
r597db97 r349b2cb 35 35 void start( T* this ); 36 36 37 forall( dtype T | is_thread(T) )38 void stop( T* this );39 40 37 //----------------------------------------------------------------------------- 41 38 // Thread ctors and dtors … … 44 41 (&this->cor){}; 45 42 this->cor.name = "Anonymous Coroutine"; 46 (&this->terminated){}; 43 this->mon.owner = this; 44 this->mon.recursion = 1; 47 45 this->next = NULL; 48 46 } … … 66 64 forall( dtype T | sized(T) | is_thread(T) ) 67 65 void ^?{}( scoped(T)* this ) { 68 stop(&this->handle);69 66 ^(&this->handle){}; 70 67 } … … 86 83 87 84 ScheduleThread(thrd_h); 88 }89 90 forall( dtype T | is_thread(T) )91 void stop( T* this ) {92 wait( & get_thread(this)->terminated );93 85 } 94 86 … … 116 108 } 117 109 118 // C Helper to signal the termination of a thread_desc119 // Used in invoke.c120 extern "C" {121 void __thread_signal_termination( thread_desc * this ) {122 this->cor.state = Halted;123 LIB_DEBUG_PRINTF("Thread end : %p\n", this);124 signal( &this->terminated );125 }126 }127 128 110 // Local Variables: // 129 111 // mode: c // -
src/tests/monitor.c
r597db97 r349b2cb 36 36 37 37 void ?{}( MyThread * this ) {} 38 void ^?{}( MyThread * mutex this ) {} 38 39 39 40 void main( MyThread* this ) { 40 for(int i = 0; i < 1 000000; i++) {41 for(int i = 0; i < 1_000_000; i++) { 41 42 increment( &global ); 42 43 } -
src/tests/multi-monitor.c
r597db97 r349b2cb 31 31 } 32 32 33 void ^?{}( MyThread * mutex this ) {} 34 33 35 void main( MyThread* this ) { 34 36 for(int i = 0; i < 1000000; i++) { -
src/tests/thread.c
r597db97 r349b2cb 12 12 void ?{}( First * this, signal_once* lock ) { this->lock = lock; } 13 13 void ?{}( Second * this, signal_once* lock ) { this->lock = lock; } 14 15 void ^?{}( First * mutex this ) {} 16 void ^?{}( Second * mutex this ) {} 14 17 15 18 void main(First* this) {
Note: See TracChangeset
for help on using the changeset viewer.