Changeset f2e40a9f for src/libcfa/concurrency
- Timestamp:
- Mar 15, 2017, 9:43:15 PM (9 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:
- 27fed7f1, 738e304
- Parents:
- bf4ac09 (diff), 9b443c7f (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. - git-author:
- Peter A. Buhr <pabuhr@…> (03/15/17 21:25:49)
- git-committer:
- Peter A. Buhr <pabuhr@…> (03/15/17 21:43:15)
- Location:
- src/libcfa/concurrency
- Files:
-
- 7 edited
- 4 moved
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/coroutine
rbf4ac09 rf2e40a9f 6 6 // file "LICENCE" distributed with Cforall. 7 7 // 8 // coroutine s--8 // coroutine -- 9 9 // 10 10 // Author : Thierry Delisle … … 27 27 trait is_coroutine(dtype T) { 28 28 void main(T * this); 29 coroutine * get_coroutine(T * this);29 coroutine_desc * get_coroutine(T * this); 30 30 }; 31 31 32 #define DECL_COROUTINE(X) static inline coroutine * get_coroutine(X* this) { return &this->c; } void main(X* this)32 #define DECL_COROUTINE(X) static inline coroutine_desc* get_coroutine(X* this) { return &this->c; } void main(X* this) 33 33 34 34 //----------------------------------------------------------------------------- 35 35 // Ctors and dtors 36 36 void ?{}(coStack_t * this); 37 void ?{}(coroutine * this);38 void ?{}(coroutine * this, const char * name);37 void ?{}(coroutine_desc * this); 38 void ?{}(coroutine_desc * this, const char * name); 39 39 void ^?{}(coStack_t * this); 40 void ^?{}(coroutine * this);40 void ^?{}(coroutine_desc * this); 41 41 42 42 //----------------------------------------------------------------------------- … … 63 63 64 64 // Get current coroutine 65 coroutine * this_coroutine(void);65 coroutine_desc * this_coroutine(void); 66 66 67 67 // Private wrappers for context switch and stack creation 68 extern void CoroutineCtxSwitch(coroutine * src, coroutine* dst);68 extern void CoroutineCtxSwitch(coroutine_desc * src, coroutine_desc * dst); 69 69 extern void create_stack( coStack_t * this, unsigned int storageSize ); 70 70 71 71 // Suspend implementation inlined for performance 72 72 static inline void suspend() { 73 coroutine * src = this_coroutine(); // optimization73 coroutine_desc * src = this_coroutine(); // optimization 74 74 75 75 assertf( src->last != 0, … … 88 88 forall(dtype T | is_coroutine(T)) 89 89 static inline void resume(T * cor) { 90 coroutine * src = this_coroutine(); // optimization91 coroutine * dst = get_coroutine(cor);90 coroutine_desc * src = this_coroutine(); // optimization 91 coroutine_desc * dst = get_coroutine(cor); 92 92 93 93 if( unlikely(!dst->stack.base) ) { … … 111 111 } 112 112 113 static inline void resume(coroutine * dst) {114 coroutine * src = this_coroutine(); // optimization113 static inline void resume(coroutine_desc * dst) { 114 coroutine_desc * src = this_coroutine(); // optimization 115 115 116 116 // not resuming self ? -
src/libcfa/concurrency/coroutine.c
rbf4ac09 rf2e40a9f 6 6 // file "LICENCE" distributed with Cforall. 7 7 // 8 // coroutine s.c --8 // coroutine.c -- 9 9 // 10 10 // Author : Thierry Delisle … … 15 15 // 16 16 17 #include "coroutine s"17 #include "coroutine" 18 18 19 19 extern "C" { … … 32 32 #include "invoke.h" 33 33 34 extern processor * get_this_processor();34 extern thread_local processor * this_processor; 35 35 36 36 //----------------------------------------------------------------------------- … … 60 60 } 61 61 62 void ?{}(coroutine * this) {62 void ?{}(coroutine_desc* this) { 63 63 this{ "Anonymous Coroutine" }; 64 64 } 65 65 66 void ?{}(coroutine * this, const char * name) {66 void ?{}(coroutine_desc* this, const char * name) { 67 67 this->name = name; 68 68 this->errno_ = 0; … … 72 72 } 73 73 74 void ?{}(coroutine * this, size_t size) {74 void ?{}(coroutine_desc* this, size_t size) { 75 75 this{}; 76 76 (&this->stack){size}; … … 88 88 } 89 89 90 void ^?{}(coroutine * this) {}90 void ^?{}(coroutine_desc* this) {} 91 91 92 92 // Part of the Public API … … 94 94 forall(dtype T | is_coroutine(T)) 95 95 void prime(T* cor) { 96 coroutine * this = get_coroutine(cor);96 coroutine_desc* this = get_coroutine(cor); 97 97 assert(this->state == Start); 98 98 … … 102 102 103 103 // Wrapper for co 104 void CoroutineCtxSwitch(coroutine * src, coroutine* dst) {104 void CoroutineCtxSwitch(coroutine_desc* src, coroutine_desc* dst) { 105 105 // THREAD_GETMEM( This )->disableInterrupts(); 106 106 … … 109 109 110 110 // set new coroutine that task is executing 111 get_this_processor()->current_coroutine = dst;111 this_processor->current_coroutine = dst; 112 112 113 113 // context switch to specified coroutine -
src/libcfa/concurrency/invoke.c
rbf4ac09 rf2e40a9f 29 29 30 30 extern void __suspend_internal(void); 31 extern void __thread_signal_termination(struct thread *);31 extern void __thread_signal_termination(struct thread_desc*); 32 32 33 33 void CtxInvokeCoroutine( 34 34 void (*main)(void *), 35 struct coroutine *(*get_coroutine)(void *),35 struct coroutine_desc *(*get_coroutine)(void *), 36 36 void *this 37 37 ) { 38 38 // LIB_DEBUG_PRINTF("Invoke Coroutine : Received %p (main %p, get_c %p)\n", this, main, get_coroutine); 39 39 40 struct coroutine * cor = get_coroutine( this );40 struct coroutine_desc* cor = get_coroutine( this ); 41 41 42 42 if(cor->state == Primed) { … … 57 57 void CtxInvokeThread( 58 58 void (*main)(void *), 59 struct thread *(*get_thread)(void *),59 struct thread_desc *(*get_thread)(void *), 60 60 void *this 61 61 ) { 62 62 __suspend_internal(); 63 63 64 struct thread * thrd = get_thread( this );65 struct coroutine * cor = &thrd->c;64 struct thread_desc* thrd = get_thread( this ); 65 struct coroutine_desc* cor = &thrd->c; 66 66 cor->state = Active; 67 67 … … 79 79 void CtxStart( 80 80 void (*main)(void *), 81 struct coroutine *(*get_coroutine)(void *),81 struct coroutine_desc *(*get_coroutine)(void *), 82 82 void *this, 83 83 void (*invoke)(void *) -
src/libcfa/concurrency/invoke.h
rbf4ac09 rf2e40a9f 35 35 36 36 struct simple_thread_list { 37 struct thread * head;38 struct thread ** tail;37 struct thread_desc * head; 38 struct thread_desc ** tail; 39 39 }; 40 40 … … 48 48 extern "Cforall" { 49 49 void ?{}( struct simple_thread_list * ); 50 void append( struct simple_thread_list *, struct thread * );51 struct thread * pop_head( struct simple_thread_list * );50 void append( struct simple_thread_list *, struct thread_desc * ); 51 struct thread_desc * pop_head( struct simple_thread_list * ); 52 52 53 53 void ?{}(spinlock * this); … … 71 71 enum coroutine_state { Halted, Start, Inactive, Active, Primed }; 72 72 73 struct coroutine {73 struct coroutine_desc { 74 74 struct coStack_t stack; 75 75 const char *name; // textual name for coroutine/task, initialized by uC++ generated code 76 76 int errno_; // copy of global UNIX variable errno 77 77 enum coroutine_state state; // current execution status for coroutine 78 struct coroutine *starter; // first coroutine to resume this one79 struct coroutine *last; // last coroutine to resume this one78 struct coroutine_desc *starter; // first coroutine to resume this one 79 struct coroutine_desc *last; // last coroutine to resume this one 80 80 }; 81 81 82 struct thread {83 struct coroutine c; // coroutine body used to store context82 struct thread_desc { 83 struct coroutine_desc c; // coroutine body used to store context 84 84 struct signal_once terminated; // indicate if execuation state is not halted 85 struct thread * next; // instrusive link field for threads85 struct thread_desc * next; // instrusive link field for threads 86 86 }; 87 87 -
src/libcfa/concurrency/kernel
rbf4ac09 rf2e40a9f 6 6 // file "LICENCE" distributed with Cforall. 7 7 // 8 // threads--8 // kernel -- 9 9 // 10 10 // Author : Thierry Delisle … … 49 49 struct FinishAction { 50 50 FinishOpCode action_code; 51 thread * thrd;51 thread_desc * thrd; 52 52 spinlock * lock; 53 53 }; … … 62 62 struct processorCtx_t * runner; 63 63 cluster * cltr; 64 coroutine * current_coroutine;65 thread * current_thread;64 coroutine_desc * current_coroutine; 65 thread_desc * current_thread; 66 66 pthread_t kernel_thread; 67 67 -
src/libcfa/concurrency/kernel.c
rbf4ac09 rf2e40a9f 43 43 KERNEL_STORAGE(cluster, systemCluster); 44 44 KERNEL_STORAGE(processor, systemProcessor); 45 KERNEL_STORAGE(thread , mainThread);45 KERNEL_STORAGE(thread_desc, mainThread); 46 46 KERNEL_STORAGE(machine_context_t, mainThread_context); 47 47 48 48 cluster * systemCluster; 49 49 processor * systemProcessor; 50 thread * mainThread;50 thread_desc * mainThread; 51 51 52 52 //----------------------------------------------------------------------------- … … 55 55 thread_local processor * this_processor; 56 56 57 processor * get_this_processor() { 58 return this_processor; 59 } 60 61 coroutine * this_coroutine(void) { 57 coroutine_desc * this_coroutine(void) { 62 58 return this_processor->current_coroutine; 63 59 } 64 60 65 thread * this_thread(void) {61 thread_desc * this_thread(void) { 66 62 return this_processor->current_thread; 67 63 } … … 103 99 } 104 100 105 void ?{}( coroutine * this, current_stack_info_t * info) {101 void ?{}( coroutine_desc * this, current_stack_info_t * info) { 106 102 (&this->stack){ info }; 107 103 this->name = "Main Thread"; … … 110 106 } 111 107 112 void ?{}( thread * this, current_stack_info_t * info) {108 void ?{}( thread_desc * this, current_stack_info_t * info) { 113 109 (&this->c){ info }; 114 110 } … … 179 175 LIB_DEBUG_PRINTF("Kernel : core %p starting\n", this); 180 176 181 thread * readyThread = NULL;177 thread_desc * readyThread = NULL; 182 178 for( unsigned int spin_count = 0; ! this->is_terminated; spin_count++ ) 183 179 { … … 206 202 // runThread runs a thread by context switching 207 203 // from the processor coroutine to the target thread 208 void runThread(processor * this, thread * dst) {209 coroutine * proc_cor = get_coroutine(this->runner);210 coroutine * thrd_cor = get_coroutine(dst);204 void runThread(processor * this, thread_desc * dst) { 205 coroutine_desc * proc_cor = get_coroutine(this->runner); 206 coroutine_desc * thrd_cor = get_coroutine(dst); 211 207 212 208 //Reset the terminating actions here … … 297 293 //----------------------------------------------------------------------------- 298 294 // Scheduler routines 299 void ScheduleThread( thread * thrd ) {295 void ScheduleThread( thread_desc * thrd ) { 300 296 assertf( thrd->next == NULL, "Expected null got %p", thrd->next ); 301 297 … … 305 301 } 306 302 307 thread * nextThread(cluster * this) {303 thread_desc * nextThread(cluster * this) { 308 304 lock( &this->lock ); 309 thread * head = pop_head( &this->ready_queue );305 thread_desc * head = pop_head( &this->ready_queue ); 310 306 unlock( &this->lock ); 311 307 return head; … … 317 313 318 314 void ScheduleInternal( spinlock * lock ) { 319 get_this_processor()->finish.action_code = Release;320 get_this_processor()->finish.lock = lock;315 this_processor->finish.action_code = Release; 316 this_processor->finish.lock = lock; 321 317 suspend(); 322 318 } 323 319 324 void ScheduleInternal( thread * thrd ) {325 get_this_processor()->finish.action_code = Schedule;326 get_this_processor()->finish.thrd = thrd;320 void ScheduleInternal( thread_desc * thrd ) { 321 this_processor->finish.action_code = Schedule; 322 this_processor->finish.thrd = thrd; 327 323 suspend(); 328 324 } 329 325 330 void ScheduleInternal( spinlock * lock, thread * thrd ) {331 get_this_processor()->finish.action_code = Release_Schedule;332 get_this_processor()->finish.lock = lock;333 get_this_processor()->finish.thrd = thrd;326 void ScheduleInternal( spinlock * lock, thread_desc * thrd ) { 327 this_processor->finish.action_code = Release_Schedule; 328 this_processor->finish.lock = lock; 329 this_processor->finish.thrd = thrd; 334 330 suspend(); 335 331 } … … 343 339 // SKULLDUGGERY: the mainThread steals the process main thread 344 340 // which will then be scheduled by the systemProcessor normally 345 mainThread = (thread *)&mainThread_storage;341 mainThread = (thread_desc *)&mainThread_storage; 346 342 current_stack_info_t info; 347 343 mainThread{ &info }; … … 440 436 this->condition = true; 441 437 442 thread * it;438 thread_desc * it; 443 439 while( it = pop_head( &this->blocked) ) { 444 440 ScheduleThread( it ); … … 455 451 } 456 452 457 void append( simple_thread_list * this, thread * t ) {453 void append( simple_thread_list * this, thread_desc * t ) { 458 454 assert(this->tail != NULL); 459 455 *this->tail = t; … … 461 457 } 462 458 463 thread * pop_head( simple_thread_list * this ) {464 thread * head = this->head;459 thread_desc * pop_head( simple_thread_list * this ) { 460 thread_desc * head = this->head; 465 461 if( head ) { 466 462 this->head = head->next; -
src/libcfa/concurrency/kernel_private.h
rbf4ac09 rf2e40a9f 6 6 // file "LICENCE" distributed with Cforall. 7 7 // 8 // threads--8 // kernel_private.h -- 9 9 // 10 10 // Author : Thierry Delisle … … 19 19 20 20 #include "kernel" 21 #include "thread s"21 #include "thread" 22 22 23 23 //----------------------------------------------------------------------------- 24 24 // Scheduler 25 void ScheduleThread( thread * );26 thread * nextThread(cluster * this);25 void ScheduleThread( thread_desc * ); 26 thread_desc * nextThread(cluster * this); 27 27 28 28 void ScheduleInternal(); 29 29 void ScheduleInternal(spinlock * lock); 30 void ScheduleInternal(thread * thrd);31 void ScheduleInternal(spinlock * lock, thread * thrd);30 void ScheduleInternal(thread_desc * thrd); 31 void ScheduleInternal(spinlock * lock, thread_desc * thrd); 32 32 33 33 //----------------------------------------------------------------------------- … … 35 35 struct processorCtx_t { 36 36 processor * proc; 37 coroutine c;37 coroutine_desc c; 38 38 }; 39 39 … … 42 42 void main(processorCtx_t *); 43 43 void start(processor * this); 44 void runThread(processor * this, thread * dst);44 void runThread(processor * this, thread_desc * dst); 45 45 void finishRunning(processor * this); 46 46 void spin(processor * this, unsigned int * spin_count); … … 53 53 } 54 54 55 extern void ThreadCtxSwitch(coroutine * src, coroutine* dst);55 extern void ThreadCtxSwitch(coroutine_desc * src, coroutine_desc * dst); 56 56 57 57 #endif //KERNEL_PRIVATE_H -
src/libcfa/concurrency/monitor
rbf4ac09 rf2e40a9f 22 22 #include "stdlib" 23 23 24 struct __monitor_t{24 struct monitor_desc { 25 25 spinlock lock; 26 thread * owner;26 thread_desc * owner; 27 27 simple_thread_list entry_queue; 28 28 unsigned int recursion; 29 29 }; 30 30 31 static inline void ?{}( __monitor_t* this) {31 static inline void ?{}(monitor_desc * this) { 32 32 this->owner = 0; 33 33 this->recursion = 0; … … 35 35 36 36 //Basic entering routine 37 void enter( __monitor_t*);38 void leave( __monitor_t*);37 void enter(monitor_desc *); 38 void leave(monitor_desc *); 39 39 40 40 //Array entering routine 41 void enter( __monitor_t**, int count);42 void leave( __monitor_t**, int count);41 void enter(monitor_desc **, int count); 42 void leave(monitor_desc **, int count); 43 43 44 44 struct monitor_guard_t { 45 __monitor_t** m;45 monitor_desc ** m; 46 46 int count; 47 47 }; 48 48 49 static inline int ?<?( __monitor_t* lhs, __monitor_t* rhs) {49 static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) { 50 50 return ((intptr_t)lhs) < ((intptr_t)rhs); 51 51 } 52 52 53 static inline void ?{}( monitor_guard_t * this, __monitor_t** m ) {53 static inline void ?{}( monitor_guard_t * this, monitor_desc ** m ) { 54 54 this->m = m; 55 55 this->count = 1; … … 57 57 } 58 58 59 static inline void ?{}( monitor_guard_t * this, __monitor_t** m, int count ) {59 static inline void ?{}( monitor_guard_t * this, monitor_desc ** m, int count ) { 60 60 this->m = m; 61 61 this->count = count; -
src/libcfa/concurrency/monitor.c
rbf4ac09 rf2e40a9f 6 6 // file "LICENCE" distributed with Cforall. 7 7 // 8 // __monitor_t.c --8 // monitor_desc.c -- 9 9 // 10 10 // Author : Thierry Delisle … … 19 19 #include "kernel_private.h" 20 20 21 void enter( __monitor_t* this) {21 void enter(monitor_desc * this) { 22 22 lock( &this->lock ); 23 thread * thrd = this_thread();23 thread_desc * thrd = this_thread(); 24 24 25 25 if( !this->owner ) { … … 45 45 } 46 46 47 void leave( __monitor_t* this) {47 void leave(monitor_desc * this) { 48 48 lock( &this->lock ); 49 49 50 thread * thrd = this_thread();50 thread_desc * thrd = this_thread(); 51 51 assert( thrd == this->owner ); 52 52 … … 55 55 56 56 //If we left the last level of recursion it means we are changing who owns the monitor 57 thread * new_owner = 0;57 thread_desc * new_owner = 0; 58 58 if( this->recursion == 0) { 59 59 //Get the next thread in the list … … 72 72 } 73 73 74 void enter( __monitor_t** monitors, int count) {74 void enter(monitor_desc ** monitors, int count) { 75 75 for(int i = 0; i < count; i++) { 76 76 // printf("%d\n", i); … … 79 79 } 80 80 81 void leave( __monitor_t** monitors, int count) {81 void leave(monitor_desc ** monitors, int count) { 82 82 for(int i = count - 1; i >= 0; i--) { 83 83 // printf("%d\n", i); -
src/libcfa/concurrency/thread
rbf4ac09 rf2e40a9f 6 6 // file "LICENCE" distributed with Cforall. 7 7 // 8 // thread s--8 // thread -- 9 9 // 10 10 // Author : Thierry Delisle … … 21 21 #include "invoke.h" 22 22 23 #include "coroutine s"23 #include "coroutine" 24 24 25 25 //----------------------------------------------------------------------------- … … 29 29 trait is_thread(dtype T) { 30 30 void main(T* this); 31 thread * get_thread(T* this);31 thread_desc* get_thread(T* this); 32 32 }; 33 33 34 #define DECL_THREAD(X) thread * get_thread(X* this) { return &this->t; } void main(X* this)34 #define DECL_THREAD(X) thread_desc* get_thread(X* this) { return &this->t; } void main(X* this) 35 35 36 36 forall( dtype T | is_thread(T) ) 37 static inline coroutine * get_coroutine(T* this) {37 static inline coroutine_desc* get_coroutine(T* this) { 38 38 return &get_thread(this)->c; 39 39 } 40 40 41 static inline coroutine * get_coroutine(thread* this) {41 static inline coroutine_desc* get_coroutine(thread_desc* this) { 42 42 return &this->c; 43 43 } 44 44 45 thread * this_thread(void);45 thread_desc * this_thread(void); 46 46 47 47 //----------------------------------------------------------------------------- 48 48 // Ctors and dtors 49 void ?{}(thread * this);50 void ^?{}(thread * this);49 void ?{}(thread_desc* this); 50 void ^?{}(thread_desc* this); 51 51 52 52 //----------------------------------------------------------------------------- -
src/libcfa/concurrency/thread.c
rbf4ac09 rf2e40a9f 6 6 // file "LICENCE" distributed with Cforall. 7 7 // 8 // thread s.c --8 // thread.c -- 9 9 // 10 10 // Author : Thierry Delisle … … 15 15 // 16 16 17 #include "thread s"17 #include "thread" 18 18 19 19 #include "kernel_private.h" … … 28 28 } 29 29 30 extern processor * get_this_processor();30 extern thread_local processor * this_processor; 31 31 32 32 //----------------------------------------------------------------------------- … … 41 41 // Thread ctors and dtors 42 42 43 void ?{}(thread * this) {43 void ?{}(thread_desc* this) { 44 44 (&this->c){}; 45 45 this->c.name = "Anonymous Coroutine"; … … 48 48 } 49 49 50 void ^?{}(thread * this) {50 void ^?{}(thread_desc* this) { 51 51 ^(&this->c){}; 52 52 } … … 74 74 forall( dtype T | is_thread(T) ) 75 75 void start( T* this ) { 76 coroutine * thrd_c = get_coroutine(this);77 thread * thrd_h = get_thread (this);76 coroutine_desc* thrd_c = get_coroutine(this); 77 thread_desc* thrd_h = get_thread (this); 78 78 thrd_c->last = this_coroutine(); 79 get_this_processor()->current_coroutine = thrd_c;79 this_processor->current_coroutine = thrd_c; 80 80 81 81 LIB_DEBUG_PRINTF("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h); … … 94 94 95 95 void yield( void ) { 96 ScheduleInternal( get_this_processor()->current_thread );96 ScheduleInternal( this_processor->current_thread ); 97 97 } 98 98 99 void ThreadCtxSwitch(coroutine * src, coroutine* dst) {99 void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) { 100 100 // set state of current coroutine to inactive 101 101 src->state = Inactive; … … 107 107 // set new coroutine that the processor is executing 108 108 // and context switch to it 109 get_this_processor()->current_coroutine = dst;109 this_processor->current_coroutine = dst; 110 110 CtxSwitch( src->stack.context, dst->stack.context ); 111 get_this_processor()->current_coroutine = src;111 this_processor->current_coroutine = src; 112 112 113 113 // set state of new coroutine to active … … 116 116 } 117 117 118 // C Helper to signal the termination of a thread 118 // C Helper to signal the termination of a thread_desc 119 119 // Used in invoke.c 120 120 extern "C" { 121 void __thread_signal_termination( thread * this ) {121 void __thread_signal_termination( thread_desc * this ) { 122 122 this->c.state = Halted; 123 123 LIB_DEBUG_PRINTF("Thread end : %p\n", this);
Note:
See TracChangeset
for help on using the changeset viewer.