Changeset 4a3386b4 for src/libcfa/concurrency/kernel.c
- Timestamp:
- Jan 19, 2017, 2:56:51 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:
- 8f49a54
- Parents:
- 765aa76 (diff), c2416d5 (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/kernel.c
r765aa76 r4a3386b4 1 // -*- Mode: CFA -*- 2 // 3 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo 4 // 5 // The contents of this file are covered under the licence agreement in the 6 // file "LICENCE" distributed with Cforall. 7 // 8 // kernel.c -- 9 // 10 // Author : Thierry Delisle 11 // Created On : Tue Jan 17 12:27:26 2016 12 // Last Modified By : Thierry Delisle 13 // Last Modified On : -- 14 // Update Count : 0 15 // 16 17 //Header 18 #include "kernel" 19 20 //C Includes 21 #include <stddef.h> 22 extern "C" { 23 #include <sys/resource.h> 24 } 25 26 //CFA Includes 27 #include "libhdr.h" 28 #include "threads" 29 30 //Private includes 31 #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 coroutine 59 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 routines 78 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 coroutine 120 // Which is now the current_coroutine 121 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 coroutine 128 } 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 storage 167 #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 construction 176 struct mainThread_info_t { 177 machine_context_t ctx; 178 unsigned int size; // size of stack 179 void *base; // base of stack 180 void *storage; // pointer to stack 181 void *limit; // stack grows towards stack limit 182 void *context; // address of cfa_context_t 183 void *top; // address of top of storage 184 }; 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 procedures 224 void kernel_startup(void) { 225 226 // SKULLDUGGERY: the mainThread steals the process main thread 227 // which will then be scheduled by the systemProcessor normally 228 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 thread 239 mainThread = (thread_h *)&mainThread_storage; 240 LIB_DEBUG_PRINTF("Kernel : Main thread : %p\n", mainThread ); 241 mainThread{ &ctx }; 242 243 // // Initialize the system processor 244 systemProcessor = (processor *)&systemProcessor_storage; 245 systemProcessor{}; 246 247 // Initialize the system processor ctx 248 // (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.