Changes in / [da6d4566:168c007]
- Location:
- src
- Files:
-
- 11 edited
-
Concurrency/Keywords.cc (modified) (1 diff)
-
libcfa/concurrency/invoke.c (modified) (3 diffs)
-
libcfa/concurrency/invoke.h (modified) (3 diffs)
-
libcfa/concurrency/kernel (modified) (1 diff)
-
libcfa/concurrency/monitor (modified) (1 diff)
-
libcfa/concurrency/monitor.c (modified) (3 diffs)
-
libcfa/concurrency/thread (modified) (3 diffs)
-
libcfa/concurrency/thread.c (modified) (5 diffs)
-
tests/monitor.c (modified) (1 diff)
-
tests/multi-monitor.c (modified) (1 diff)
-
tests/thread.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Keywords.cc
rda6d4566 r168c007 331 331 ), 332 332 new ListInit( 333 map_range < std::list<Initializer*> > ( args, [this](DeclarationWithType * var ){ 334 Type * type = var->get_type()->clone(); 335 type->set_mutex( false ); 333 map_range < std::list<Initializer*> > ( args, [](DeclarationWithType * var ){ 336 334 return new SingleInit( new UntypedExpr( 337 335 new NameExpr( "get_monitor" ), 338 { new CastExpr( new VariableExpr( var ), type) }336 { new VariableExpr( var ) } 339 337 ) ); 340 338 }) -
src/libcfa/concurrency/invoke.c
rda6d4566 r168c007 29 29 30 30 extern void __suspend_internal(void); 31 extern void __ leave_monitor_desc( struct monitor_desc * this);31 extern void __thread_signal_termination(struct thread_desc*); 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;68 67 cor->state = Active; 69 68 … … 71 70 main( this ); 72 71 73 __ leave_monitor_desc( mon);72 __thread_signal_termination(thrd); 74 73 75 74 //Final suspend, should never return -
src/libcfa/concurrency/invoke.h
rda6d4566 r168c007 38 38 }; 39 39 40 struct signal_once { 41 volatile bool condition; 42 struct spinlock lock; 43 struct simple_thread_list blocked; 44 }; 45 40 46 #ifdef __CFORALL__ 41 47 extern "Cforall" { … … 46 52 void ?{}(spinlock * this); 47 53 void ^?{}(spinlock * this); 54 55 void ?{}(signal_once * this); 56 void ^?{}(signal_once * this); 48 57 } 49 58 #endif … … 70 79 }; 71 80 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 79 81 struct thread_desc { 80 struct coroutine_desc cor; // coroutine body used to store context81 struct monitor_desc mon; // monitor body used for mutual exclusion82 struct coroutine_desc cor; // coroutine body used to store context 83 struct signal_once terminated; // indicate if execuation state is not halted 82 84 struct thread_desc * next; // instrusive link field for threads 83 85 }; -
src/libcfa/concurrency/kernel
rda6d4566 r168c007 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);41 32 42 33 void wait( signal_once * ); -
src/libcfa/concurrency/monitor
rda6d4566 r168c007 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 }; 23 30 24 31 static inline void ?{}(monitor_desc * this) { -
src/libcfa/concurrency/monitor.c
rda6d4566 r168c007 19 19 #include "kernel_private.h" 20 20 21 extern "C" { 22 void __enter_monitor_desc(monitor_desc * this) { 23 lock( &this->lock ); 24 thread_desc * thrd = this_thread(); 21 void enter(monitor_desc * this) { 22 lock( &this->lock ); 23 thread_desc * thrd = this_thread(); 25 24 26 if( !this->owner ) {27 //No one has the monitor, just take it28 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 it33 assert( this->recursion > 0 );34 this->recursion += 1;35 }36 else {37 //Some one else has the monitor, wait in line for it38 append( &this->entry_queue, thrd );39 ScheduleInternal( &this->lock );25 if( !this->owner ) { 26 //No one has the monitor, just take it 27 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 it 32 assert( this->recursion > 0 ); 33 this->recursion += 1; 34 } 35 else { 36 //Some one else has the monitor, wait in line for it 37 append( &this->entry_queue, thrd ); 38 ScheduleInternal( &this->lock ); 40 39 41 //ScheduleInternal will unlock spinlock, no need to unlock ourselves 42 return; 43 } 44 45 unlock( &this->lock ); 40 //ScheduleInternal will unlock spinlock, no need to unlock ourselves 41 return; 46 42 } 47 43 48 void __leave_monitor_desc(monitor_desc * this) {49 lock( &this->lock ); 44 unlock( &this->lock ); 45 } 50 46 51 thread_desc * thrd = this_thread(); 52 assert( thrd == this->owner);47 void leave(monitor_desc * this) { 48 lock( &this->lock ); 53 49 54 //Leaving a recursion level, decrement the counter55 this->recursion -= 1;50 thread_desc * thrd = this_thread(); 51 assert( thrd == this->owner ); 56 52 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 ); 53 //Leaving a recursion level, decrement the counter 54 this->recursion -= 1; 62 55 63 //We are passing the monitor to someone else, which means recursion level is not 0 64 this->recursion = new_owner ? 1 : 0; 65 } 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 ); 66 61 67 unlock( &this->lock ); 62 //We are passing the monitor to someone else, which means recursion level is not 0 63 this->recursion = new_owner ? 1 : 0; 64 } 68 65 69 //If we have a new owner, we need to wake-up the thread 70 if( new_owner ) { 71 ScheduleThread( new_owner ); 72 } 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 ); 73 71 } 74 72 } … … 76 74 void enter(monitor_desc ** monitors, int count) { 77 75 for(int i = 0; i < count; i++) { 78 __enter_monitor_desc( monitors[i] );76 enter( monitors[i] ); 79 77 } 80 78 } … … 82 80 void leave(monitor_desc ** monitors, int count) { 83 81 for(int i = count - 1; i >= 0; i--) { 84 __leave_monitor_desc( monitors[i] );82 leave( monitors[i] ); 85 83 } 86 84 } -
src/libcfa/concurrency/thread
rda6d4566 r168c007 22 22 23 23 #include "coroutine" 24 #include "monitor"25 24 26 25 //----------------------------------------------------------------------------- … … 29 28 // Anything that is resumed is a coroutine. 30 29 trait is_thread(dtype T) { 31 void ^?{}(T* mutexthis);30 void ^?{}(T* this); 32 31 void main(T* this); 33 32 thread_desc* get_thread(T* this); … … 41 40 } 42 41 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) { 42 static inline coroutine_desc* get_coroutine(thread_desc* this) { 49 43 return &this->cor; 50 }51 52 static inline monitor_desc* get_monitor(thread_desc * this) {53 return &this->mon;54 44 } 55 45 -
src/libcfa/concurrency/thread.c
rda6d4566 r168c007 35 35 void start( T* this ); 36 36 37 forall( dtype T | is_thread(T) ) 38 void stop( T* this ); 39 37 40 //----------------------------------------------------------------------------- 38 41 // Thread ctors and dtors … … 41 44 (&this->cor){}; 42 45 this->cor.name = "Anonymous Coroutine"; 43 this->mon.owner = this; 44 this->mon.recursion = 1; 46 (&this->terminated){}; 45 47 this->next = NULL; 46 48 } … … 64 66 forall( dtype T | sized(T) | is_thread(T) ) 65 67 void ^?{}( scoped(T)* this ) { 68 stop(&this->handle); 66 69 ^(&this->handle){}; 67 70 } … … 83 86 84 87 ScheduleThread(thrd_h); 88 } 89 90 forall( dtype T | is_thread(T) ) 91 void stop( T* this ) { 92 wait( & get_thread(this)->terminated ); 85 93 } 86 94 … … 108 116 } 109 117 118 // C Helper to signal the termination of a thread_desc 119 // Used in invoke.c 120 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 110 128 // Local Variables: // 111 129 // mode: c // -
src/tests/monitor.c
rda6d4566 r168c007 36 36 37 37 void ?{}( MyThread * this ) {} 38 void ^?{}( MyThread * mutex this ) {}39 38 40 39 void main( MyThread* this ) { 41 for(int i = 0; i < 1 _000_000; i++) {40 for(int i = 0; i < 1000000; i++) { 42 41 increment( &global ); 43 42 } -
src/tests/multi-monitor.c
rda6d4566 r168c007 31 31 } 32 32 33 void ^?{}( MyThread * mutex this ) {}34 35 33 void main( MyThread* this ) { 36 34 for(int i = 0; i < 1000000; i++) { -
src/tests/thread.c
rda6d4566 r168c007 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 ) {}17 14 18 15 void main(First* this) {
Note:
See TracChangeset
for help on using the changeset viewer.