Changeset 0c92c9f for src/libcfa/concurrency
- Timestamp:
- Jan 27, 2017, 4:28:05 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:
- 8804701
- Parents:
- 0157ca7
- Location:
- src/libcfa/concurrency
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/coroutines
r0157ca7 r0c92c9f 65 65 66 66 // Private wrappers for context switch and stack creation 67 extern void corCxtSw(coroutine * src, coroutine * dst);67 extern void CoroutineCtxSwitch(coroutine * src, coroutine * dst); 68 68 extern void create_stack( coStack_t * this, unsigned int storageSize ); 69 69 … … 81 81 src->name, src, src->last->name, src->last ); 82 82 83 corCxtSw( src, src->last );83 CoroutineCtxSwitch( src, src->last ); 84 84 } 85 85 … … 107 107 108 108 // always done for performance testing 109 corCxtSw( src, dst );109 CoroutineCtxSwitch( src, dst ); 110 110 } 111 111 -
src/libcfa/concurrency/coroutines.c
r0157ca7 r0c92c9f 98 98 } 99 99 100 // We need to call suspend from invoke.c, so we expose this wrapper that 101 // is not inline (We can't inline Cforall in C) 102 void suspend_no_inline(void) { 103 suspend(); 104 } 105 106 void corCxtSw(coroutine* src, coroutine* dst) { 100 // Wrapper for co 101 void CoroutineCtxSwitch(coroutine* src, coroutine* dst) { 107 102 // THREAD_GETMEM( This )->disableInterrupts(); 108 103 … … 167 162 } 168 163 164 // We need to call suspend from invoke.c, so we expose this wrapper that 165 // is not inline (We can't inline Cforall in C) 166 extern "C" { 167 void __suspend_internal(void) { 168 suspend(); 169 } 170 } 171 169 172 // Local Variables: // 170 173 // mode: c // -
src/libcfa/concurrency/invoke.c
r0157ca7 r0c92c9f 28 28 // Called from the kernel when starting a coroutine or task so must switch back to user mode. 29 29 30 extern void __suspend_ no_inline__F___1(void);31 extern void __ signal_termination__F_P7sthread__1(struct thread*);30 extern void __suspend_internal(void); 31 extern void __thread_signal_termination(struct thread*); 32 32 33 33 void CtxInvokeCoroutine( … … 41 41 42 42 if(cor->state == Primed) { 43 __suspend_ no_inline__F___1();43 __suspend_internal(); 44 44 } 45 45 … … 52 52 53 53 //Final suspend, should never return 54 __suspend_ no_inline__F___1();55 a ssertf(false,"Resumed dead coroutine");54 __suspend_internal(); 55 abortf("Resumed dead coroutine"); 56 56 } 57 57 … … 61 61 void *this 62 62 ) { 63 // LIB_DEBUG_PRINTF("Invoke Thread : Received %p (main %p, get_t %p)\n", this, main, get_thread); 64 65 __suspend_no_inline__F___1(); 63 __suspend_internal(); 66 64 67 65 struct thread* thrd = get_thread( this ); … … 72 70 main( this ); 73 71 74 __ signal_termination__F_P7sthread__1(thrd);72 __thread_signal_termination(thrd); 75 73 76 74 //Final suspend, should never return 77 __suspend_ no_inline__F___1();78 a ssertf(false,"Resumed dead thread");75 __suspend_internal(); 76 abortf("Resumed dead thread"); 79 77 } 80 78 -
src/libcfa/concurrency/kernel.c
r0157ca7 r0c92c9f 15 15 // 16 16 17 //Start and stop routine for the kernel, declared first to make sure they run first 18 void kernel_startup(void) __attribute__((constructor(101))); 19 void kernel_shutdown(void) __attribute__((destructor(101))); 20 17 21 //Header 18 22 #include "kernel" … … 52 56 processor * systemProcessor; 53 57 thread * mainThread; 54 55 void kernel_startup(void) __attribute__((constructor(101)));56 void kernel_shutdown(void) __attribute__((destructor(101)));57 58 58 59 //----------------------------------------------------------------------------- … … 184 185 void main(processorCtx_t * ctx); 185 186 thread * nextThread(cluster * this); 186 void runThread(processor * this, thread * dst);187 void scheduleInternal(processor * this, thread * dst); 187 188 void spin(processor * this, unsigned int * spin_count); 188 189 … … 197 198 198 199 if(readyThread) { 199 runThread(this, readyThread);200 scheduleInternal(this, readyThread); 200 201 spin_count = 0; 201 202 } else { … … 209 210 } 210 211 211 void runThread(processor * this, thread * dst) { 212 //Declarations for scheduleInternal 213 extern void ThreadCtxSwitch(coroutine * src, coroutine * dst); 214 215 // scheduleInternal runs a thread by context switching 216 // from the processor coroutine to the target thread 217 void scheduleInternal(processor * this, thread * dst) { 218 // coroutine * proc_ctx = get_coroutine(this->ctx); 219 // coroutine * thrd_ctx = get_coroutine(dst); 220 221 // //Update global state 222 // this->current_thread = dst; 223 224 // // Context Switch to the thread 225 // ThreadCtxSwitch(proc_ctx, thrd_ctx); 226 // // when ThreadCtxSwitch returns we are back in the processor coroutine 227 212 228 coroutine * proc_ctx = get_coroutine(this->ctx); 213 229 coroutine * thrd_ctx = get_coroutine(dst); 214 thrd_ctx->last = proc_ctx; 215 216 // context switch to specified coroutine 217 // Which is now the current_coroutine 218 // LIB_DEBUG_PRINTF("Kernel : switching to ctx %p (from %p, current %p)\n", thrd_ctx, proc_ctx, current_coroutine); 219 this->current_thread = dst; 220 this->current_coroutine = thrd_ctx; 221 CtxSwitch( proc_ctx->stack.context, thrd_ctx->stack.context ); 222 this->current_coroutine = proc_ctx; 223 // LIB_DEBUG_PRINTF("Kernel : returned from ctx %p (to %p, current %p)\n", thrd_ctx, proc_ctx, current_coroutine); 224 225 // when CtxSwitch returns we are back in the processor coroutine 226 } 227 230 thrd_ctx->last = proc_ctx; 231 232 // context switch to specified coroutine 233 // Which is now the current_coroutine 234 LIB_DEBUG_PRINTF("Kernel : switching to ctx %p (from %p, current %p)\n", thrd_ctx, proc_ctx, this->current_coroutine); 235 this->current_thread = dst; 236 this->current_coroutine = thrd_ctx; 237 CtxSwitch( proc_ctx->stack.context, thrd_ctx->stack.context ); 238 this->current_coroutine = proc_ctx; 239 LIB_DEBUG_PRINTF("Kernel : returned from ctx %p (to %p, current %p)\n", thrd_ctx, proc_ctx, this->current_coroutine); 240 241 // when CtxSwitch returns we are back in the processor coroutine 242 } 243 244 // Handles spinning logic 245 // TODO : find some strategy to put cores to sleep after some time 228 246 void spin(processor * this, unsigned int * spin_count) { 229 247 (*spin_count)++; 230 248 } 231 249 250 // Context invoker for processors 251 // This is the entry point for processors (kernel threads) 252 // It effectively constructs a coroutine by stealing the pthread stack 232 253 void * CtxInvokeProcessor(void * arg) { 233 254 processor * proc = (processor *) arg; … … 241 262 processorCtx_t proc_cor_storage = { proc, &info }; 242 263 264 //Set global state 243 265 proc->current_coroutine = &proc->ctx->c; 244 266 proc->current_thread = NULL; 245 267 268 //We now have a proper context from which to schedule threads 246 269 LIB_DEBUG_PRINTF("Kernel : core %p created (%p)\n", proc, proc->ctx); 247 248 // LIB_DEBUG_PRINTF("Kernel : core base : %p \n", info.base );249 // LIB_DEBUG_PRINTF("Kernel : core storage : %p \n", info.storage );250 // LIB_DEBUG_PRINTF("Kernel : core size : %x \n", info.size );251 // LIB_DEBUG_PRINTF("Kernel : core limit : %p \n", info.limit );252 // LIB_DEBUG_PRINTF("Kernel : core context : %p \n", info.context );253 // LIB_DEBUG_PRINTF("Kernel : core top : %p \n", info.top );254 255 //We now have a proper context from which to schedule threads256 270 257 271 // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't … … 264 278 proc_cor_storage.c.notHalted = false; 265 279 280 // Main routine of the core returned, the core is now fully terminated 266 281 LIB_DEBUG_PRINTF("Kernel : core %p main ended (%p)\n", proc, proc->ctx); 267 282 -
src/libcfa/concurrency/threads
r0157ca7 r0c92c9f 27 27 // Anything that implements this trait can be resumed. 28 28 // Anything that is resumed is a coroutine. 29 trait is_thread(dtype T | sized(T)) {29 trait is_thread(dtype T) { 30 30 void main(T* this); 31 31 thread* get_thread(T* this); 32 32 }; 33 33 34 #define DECL_THREAD(X) static inlinethread* get_thread(X* this) { return &this->t; } void main(X* this);34 #define DECL_THREAD(X) thread* get_thread(X* this) { return &this->t; } void main(X* this); 35 35 36 forall( dtype T | sized(T) |is_thread(T) )36 forall( dtype T | is_thread(T) ) 37 37 static inline coroutine* get_coroutine(T* this) { 38 38 return &get_thread(this)->c; -
src/libcfa/concurrency/threads.c
r0157ca7 r0c92c9f 31 31 //----------------------------------------------------------------------------- 32 32 // Forward declarations 33 forall( dtype T | sized(T) |is_thread(T) )33 forall( dtype T | is_thread(T) ) 34 34 void start( T* this ); 35 35 36 forall( dtype T | sized(T) |is_thread(T) )36 forall( dtype T | is_thread(T) ) 37 37 void stop( T* this ); 38 38 … … 78 78 extern void thread_schedule( thread * ); 79 79 80 forall( dtype T | sized(T) |is_thread(T) )80 forall( dtype T | is_thread(T) ) 81 81 void start( T* this ) { 82 82 coroutine* thrd_c = get_coroutine(this); … … 85 85 get_this_processor()->current_coroutine = thrd_c; 86 86 87 // LIB_DEBUG_PRINTF("Thread start : %p (t %p, c %p)\n", handle, thrd_c, thrd_h);87 LIB_DEBUG_PRINTF("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h); 88 88 89 89 create_stack(&thrd_c->stack, thrd_c->stack.size); … … 91 91 CtxSwitch( thrd_c->last->stack.context, thrd_c->stack.context ); 92 92 93 LIB_DEBUG_PRINTF("Thread started : %p (t %p, c %p)\n", this, thrd_c, thrd_h); 94 93 95 thread_schedule(thrd_h); 94 96 } 95 97 96 forall( dtype T | sized(T) |is_thread(T) )98 forall( dtype T | is_thread(T) ) 97 99 void stop( T* this ) { 98 100 thread* thrd = get_thread(this); … … 102 104 } 103 105 104 void signal_termination( thread * this ) {105 this->c.state = Halt;106 this->c.notHalted = false;107 unlock( &this->lock );108 }109 110 106 void yield( void ) { 111 107 thread_schedule( this_thread() ); 112 108 suspend(); 109 } 110 111 void ThreadCtxSwitch(coroutine* src, coroutine* dst) { 112 dst->last = src; 113 114 // set state of current coroutine to inactive 115 src->state = Inactive; 116 117 // set new coroutine that task is executing 118 get_this_processor()->current_coroutine = dst; 119 120 // context switch to specified coroutine 121 CtxSwitch( src->stack.context, dst->stack.context ); 122 // when CtxSwitch returns we are back in the src coroutine 123 124 // set state of new coroutine to active 125 src->state = Active; 126 } 127 128 // C Helper to signal the termination of a thread 129 // Used in invoke.c 130 extern "C" { 131 void __thread_signal_termination( thread * this ) { 132 this->c.state = Halt; 133 this->c.notHalted = false; 134 unlock( &this->lock ); 135 } 113 136 } 114 137
Note: See TracChangeset
for help on using the changeset viewer.