Changes in src/libcfa/concurrency/kernel.c [b10affd:094476d]
- File:
-
- 1 edited
-
src/libcfa/concurrency/kernel.c (modified) (32 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/kernel.c
rb10affd r094476d 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 30 18:26:11201813 // Update Count : 2312 // Last Modified On : Thu Feb 8 23:52:19 2018 13 // Update Count : 5 14 14 // 15 15 … … 52 52 // Global state 53 53 54 thread_local coroutine_desc * volatile this_coroutine; 55 thread_local thread_desc * volatile this_thread; 56 thread_local processor * volatile this_processor; 57 54 58 // volatile thread_local bool preemption_in_progress = 0; 55 59 // volatile thread_local bool preemption_enabled = false; 56 60 // volatile thread_local unsigned short disable_preempt_count = 1; 57 61 58 thread_local struct KernelThreadData kernelThreadData = { 59 NULL, 60 NULL, 61 NULL, 62 { 1, false, false } 63 }; 62 volatile thread_local __cfa_kernel_preemption_state_t preemption_state = { false, false, 1 }; 64 63 65 64 //----------------------------------------------------------------------------- … … 173 172 terminate(&this); 174 173 verify(this.do_terminate); 175 verify( TL_GET( this_processor )!= &this);174 verify(this_processor != &this); 176 175 P( terminated ); 177 verify( TL_GET( this_processor )!= &this);176 verify(this_processor != &this); 178 177 pthread_join( kernel_thread, NULL ); 179 178 } … … 214 213 if(readyThread) 215 214 { 216 verify( ! TL_GET( preemption_state ).enabled );215 verify( !preemption_state.enabled ); 217 216 218 217 runThread(this, readyThread); 219 218 220 verify( ! TL_GET( preemption_state ).enabled );219 verify( !preemption_state.enabled ); 221 220 222 221 //Some actions need to be taken from the kernel … … 250 249 251 250 //Update global state 252 TL_SET( this_thread, dst );251 this_thread = dst; 253 252 254 253 // Context Switch to the thread … … 258 257 259 258 void returnToKernel() { 260 coroutine_desc * proc_cor = get_coroutine( TL_GET( this_processor )->runner);261 coroutine_desc * thrd_cor = TL_GET( this_thread )->curr_cor = TL_GET( this_coroutine );259 coroutine_desc * proc_cor = get_coroutine(this_processor->runner); 260 coroutine_desc * thrd_cor = this_thread->curr_cor = this_coroutine; 262 261 ThreadCtxSwitch(thrd_cor, proc_cor); 263 262 } … … 267 266 void finishRunning(processor * this) with( this->finish ) { 268 267 if( action_code == Release ) { 269 verify( ! TL_GET( preemption_state ).enabled );268 verify( !preemption_state.enabled ); 270 269 unlock( *lock ); 271 270 } … … 274 273 } 275 274 else if( action_code == Release_Schedule ) { 276 verify( ! TL_GET( preemption_state ).enabled );275 verify( !preemption_state.enabled ); 277 276 unlock( *lock ); 278 277 ScheduleThread( thrd ); 279 278 } 280 279 else if( action_code == Release_Multi ) { 281 verify( ! TL_GET( preemption_state ).enabled );280 verify( !preemption_state.enabled ); 282 281 for(int i = 0; i < lock_count; i++) { 283 282 unlock( *locks[i] ); … … 308 307 void * CtxInvokeProcessor(void * arg) { 309 308 processor * proc = (processor *) arg; 310 TL_SET( this_processor, proc );311 TL_SET( this_coroutine, NULL );312 TL_SET( this_thread, NULL );313 TL_GET( preemption_state ).enabled = false;314 TL_GET( preemption_state ).disable_count = 1;309 this_processor = proc; 310 this_coroutine = NULL; 311 this_thread = NULL; 312 preemption_state.enabled = false; 313 preemption_state.disable_count = 1; 315 314 // SKULLDUGGERY: We want to create a context for the processor coroutine 316 315 // which is needed for the 2-step context switch. However, there is no reason … … 324 323 325 324 //Set global state 326 TL_SET( this_coroutine, get_coroutine(proc->runner));327 TL_SET( this_thread, NULL );325 this_coroutine = get_coroutine(proc->runner); 326 this_thread = NULL; 328 327 329 328 //We now have a proper context from which to schedule threads … … 353 352 354 353 void kernel_first_resume(processor * this) { 355 coroutine_desc * src = TL_GET( this_coroutine );354 coroutine_desc * src = this_coroutine; 356 355 coroutine_desc * dst = get_coroutine(this->runner); 357 356 358 verify( ! TL_GET( preemption_state ).enabled );357 verify( !preemption_state.enabled ); 359 358 360 359 create_stack(&dst->stack, dst->stack.size); 361 360 CtxStart(&this->runner, CtxInvokeCoroutine); 362 361 363 verify( ! TL_GET( preemption_state ).enabled );362 verify( !preemption_state.enabled ); 364 363 365 364 dst->last = src; … … 370 369 371 370 // set new coroutine that task is executing 372 TL_SET( this_coroutine, dst );371 this_coroutine = dst; 373 372 374 373 // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch. … … 387 386 src->state = Active; 388 387 389 verify( ! TL_GET( preemption_state ).enabled );388 verify( !preemption_state.enabled ); 390 389 } 391 390 … … 393 392 // Scheduler routines 394 393 void ScheduleThread( thread_desc * thrd ) { 395 // if( ! thrd ) return;394 // if( !thrd ) return; 396 395 verify( thrd ); 397 396 verify( thrd->self_cor.state != Halted ); 398 397 399 verify( ! TL_GET( preemption_state ).enabled );398 verify( !preemption_state.enabled ); 400 399 401 400 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 402 401 403 with( * TL_GET( this_processor )->cltr ) {402 with( *this_processor->cltr ) { 404 403 lock ( ready_queue_lock __cfaabi_dbg_ctx2 ); 405 404 append( ready_queue, thrd ); … … 407 406 } 408 407 409 verify( ! TL_GET( preemption_state ).enabled );408 verify( !preemption_state.enabled ); 410 409 } 411 410 412 411 thread_desc * nextThread(cluster * this) with( *this ) { 413 verify( ! TL_GET( preemption_state ).enabled );412 verify( !preemption_state.enabled ); 414 413 lock( ready_queue_lock __cfaabi_dbg_ctx2 ); 415 414 thread_desc * head = pop_head( ready_queue ); 416 415 unlock( ready_queue_lock ); 417 verify( ! TL_GET( preemption_state ).enabled );416 verify( !preemption_state.enabled ); 418 417 return head; 419 418 } … … 421 420 void BlockInternal() { 422 421 disable_interrupts(); 423 verify( ! TL_GET( preemption_state ).enabled );422 verify( !preemption_state.enabled ); 424 423 returnToKernel(); 425 verify( ! TL_GET( preemption_state ).enabled );424 verify( !preemption_state.enabled ); 426 425 enable_interrupts( __cfaabi_dbg_ctx ); 427 426 } … … 429 428 void BlockInternal( __spinlock_t * lock ) { 430 429 disable_interrupts(); 431 TL_GET( this_processor )->finish.action_code = Release;432 TL_GET( this_processor )->finish.lock = lock;433 434 verify( ! TL_GET( preemption_state ).enabled );430 this_processor->finish.action_code = Release; 431 this_processor->finish.lock = lock; 432 433 verify( !preemption_state.enabled ); 435 434 returnToKernel(); 436 verify( ! TL_GET( preemption_state ).enabled );435 verify( !preemption_state.enabled ); 437 436 438 437 enable_interrupts( __cfaabi_dbg_ctx ); … … 441 440 void BlockInternal( thread_desc * thrd ) { 442 441 disable_interrupts(); 443 TL_GET( this_processor )->finish.action_code = Schedule;444 TL_GET( this_processor )->finish.thrd = thrd;445 446 verify( ! TL_GET( preemption_state ).enabled );442 this_processor->finish.action_code = Schedule; 443 this_processor->finish.thrd = thrd; 444 445 verify( !preemption_state.enabled ); 447 446 returnToKernel(); 448 verify( ! TL_GET( preemption_state ).enabled );447 verify( !preemption_state.enabled ); 449 448 450 449 enable_interrupts( __cfaabi_dbg_ctx ); … … 454 453 assert(thrd); 455 454 disable_interrupts(); 456 TL_GET( this_processor )->finish.action_code = Release_Schedule;457 TL_GET( this_processor )->finish.lock = lock;458 TL_GET( this_processor )->finish.thrd = thrd;459 460 verify( ! TL_GET( preemption_state ).enabled );455 this_processor->finish.action_code = Release_Schedule; 456 this_processor->finish.lock = lock; 457 this_processor->finish.thrd = thrd; 458 459 verify( !preemption_state.enabled ); 461 460 returnToKernel(); 462 verify( ! TL_GET( preemption_state ).enabled );461 verify( !preemption_state.enabled ); 463 462 464 463 enable_interrupts( __cfaabi_dbg_ctx ); … … 467 466 void BlockInternal(__spinlock_t * locks [], unsigned short count) { 468 467 disable_interrupts(); 469 TL_GET( this_processor )->finish.action_code = Release_Multi;470 TL_GET( this_processor )->finish.locks = locks;471 TL_GET( this_processor )->finish.lock_count = count;472 473 verify( ! TL_GET( preemption_state ).enabled );468 this_processor->finish.action_code = Release_Multi; 469 this_processor->finish.locks = locks; 470 this_processor->finish.lock_count = count; 471 472 verify( !preemption_state.enabled ); 474 473 returnToKernel(); 475 verify( ! TL_GET( preemption_state ).enabled );474 verify( !preemption_state.enabled ); 476 475 477 476 enable_interrupts( __cfaabi_dbg_ctx ); … … 480 479 void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) { 481 480 disable_interrupts(); 482 TL_GET( this_processor )->finish.action_code = Release_Multi_Schedule;483 TL_GET( this_processor )->finish.locks = locks;484 TL_GET( this_processor )->finish.lock_count = lock_count;485 TL_GET( this_processor )->finish.thrds = thrds;486 TL_GET( this_processor )->finish.thrd_count = thrd_count;487 488 verify( ! TL_GET( preemption_state ).enabled );481 this_processor->finish.action_code = Release_Multi_Schedule; 482 this_processor->finish.locks = locks; 483 this_processor->finish.lock_count = lock_count; 484 this_processor->finish.thrds = thrds; 485 this_processor->finish.thrd_count = thrd_count; 486 487 verify( !preemption_state.enabled ); 489 488 returnToKernel(); 490 verify( ! TL_GET( preemption_state ).enabled );489 verify( !preemption_state.enabled ); 491 490 492 491 enable_interrupts( __cfaabi_dbg_ctx ); … … 494 493 495 494 void LeaveThread(__spinlock_t * lock, thread_desc * thrd) { 496 verify( ! TL_GET( preemption_state ).enabled );497 TL_GET( this_processor )->finish.action_code = thrd ? Release_Schedule : Release;498 TL_GET( this_processor )->finish.lock = lock;499 TL_GET( this_processor )->finish.thrd = thrd;495 verify( !preemption_state.enabled ); 496 this_processor->finish.action_code = thrd ? Release_Schedule : Release; 497 this_processor->finish.lock = lock; 498 this_processor->finish.thrd = thrd; 500 499 501 500 returnToKernel(); … … 508 507 // Kernel boot procedures 509 508 void kernel_startup(void) { 510 verify( ! TL_GET( preemption_state ).enabled );509 verify( !preemption_state.enabled ); 511 510 __cfaabi_dbg_print_safe("Kernel : Starting\n"); 512 511 … … 532 531 533 532 //initialize the global state variables 534 TL_SET( this_processor, mainProcessor );535 TL_SET( this_thread, mainThread );536 TL_SET( this_coroutine, &mainThread->self_cor );533 this_processor = mainProcessor; 534 this_thread = mainThread; 535 this_coroutine = &mainThread->self_cor; 537 536 538 537 // Enable preemption … … 546 545 // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that 547 546 // mainThread is on the ready queue when this call is made. 548 kernel_first_resume( TL_GET( this_processor ));547 kernel_first_resume( this_processor ); 549 548 550 549 … … 553 552 __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n"); 554 553 555 verify( ! TL_GET( preemption_state ).enabled );554 verify( !preemption_state.enabled ); 556 555 enable_interrupts( __cfaabi_dbg_ctx ); 557 verify( TL_GET( preemption_state ).enabled );556 verify( preemption_state.enabled ); 558 557 } 559 558 … … 561 560 __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n"); 562 561 563 verify( TL_GET( preemption_state ).enabled );562 verify( preemption_state.enabled ); 564 563 disable_interrupts(); 565 verify( ! TL_GET( preemption_state ).enabled );564 verify( !preemption_state.enabled ); 566 565 567 566 // SKULLDUGGERY: Notify the mainProcessor it needs to terminates. … … 603 602 604 603 // first task to abort ? 605 if ( ! kernel_abort_called ) { // not first task to abort ?604 if ( !kernel_abort_called ) { // not first task to abort ? 606 605 kernel_abort_called = true; 607 606 unlock( kernel_abort_lock ); … … 618 617 } 619 618 620 return TL_GET( this_thread );619 return this_thread; 621 620 } 622 621 … … 627 626 __cfaabi_dbg_bits_write( abort_text, len ); 628 627 629 if ( thrd != TL_GET( this_coroutine )) {630 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", TL_GET( this_coroutine )->name, TL_GET( this_coroutine ));628 if ( thrd != this_coroutine ) { 629 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine->name, this_coroutine ); 631 630 __cfaabi_dbg_bits_write( abort_text, len ); 632 631 } … … 637 636 638 637 int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) { 639 return get_coroutine( TL_GET( this_thread )) == get_coroutine(mainThread) ? 4 : 2;638 return get_coroutine(this_thread) == get_coroutine(mainThread) ? 4 : 2; 640 639 } 641 640 … … 667 666 if ( count < 0 ) { 668 667 // queue current task 669 append( waiting, (thread_desc *) TL_GET( this_thread ));668 append( waiting, (thread_desc *)this_thread ); 670 669 671 670 // atomically release spin lock and block
Note:
See TracChangeset
for help on using the changeset viewer.