Changes in src/libcfa/concurrency/kernel.c [eb2e723:aed3f54]
- File:
-
- 1 edited
-
src/libcfa/concurrency/kernel.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/kernel.c
reb2e723 raed3f54 1 // -*- Mode: CFA -*-2 //3 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo4 //5 // The contents of this file are covered under the licence agreement in the6 // file "LICENCE" distributed with Cforall.7 //8 // kernel.c --9 //10 // Author : Thierry Delisle11 // Created On : Tue Jan 17 12:27:26 201612 // Last Modified By : Thierry Delisle13 // Last Modified On : --14 // Update Count : 015 //16 17 //Header18 #include "kernel"19 20 //C Includes21 #include <stddef.h>22 extern "C" {23 #include <sys/resource.h>24 }25 26 //CFA Includes27 #include "libhdr.h"28 #include "threads"29 30 //Private includes31 #define __CFA_INVOKE_PRIVATE__32 #include "invoke.h"33 34 processor * systemProcessor;35 thread_h * mainThread;36 37 void kernel_startup(void) __attribute__((constructor(101)));38 void kernel_shutdown(void) __attribute__((destructor(101)));39 40 void ?{}(processor * this) {41 this->ctx = NULL;42 this->thread_index = 0;43 this->thread_count = 10;44 this->terminated = false;45 46 for(int i = 0; i < 10; i++) {47 this->threads[i] = NULL;48 }49 50 LIB_DEBUG_PRINTF("Processor : ctor for core %p (core spots %d)\n", this, this->thread_count);51 }52 53 void ^?{}(processor * this) {54 55 }56 57 //-----------------------------------------------------------------------------58 // Processor coroutine59 struct processorCtx_t {60 processor * proc;61 coroutine c;62 };63 64 DECL_COROUTINE(processorCtx_t)65 66 void ?{}(processorCtx_t * this, processor * proc) {67 (&this->c){};68 this->proc = proc;69 }70 71 void CtxInvokeProcessor(processor * proc) {72 processorCtx_t proc_cor_storage = {proc};73 resume( &proc_cor_storage );74 }75 76 //-----------------------------------------------------------------------------77 // Processor running routines78 void main(processorCtx_t * ctx);79 thread_h * nextThread(processor * this);80 void runThread(processor * this, thread_h * dst);81 void spin(processor * this, unsigned int * spin_count);82 83 void main(processorCtx_t * ctx) {84 processor * this = ctx->proc;85 LIB_DEBUG_PRINTF("Kernel : core %p starting\n", this);86 87 thread_h * readyThread = NULL;88 for( unsigned int spin_count = 0; ! this->terminated; spin_count++ ) {89 90 readyThread = nextThread(this);91 92 if(readyThread) {93 runThread(this, readyThread);94 spin_count = 0;95 } else {96 spin(this, &spin_count);97 }98 }99 100 LIB_DEBUG_PRINTF("Kernel : core %p terminated\n", this);101 }102 103 thread_h * nextThread(processor * this) {104 for(int i = 0; i < this->thread_count; i++) {105 this->thread_index = (this->thread_index + 1) % this->thread_count;106 107 thread_h * thrd = this->threads[this->thread_index];108 if(thrd) return thrd;109 }110 111 return NULL;112 }113 114 void runThread(processor * this, thread_h * dst) {115 coroutine * proc_ctx = get_coroutine(this->ctx);116 coroutine * thrd_ctx = get_coroutine(dst);117 thrd_ctx->last = proc_ctx;118 119 // context switch to specified coroutine120 // Which is now the current_coroutine121 LIB_DEBUG_PRINTF("Kernel : switching to ctx %p (from %p, current %p)\n", thrd_ctx, proc_ctx, current_coroutine);122 current_coroutine = thrd_ctx;123 CtxSwitch( proc_ctx->stack.context, thrd_ctx->stack.context );124 current_coroutine = proc_ctx;125 LIB_DEBUG_PRINTF("Kernel : returned from ctx %p (to %p, current %p)\n", thrd_ctx, proc_ctx, current_coroutine);126 127 // when CtxSwitch returns we are back in the processor coroutine128 }129 130 void spin(processor * this, unsigned int * spin_count) {131 (*spin_count)++;132 }133 134 //-----------------------------------------------------------------------------135 // Kernel runner (Temporary)136 137 void scheduler_add( thread_h * thrd ) {138 LIB_DEBUG_PRINTF("Kernel : scheduling %p on core %p (%d spots)\n", thrd, systemProcessor, systemProcessor->thread_count);139 for(int i = 0; i < systemProcessor->thread_count; i++) {140 if(systemProcessor->threads[i] == NULL) {141 systemProcessor->threads[i] = thrd;142 return;143 }144 }145 assert(false);146 }147 148 void scheduler_remove( thread_h * thrd ) {149 LIB_DEBUG_PRINTF("Kernel : unscheduling %p from core %p\n", thrd, systemProcessor);150 for(int i = 0; i < systemProcessor->thread_count; i++) {151 if(systemProcessor->threads[i] == thrd) {152 systemProcessor->threads[i] = NULL;153 break;154 }155 }156 for(int i = 0; i < systemProcessor->thread_count; i++) {157 if(systemProcessor->threads[i] != NULL) {158 return;159 }160 }161 LIB_DEBUG_PRINTF("Kernel : terminating core %p\n", systemProcessor);162 systemProcessor->terminated = true;163 }164 165 //-----------------------------------------------------------------------------166 // Kernel storage167 #define KERNEL_STORAGE(T,X) static char X##_storage[sizeof(T)]168 169 KERNEL_STORAGE(processorCtx_t, systemProcessorCtx);170 KERNEL_STORAGE(processor, systemProcessor);171 KERNEL_STORAGE(thread_h, mainThread);172 KERNEL_STORAGE(machine_context_t, mainThread_context);173 174 //-----------------------------------------------------------------------------175 // Main thread construction176 struct mainThread_info_t {177 machine_context_t ctx;178 unsigned int size; // size of stack179 void *base; // base of stack180 void *storage; // pointer to stack181 void *limit; // stack grows towards stack limit182 void *context; // address of cfa_context_t183 void *top; // address of top of storage184 };185 186 void ?{}( mainThread_info_t * this ) {187 CtxGet( &this->ctx );188 this->base = this->ctx.FP;189 this->storage = this->ctx.SP;190 191 rlimit r;192 int ret = getrlimit( RLIMIT_STACK, &r);193 this->size = r.rlim_cur;194 195 this->limit = (void *)(((intptr_t)this->base) - this->size);196 this->context = &mainThread_context_storage;197 this->top = this->base;198 }199 200 void ?{}( coStack_t * this, mainThread_info_t * info) {201 this->size = info->size;202 this->storage = info->storage;203 this->limit = info->limit;204 this->base = info->base;205 this->context = info->context;206 this->top = info->top;207 this->userStack = true;208 }209 210 void ?{}( coroutine * this, mainThread_info_t * info) {211 (&this->stack){ info };212 this->name = "Main Thread";213 this->errno_ = 0;214 this->state = Inactive;215 this->notHalted = true;216 }217 218 void ?{}( thread_h * this, mainThread_info_t * info) {219 (&this->c){ info };220 }221 222 //-----------------------------------------------------------------------------223 // Kernel boot procedures224 void kernel_startup(void) {225 226 // SKULLDUGGERY: the mainThread steals the process main thread227 // which will then be scheduled by the systemProcessor normally228 LIB_DEBUG_PRINTF("Kernel : Starting\n");229 230 mainThread_info_t ctx;231 LIB_DEBUG_PRINTF("Kernel : base : %p\n", ctx.base );232 LIB_DEBUG_PRINTF("Kernel : top : %p\n", ctx.top );233 LIB_DEBUG_PRINTF("Kernel : limit : %p\n", ctx.limit );234 LIB_DEBUG_PRINTF("Kernel : size : %x\n", ctx.size );235 LIB_DEBUG_PRINTF("Kernel : storage : %p\n", ctx.storage );236 LIB_DEBUG_PRINTF("Kernel : context : %p\n", ctx.context );237 238 // Start by initializing the main thread239 mainThread = (thread_h *)&mainThread_storage;240 LIB_DEBUG_PRINTF("Kernel : Main thread : %p\n", mainThread );241 mainThread{ &ctx };242 243 // // Initialize the system processor244 systemProcessor = (processor *)&systemProcessor_storage;245 systemProcessor{};246 247 // Initialize the system processor ctx248 // (the coroutine that contains the processing control flow)249 systemProcessor->ctx = (processorCtx_t *)&systemProcessorCtx_storage;250 systemProcessor->ctx{ systemProcessor };251 252 scheduler_add(mainThread);253 254 current_coroutine = &mainThread->c;255 256 LIB_DEBUG_PRINTF("Kernel : Starting system processor\n");257 resume(systemProcessor->ctx);258 259 LIB_DEBUG_PRINTF("Kernel : Started\n--------------------------------------------------\n\n");260 }261 void kernel_shutdown(void) {262 LIB_DEBUG_PRINTF("\n--------------------------------------------------\nKernel : Shutting down");263 264 LIB_DEBUG_PRINTF("Unscheduling main thread\n");265 scheduler_remove(mainThread);266 267 LIB_DEBUG_PRINTF("Suspending main\n");268 suspend();269 270 LIB_DEBUG_PRINTF("Kernel : Control return to initial process thread\n");271 272 ^(systemProcessor->ctx){};273 ^(systemProcessor){};274 275 ^(mainThread){};276 277 LIB_DEBUG_PRINTF("Kernel : Shutdown complete\n");278 }279 280 // Local Variables: //281 // mode: c //282 // tab-width: 4 //283 // End: //
Note:
See TracChangeset
for help on using the changeset viewer.