Changes in / [8804701:0a86a30]
- Location:
- src
- Files:
-
- 1 added
- 2 deleted
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/coroutines
r8804701 r0a86a30 65 65 66 66 // Private wrappers for context switch and stack creation 67 extern void CoroutineCtxSwitch(coroutine * src, coroutine * dst);67 extern void corCxtSw(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 CoroutineCtxSwitch( src, src->last );83 corCxtSw( src, src->last ); 84 84 } 85 85 … … 107 107 108 108 // always done for performance testing 109 CoroutineCtxSwitch( src, dst );109 corCxtSw( src, dst ); 110 110 } 111 111 -
src/libcfa/concurrency/coroutines.c
r8804701 r0a86a30 98 98 } 99 99 100 // Wrapper for co 101 void CoroutineCtxSwitch(coroutine* src, coroutine* dst) { 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) { 102 107 // THREAD_GETMEM( This )->disableInterrupts(); 103 108 … … 162 167 } 163 168 164 // We need to call suspend from invoke.c, so we expose this wrapper that165 // is not inline (We can't inline Cforall in C)166 extern "C" {167 void __suspend_internal(void) {168 suspend();169 }170 }171 172 169 // Local Variables: // 173 170 // mode: c // -
src/libcfa/concurrency/invoke.c
r8804701 r0a86a30 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_ internal(void);31 extern void __ thread_signal_termination(struct thread*);30 extern void __suspend_no_inline__F___1(void); 31 extern void __signal_termination__F_P7sthread__1(struct thread*); 32 32 33 33 void CtxInvokeCoroutine( … … 41 41 42 42 if(cor->state == Primed) { 43 __suspend_ internal();43 __suspend_no_inline__F___1(); 44 44 } 45 45 … … 52 52 53 53 //Final suspend, should never return 54 __suspend_ internal();55 a bortf("Resumed dead coroutine");54 __suspend_no_inline__F___1(); 55 assertf(false, "Resumed dead coroutine"); 56 56 } 57 57 … … 61 61 void *this 62 62 ) { 63 __suspend_internal(); 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(); 64 66 65 67 struct thread* thrd = get_thread( this ); … … 70 72 main( this ); 71 73 72 __ thread_signal_termination(thrd);74 __signal_termination__F_P7sthread__1(thrd); 73 75 74 76 //Final suspend, should never return 75 __suspend_ internal();76 a bortf("Resumed dead thread");77 __suspend_no_inline__F___1(); 78 assertf(false, "Resumed dead thread"); 77 79 } 78 80 -
src/libcfa/concurrency/kernel.c
r8804701 r0a86a30 15 15 // 16 16 17 //Start and stop routine for the kernel, declared first to make sure they run first18 void kernel_startup(void) __attribute__((constructor(101)));19 void kernel_shutdown(void) __attribute__((destructor(101)));20 21 17 //Header 22 18 #include "kernel" … … 56 52 processor * systemProcessor; 57 53 thread * mainThread; 54 55 void kernel_startup(void) __attribute__((constructor(101))); 56 void kernel_shutdown(void) __attribute__((destructor(101))); 58 57 59 58 //----------------------------------------------------------------------------- … … 185 184 void main(processorCtx_t * ctx); 186 185 thread * nextThread(cluster * this); 187 void scheduleInternal(processor * this, thread * dst);186 void runThread(processor * this, thread * dst); 188 187 void spin(processor * this, unsigned int * spin_count); 189 188 … … 198 197 199 198 if(readyThread) { 200 scheduleInternal(this, readyThread);199 runThread(this, readyThread); 201 200 spin_count = 0; 202 201 } else { … … 210 209 } 211 210 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 211 void runThread(processor * this, thread * dst) { 228 212 coroutine * proc_ctx = get_coroutine(this->ctx); 229 213 coroutine * thrd_ctx = get_coroutine(dst); 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 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 246 228 void spin(processor * this, unsigned int * spin_count) { 247 229 (*spin_count)++; 248 230 } 249 231 250 // Context invoker for processors251 // This is the entry point for processors (kernel threads)252 // It effectively constructs a coroutine by stealing the pthread stack253 232 void * CtxInvokeProcessor(void * arg) { 254 233 processor * proc = (processor *) arg; … … 262 241 processorCtx_t proc_cor_storage = { proc, &info }; 263 242 264 //Set global state265 243 proc->current_coroutine = &proc->ctx->c; 266 244 proc->current_thread = NULL; 267 245 246 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 268 255 //We now have a proper context from which to schedule threads 269 LIB_DEBUG_PRINTF("Kernel : core %p created (%p)\n", proc, proc->ctx);270 256 271 257 // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't … … 278 264 proc_cor_storage.c.notHalted = false; 279 265 280 // Main routine of the core returned, the core is now fully terminated281 266 LIB_DEBUG_PRINTF("Kernel : core %p main ended (%p)\n", proc, proc->ctx); 282 267 -
src/libcfa/concurrency/threads
r8804701 r0a86a30 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 ) {29 trait is_thread(dtype T | sized(T)) { 30 30 void main(T* this); 31 31 thread* 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) static inline thread* get_thread(X* this) { return &this->t; } void main(X* this); 35 35 36 forall( dtype T | is_thread(T) )36 forall( dtype T | sized(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
r8804701 r0a86a30 31 31 //----------------------------------------------------------------------------- 32 32 // Forward declarations 33 forall( dtype T | is_thread(T) )33 forall( dtype T | sized(T) | is_thread(T) ) 34 34 void start( T* this ); 35 35 36 forall( dtype T | is_thread(T) )36 forall( dtype T | sized(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 | is_thread(T) )80 forall( dtype T | sized(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", this, thrd_c, thrd_h);87 // LIB_DEBUG_PRINTF("Thread start : %p (t %p, c %p)\n", handle, 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 95 93 thread_schedule(thrd_h); 96 94 } 97 95 98 forall( dtype T | is_thread(T) )96 forall( dtype T | sized(T) | is_thread(T) ) 99 97 void stop( T* this ) { 100 98 thread* thrd = get_thread(this); … … 104 102 } 105 103 104 void signal_termination( thread * this ) { 105 this->c.state = Halt; 106 this->c.notHalted = false; 107 unlock( &this->lock ); 108 } 109 106 110 void yield( void ) { 107 111 thread_schedule( this_thread() ); 108 112 suspend(); 109 }110 111 void ThreadCtxSwitch(coroutine* src, coroutine* dst) {112 dst->last = src;113 114 // set state of current coroutine to inactive115 src->state = Inactive;116 117 // set new coroutine that task is executing118 get_this_processor()->current_coroutine = dst;119 120 // context switch to specified coroutine121 CtxSwitch( src->stack.context, dst->stack.context );122 // when CtxSwitch returns we are back in the src coroutine123 124 // set state of new coroutine to active125 src->state = Active;126 }127 128 // C Helper to signal the termination of a thread129 // Used in invoke.c130 extern "C" {131 void __thread_signal_termination( thread * this ) {132 this->c.state = Halt;133 this->c.notHalted = false;134 unlock( &this->lock );135 }136 113 } 137 114
Note: See TracChangeset
for help on using the changeset viewer.