Changes in src/libcfa/concurrency/kernel.c [8fcbb4c:77e6fcb]
- File:
-
- 1 edited
-
src/libcfa/concurrency/kernel.c (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/kernel.c
r8fcbb4c r77e6fcb 25 25 #include <stddef.h> 26 26 extern "C" { 27 #include <fenv.h>28 27 #include <sys/resource.h> 29 28 } … … 36 35 #define __CFA_INVOKE_PRIVATE__ 37 36 #include "invoke.h" 38 39 static volatile int lock;40 41 void spin_lock( volatile int *lock ) {42 for ( unsigned int i = 1;; i += 1 ) {43 if ( *lock == 0 && __sync_lock_test_and_set_4( lock, 1 ) == 0 ) break;44 }45 }46 47 void spin_unlock( volatile int *lock ) {48 __sync_lock_release_4( lock );49 }50 37 51 38 //----------------------------------------------------------------------------- … … 140 127 (&this->c){}; 141 128 this->proc = proc; 142 proc-> runner= this;129 proc->ctx = this; 143 130 } 144 131 … … 146 133 (&this->c){ info }; 147 134 this->proc = proc; 148 proc-> runner= this;135 proc->ctx = this; 149 136 } 150 137 … … 165 152 } 166 153 167 void ?{}(processor * this, cluster * cltr, processorCtx_t * runner) {154 void ?{}(processor * this, cluster * cltr, processorCtx_t * ctx) { 168 155 this->cltr = cltr; 169 156 this->current_coroutine = NULL; … … 172 159 this->terminated = false; 173 160 174 this-> runner = runner;175 LIB_DEBUG_PRINTF("Kernel : constructing processor context %p\n", runner);176 runner{ this };161 this->ctx = ctx; 162 LIB_DEBUG_PRINTF("Kernel : constructing processor context %p\n", ctx); 163 ctx{ this }; 177 164 } 178 165 … … 187 174 void ?{}(cluster * this) { 188 175 ( &this->ready_queue ){}; 189 lock = 0;176 pthread_spin_init( &this->lock, PTHREAD_PROCESS_PRIVATE ); 190 177 } 191 178 192 179 void ^?{}(cluster * this) { 193 180 pthread_spin_destroy( &this->lock ); 194 181 } 195 182 196 183 //----------------------------------------------------------------------------- 197 184 // Processor running routines 198 void main(processorCtx_t * );185 void main(processorCtx_t * ctx); 199 186 thread * nextThread(cluster * this); 200 187 void scheduleInternal(processor * this, thread * dst); 201 188 void spin(processor * this, unsigned int * spin_count); 202 void thread_schedule( thread * thrd ); 203 204 //Main of the processor contexts 205 void main(processorCtx_t * runner) { 206 processor * this = runner->proc; 189 190 void main(processorCtx_t * ctx) { 191 processor * this = ctx->proc; 207 192 LIB_DEBUG_PRINTF("Kernel : core %p starting\n", this); 208 209 fenv_t envp;210 fegetenv( &envp );211 LIB_DEBUG_PRINTF("Kernel : mxcsr %x\n", envp.__mxcsr);212 193 213 194 thread * readyThread = NULL; … … 235 216 // from the processor coroutine to the target thread 236 217 void scheduleInternal(processor * this, thread * dst) { 237 this->thread_action = NoAction;238 239 218 // coroutine * proc_ctx = get_coroutine(this->ctx); 240 219 // coroutine * thrd_ctx = get_coroutine(dst); … … 247 226 // // when ThreadCtxSwitch returns we are back in the processor coroutine 248 227 249 coroutine * proc_ctx = get_coroutine(this-> runner);228 coroutine * proc_ctx = get_coroutine(this->ctx); 250 229 coroutine * thrd_ctx = get_coroutine(dst); 251 230 thrd_ctx->last = proc_ctx; … … 253 232 // context switch to specified coroutine 254 233 // Which is now the current_coroutine 255 //LIB_DEBUG_PRINTF("Kernel : switching to ctx %p (from %p, current %p)\n", thrd_ctx, proc_ctx, this->current_coroutine);234 LIB_DEBUG_PRINTF("Kernel : switching to ctx %p (from %p, current %p)\n", thrd_ctx, proc_ctx, this->current_coroutine); 256 235 this->current_thread = dst; 257 236 this->current_coroutine = thrd_ctx; 258 237 CtxSwitch( proc_ctx->stack.context, thrd_ctx->stack.context ); 259 238 this->current_coroutine = proc_ctx; 260 //LIB_DEBUG_PRINTF("Kernel : returned from ctx %p (to %p, current %p)\n", thrd_ctx, proc_ctx, this->current_coroutine);239 LIB_DEBUG_PRINTF("Kernel : returned from ctx %p (to %p, current %p)\n", thrd_ctx, proc_ctx, this->current_coroutine); 261 240 262 241 // when CtxSwitch returns we are back in the processor coroutine 263 if(this->thread_action == Reschedule) {264 thread_schedule( dst );265 }266 242 } 267 243 … … 286 262 processorCtx_t proc_cor_storage = { proc, &info }; 287 263 288 LIB_DEBUG_PRINTF("Coroutine : created stack %p\n", proc_cor_storage.c.stack.base);289 290 264 //Set global state 291 proc->current_coroutine = &proc-> runner->c;265 proc->current_coroutine = &proc->ctx->c; 292 266 proc->current_thread = NULL; 293 267 294 268 //We now have a proper context from which to schedule threads 295 LIB_DEBUG_PRINTF("Kernel : core %p created (%p , %p)\n", proc, proc->runner, &ctx);269 LIB_DEBUG_PRINTF("Kernel : core %p created (%p)\n", proc, proc->ctx); 296 270 297 271 // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't … … 305 279 306 280 // Main routine of the core returned, the core is now fully terminated 307 LIB_DEBUG_PRINTF("Kernel : core %p main ended (%p)\n", proc, proc-> runner);281 LIB_DEBUG_PRINTF("Kernel : core %p main ended (%p)\n", proc, proc->ctx); 308 282 309 283 return NULL; … … 313 287 LIB_DEBUG_PRINTF("Kernel : Starting core %p\n", this); 314 288 315 //pthread_attr_t attributes;316 //pthread_attr_init( &attributes );317 318 pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this );319 320 //pthread_attr_destroy( &attributes );289 pthread_attr_t attributes; 290 pthread_attr_init( &attributes ); 291 292 pthread_create( &this->kernel_thread, &attributes, CtxInvokeProcessor, (void*)this ); 293 294 pthread_attr_destroy( &attributes ); 321 295 322 296 LIB_DEBUG_PRINTF("Kernel : core %p started\n", this); … … 328 302 assertf( thrd->next == NULL, "Expected null got %p", thrd->next ); 329 303 330 spin_lock( &lock );304 pthread_spinlock_guard guard = { &systemProcessor->cltr->lock }; 331 305 append( &systemProcessor->cltr->ready_queue, thrd ); 332 spin_unlock( &lock );333 306 } 334 307 335 308 thread * nextThread(cluster * this) { 336 spin_lock( &lock ); 337 thread * head = pop_head( &this->ready_queue ); 338 spin_unlock( &lock ); 339 return head; 309 pthread_spinlock_guard guard = { &this->lock }; 310 return pop_head( &this->ready_queue ); 340 311 } 341 312 … … 343 314 // Kernel boot procedures 344 315 void kernel_startup(void) { 345 LIB_DEBUG_PRINTF("Kernel : Starting\n"); 346 347 // Start by initializing the main thread 316 348 317 // SKULLDUGGERY: the mainThread steals the process main thread 349 318 // which will then be scheduled by the systemProcessor normally 319 LIB_DEBUG_PRINTF("Kernel : Starting\n"); 320 321 current_stack_info_t info; 322 323 // LIB_DEBUG_PRINTF("Kernel : core base : %p \n", info.base ); 324 // LIB_DEBUG_PRINTF("Kernel : core storage : %p \n", info.storage ); 325 // LIB_DEBUG_PRINTF("Kernel : core size : %x \n", info.size ); 326 // LIB_DEBUG_PRINTF("Kernel : core limit : %p \n", info.limit ); 327 // LIB_DEBUG_PRINTF("Kernel : core context : %p \n", info.context ); 328 // LIB_DEBUG_PRINTF("Kernel : core top : %p \n", info.top ); 329 330 // Start by initializing the main thread 350 331 mainThread = (thread *)&mainThread_storage; 351 current_stack_info_t info;352 332 mainThread{ &info }; 353 333 … … 373 353 // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that 374 354 // mainThread is on the ready queue when this call is made. 375 resume(systemProcessor-> runner);355 resume(systemProcessor->ctx); 376 356 377 357 378 358 379 359 // THE SYSTEM IS NOW COMPLETELY RUNNING 360 361 362 380 363 LIB_DEBUG_PRINTF("Kernel : Started\n--------------------------------------------------\n\n"); 381 364 } … … 394 377 // Destroy the system processor and its context in reverse order of construction 395 378 // These were manually constructed so we need manually destroy them 396 ^(systemProcessor-> runner){};379 ^(systemProcessor->ctx){}; 397 380 ^(systemProcessor){}; 398 381 … … 416 399 void lock( simple_lock * this ) { 417 400 { 418 spin_lock( &lock );401 pthread_spinlock_guard guard = { &systemCluster->lock }; //HUGE TEMP HACK which only works if we have a single cluster and is stupid 419 402 append( &this->blocked, this_thread() ); 420 spin_unlock( &lock );421 403 } 422 404 suspend();
Note:
See TracChangeset
for help on using the changeset viewer.