Changes in src/libcfa/concurrency/kernel.c [01963df:de94a60]
- File:
-
- 1 edited
-
src/libcfa/concurrency/kernel.c (modified) (42 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/kernel.c
r01963df rde94a60 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 : 2 312 // Last Modified On : Mon Apr 9 16:11:46 2018 13 // Update Count : 24 14 14 // 15 15 … … 25 25 26 26 //CFA Includes 27 #include "time" 27 28 #include "kernel_private.h" 28 29 #include "preemption.h" … … 41 42 KERNEL_STORAGE(cluster, mainCluster); 42 43 KERNEL_STORAGE(processor, mainProcessor); 43 KERNEL_STORAGE(processorCtx_t, mainProcessorCtx);44 44 KERNEL_STORAGE(thread_desc, mainThread); 45 45 KERNEL_STORAGE(machine_context_t, mainThreadCtx); 46 46 47 cluster *mainCluster;48 processor *mainProcessor;47 cluster * mainCluster; 48 processor * mainProcessor; 49 49 thread_desc * mainThread; 50 51 struct { __dllist_t(thread_desc) list; __spinlock_t lock; } global_threads ; 52 struct { __dllist_t(cluster ) list; __spinlock_t lock; } global_clusters; 50 53 51 54 //----------------------------------------------------------------------------- … … 56 59 // volatile thread_local unsigned short disable_preempt_count = 1; 57 60 58 thread_local struct KernelThreadData kernelT hreadData= {61 thread_local struct KernelThreadData kernelTLS = { 59 62 NULL, 60 63 NULL, … … 64 67 65 68 //----------------------------------------------------------------------------- 66 // Main thread construction69 // Struct to steal stack 67 70 struct current_stack_info_t { 68 71 machine_context_t ctx; … … 89 92 } 90 93 94 //----------------------------------------------------------------------------- 95 // Main thread construction 91 96 void ?{}( coStack_t & this, current_stack_info_t * info) with( this ) { 92 97 size = info->size; … … 110 115 self_cor{ info }; 111 116 curr_cor = &self_cor; 117 curr_cluster = mainCluster; 112 118 self_mon.owner = &this; 113 119 self_mon.recursion = 1; 114 120 self_mon_p = &self_mon; 115 121 next = NULL; 116 __cfaabi_dbg_debug_do( 117 dbg_next = NULL; 118 dbg_prev = NULL; 119 __cfaabi_dbg_thread_register(&this); 120 ) 122 123 node.next = NULL; 124 node.prev = NULL; 125 doregister(this); 121 126 122 127 monitors{ &self_mon_p, 1, (fptr_t)0 }; … … 125 130 //----------------------------------------------------------------------------- 126 131 // Processor coroutine 127 void ?{}(processorCtx_t & this) {} 128 129 // Construct the processor context of the main processor 130 void ?{}(processorCtx_t & this, processor * proc) { 131 (this.__cor){ "Processor" }; 132 this.__cor.starter = NULL; 133 this.proc = proc; 132 void ?{}(processorCtx_t & this) { 133 134 134 } 135 135 … … 140 140 } 141 141 142 void ?{}(processor & this) { 143 this{ mainCluster }; 144 } 145 146 void ?{}(processor & this, cluster * cltr) with( this ) { 147 this.cltr = cltr; 142 void ?{}(processor & this, const char * name, cluster & cltr) with( this ) { 143 this.name = name; 144 this.cltr = &cltr; 148 145 terminated{ 0 }; 149 146 do_terminate = false; … … 155 152 } 156 153 157 void ?{}(processor & this, cluster * cltr, processorCtx_t & runner) with( this ) {158 this.cltr = cltr;159 terminated{ 0 };160 do_terminate = false;161 preemption_alarm = NULL;162 pending_preemption = false;163 kernel_thread = pthread_self();164 runner.proc = &this;165 166 __cfaabi_dbg_print_safe("Kernel : constructing main processor context %p\n", &runner);167 runner{ &this };168 }169 170 154 void ^?{}(processor & this) with( this ){ 171 155 if( ! do_terminate ) { … … 173 157 terminate(&this); 174 158 verify(this.do_terminate); 175 verify( TL_GET( this_processor )!= &this);159 verify( kernelTLS.this_processor != &this); 176 160 P( terminated ); 177 verify( TL_GET( this_processor )!= &this);161 verify( kernelTLS.this_processor != &this); 178 162 pthread_join( kernel_thread, NULL ); 179 163 } 180 164 } 181 165 182 void ?{}(cluster & this) with( this ) { 166 void ?{}(cluster & this, const char * name, Duration preemption_rate) with( this ) { 167 this.name = name; 168 this.preemption_rate = preemption_rate; 183 169 ready_queue{}; 184 170 ready_queue_lock{}; 185 171 186 preemption_rate = default_preemption(); 172 procs{ __get }; 173 idles{ __get }; 174 175 doregister(this); 187 176 } 188 177 189 178 void ^?{}(cluster & this) { 190 179 unregister(this); 191 180 } 192 181 … … 201 190 __cfaabi_dbg_print_safe("Kernel : core %p starting\n", this); 202 191 192 doregister(this->cltr, this); 193 203 194 { 204 195 // Setup preemption data … … 214 205 if(readyThread) 215 206 { 216 verify( ! TL_GET( preemption_state ).enabled );207 verify( ! kernelTLS.preemption_state.enabled ); 217 208 218 209 runThread(this, readyThread); 219 210 220 verify( ! TL_GET( preemption_state ).enabled );211 verify( ! kernelTLS.preemption_state.enabled ); 221 212 222 213 //Some actions need to be taken from the kernel … … 234 225 } 235 226 227 unregister(this->cltr, this); 228 236 229 V( this->terminated ); 237 230 … … 239 232 } 240 233 234 // KERNEL ONLY 241 235 // runThread runs a thread by context switching 242 236 // from the processor coroutine to the target thread … … 246 240 coroutine_desc * thrd_cor = dst->curr_cor; 247 241 248 // Reset the terminating actions here242 // Reset the terminating actions here 249 243 this->finish.action_code = No_Action; 250 244 251 // Update global state252 TL_SET( this_thread, dst );245 // Update global state 246 kernelTLS.this_thread = dst; 253 247 254 248 // Context Switch to the thread … … 257 251 } 258 252 253 // KERNEL_ONLY 259 254 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 );255 coroutine_desc * proc_cor = get_coroutine(kernelTLS.this_processor->runner); 256 coroutine_desc * thrd_cor = kernelTLS.this_thread->curr_cor = kernelTLS.this_coroutine; 262 257 ThreadCtxSwitch(thrd_cor, proc_cor); 263 258 } 264 259 260 // KERNEL_ONLY 265 261 // Once a thread has finished running, some of 266 262 // its final actions must be executed from the kernel 267 263 void finishRunning(processor * this) with( this->finish ) { 268 264 if( action_code == Release ) { 269 verify( ! TL_GET( preemption_state ).enabled );265 verify( ! kernelTLS.preemption_state.enabled ); 270 266 unlock( *lock ); 271 267 } … … 274 270 } 275 271 else if( action_code == Release_Schedule ) { 276 verify( ! TL_GET( preemption_state ).enabled );272 verify( ! kernelTLS.preemption_state.enabled ); 277 273 unlock( *lock ); 278 274 ScheduleThread( thrd ); 279 275 } 280 276 else if( action_code == Release_Multi ) { 281 verify( ! TL_GET( preemption_state ).enabled );277 verify( ! kernelTLS.preemption_state.enabled ); 282 278 for(int i = 0; i < lock_count; i++) { 283 279 unlock( *locks[i] ); … … 303 299 } 304 300 301 // KERNEL_ONLY 305 302 // Context invoker for processors 306 303 // This is the entry point for processors (kernel threads) … … 308 305 void * CtxInvokeProcessor(void * arg) { 309 306 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; 307 kernelTLS.this_processor = proc; 308 kernelTLS.this_coroutine = NULL; 309 kernelTLS.this_thread = NULL; 310 kernelTLS.preemption_state.[enabled, disable_count] = [false, 1]; 315 311 // SKULLDUGGERY: We want to create a context for the processor coroutine 316 312 // which is needed for the 2-step context switch. However, there is no reason … … 324 320 325 321 //Set global state 326 TL_SET( this_coroutine, get_coroutine(proc->runner));327 TL_SET( this_thread, NULL );322 kernelTLS.this_coroutine = get_coroutine(proc->runner); 323 kernelTLS.this_thread = NULL; 328 324 329 325 //We now have a proper context from which to schedule threads … … 352 348 } 353 349 350 // KERNEL_ONLY 354 351 void kernel_first_resume(processor * this) { 355 coroutine_desc * src = TL_GET( this_coroutine );352 coroutine_desc * src = kernelTLS.this_coroutine; 356 353 coroutine_desc * dst = get_coroutine(this->runner); 357 354 358 verify( ! TL_GET( preemption_state ).enabled );355 verify( ! kernelTLS.preemption_state.enabled ); 359 356 360 357 create_stack(&dst->stack, dst->stack.size); 361 358 CtxStart(&this->runner, CtxInvokeCoroutine); 362 359 363 verify( ! TL_GET( preemption_state ).enabled );360 verify( ! kernelTLS.preemption_state.enabled ); 364 361 365 362 dst->last = src; … … 370 367 371 368 // set new coroutine that task is executing 372 TL_SET( this_coroutine, dst );369 kernelTLS.this_coroutine = dst; 373 370 374 371 // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch. … … 387 384 src->state = Active; 388 385 389 verify( ! TL_GET( preemption_state ).enabled );386 verify( ! kernelTLS.preemption_state.enabled ); 390 387 } 391 388 392 389 //----------------------------------------------------------------------------- 393 390 // Scheduler routines 391 392 // KERNEL ONLY 394 393 void ScheduleThread( thread_desc * thrd ) { 395 // if( ! thrd ) return;396 394 verify( thrd ); 397 395 verify( thrd->self_cor.state != Halted ); 398 396 399 verify( ! TL_GET( preemption_state ).enabled );397 verify( ! kernelTLS.preemption_state.enabled ); 400 398 401 399 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 402 400 403 with( * TL_GET( this_processor )->cltr ) {401 with( *thrd->curr_cluster ) { 404 402 lock ( ready_queue_lock __cfaabi_dbg_ctx2 ); 405 403 append( ready_queue, thrd ); … … 407 405 } 408 406 409 verify( ! TL_GET( preemption_state ).enabled ); 410 } 411 407 verify( ! kernelTLS.preemption_state.enabled ); 408 } 409 410 // KERNEL ONLY 412 411 thread_desc * nextThread(cluster * this) with( *this ) { 413 verify( ! TL_GET( preemption_state ).enabled );412 verify( ! kernelTLS.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( ! kernelTLS.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( ! kernelTLS.preemption_state.enabled ); 424 423 returnToKernel(); 425 verify( ! TL_GET( preemption_state ).enabled );424 verify( ! kernelTLS.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 with( *kernelTLS.this_processor ) { 431 finish.action_code = Release; 432 finish.lock = lock; 433 } 434 435 verify( ! kernelTLS.preemption_state.enabled ); 435 436 returnToKernel(); 436 verify( ! TL_GET( preemption_state ).enabled );437 verify( ! kernelTLS.preemption_state.enabled ); 437 438 438 439 enable_interrupts( __cfaabi_dbg_ctx ); … … 441 442 void BlockInternal( thread_desc * thrd ) { 442 443 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 ); 444 with( * kernelTLS.this_processor ) { 445 finish.action_code = Schedule; 446 finish.thrd = thrd; 447 } 448 449 verify( ! kernelTLS.preemption_state.enabled ); 447 450 returnToKernel(); 448 verify( ! TL_GET( preemption_state ).enabled );451 verify( ! kernelTLS.preemption_state.enabled ); 449 452 450 453 enable_interrupts( __cfaabi_dbg_ctx ); … … 454 457 assert(thrd); 455 458 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 ); 459 with( * kernelTLS.this_processor ) { 460 finish.action_code = Release_Schedule; 461 finish.lock = lock; 462 finish.thrd = thrd; 463 } 464 465 verify( ! kernelTLS.preemption_state.enabled ); 461 466 returnToKernel(); 462 verify( ! TL_GET( preemption_state ).enabled );467 verify( ! kernelTLS.preemption_state.enabled ); 463 468 464 469 enable_interrupts( __cfaabi_dbg_ctx ); … … 467 472 void BlockInternal(__spinlock_t * locks [], unsigned short count) { 468 473 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 ); 474 with( * kernelTLS.this_processor ) { 475 finish.action_code = Release_Multi; 476 finish.locks = locks; 477 finish.lock_count = count; 478 } 479 480 verify( ! kernelTLS.preemption_state.enabled ); 474 481 returnToKernel(); 475 verify( ! TL_GET( preemption_state ).enabled );482 verify( ! kernelTLS.preemption_state.enabled ); 476 483 477 484 enable_interrupts( __cfaabi_dbg_ctx ); … … 480 487 void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) { 481 488 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 ); 489 with( *kernelTLS.this_processor ) { 490 finish.action_code = Release_Multi_Schedule; 491 finish.locks = locks; 492 finish.lock_count = lock_count; 493 finish.thrds = thrds; 494 finish.thrd_count = thrd_count; 495 } 496 497 verify( ! kernelTLS.preemption_state.enabled ); 489 498 returnToKernel(); 490 verify( ! TL_GET( preemption_state ).enabled );499 verify( ! kernelTLS.preemption_state.enabled ); 491 500 492 501 enable_interrupts( __cfaabi_dbg_ctx ); 493 502 } 494 503 504 // KERNEL ONLY 495 505 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; 506 verify( ! kernelTLS.preemption_state.enabled ); 507 with( * kernelTLS.this_processor ) { 508 finish.action_code = thrd ? Release_Schedule : Release; 509 finish.lock = lock; 510 finish.thrd = thrd; 511 } 500 512 501 513 returnToKernel(); … … 508 520 // Kernel boot procedures 509 521 void kernel_startup(void) { 510 verify( ! TL_GET( preemption_state ).enabled );522 verify( ! kernelTLS.preemption_state.enabled ); 511 523 __cfaabi_dbg_print_safe("Kernel : Starting\n"); 524 525 global_threads. list{ __get }; 526 global_threads. lock{}; 527 global_clusters.list{ __get }; 528 global_clusters.lock{}; 529 530 // Initialize the main cluster 531 mainCluster = (cluster *)&storage_mainCluster; 532 (*mainCluster){"Main Cluster"}; 533 534 __cfaabi_dbg_print_safe("Kernel : Main cluster ready\n"); 512 535 513 536 // Start by initializing the main thread … … 520 543 __cfaabi_dbg_print_safe("Kernel : Main thread ready\n"); 521 544 522 // Initialize the main cluster 523 mainCluster = (cluster *)&storage_mainCluster; 524 (*mainCluster){}; 525 526 __cfaabi_dbg_print_safe("Kernel : main cluster ready\n"); 545 546 547 // Construct the processor context of the main processor 548 void ?{}(processorCtx_t & this, processor * proc) { 549 (this.__cor){ "Processor" }; 550 this.__cor.starter = NULL; 551 this.proc = proc; 552 } 553 554 void ?{}(processor & this) with( this ) { 555 name = "Main Processor"; 556 cltr = mainCluster; 557 terminated{ 0 }; 558 do_terminate = false; 559 preemption_alarm = NULL; 560 pending_preemption = false; 561 kernel_thread = pthread_self(); 562 563 runner{ &this }; 564 __cfaabi_dbg_print_safe("Kernel : constructed main processor context %p\n", &runner); 565 } 527 566 528 567 // Initialize the main processor and the main processor ctx 529 568 // (the coroutine that contains the processing control flow) 530 569 mainProcessor = (processor *)&storage_mainProcessor; 531 (*mainProcessor){ mainCluster, *(processorCtx_t *)&storage_mainProcessorCtx};570 (*mainProcessor){}; 532 571 533 572 //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 );573 kernelTLS.this_processor = mainProcessor; 574 kernelTLS.this_thread = mainThread; 575 kernelTLS.this_coroutine = &mainThread->self_cor; 537 576 538 577 // Enable preemption … … 546 585 // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that 547 586 // mainThread is on the ready queue when this call is made. 548 kernel_first_resume( TL_GET( this_processor ));587 kernel_first_resume( kernelTLS.this_processor ); 549 588 550 589 … … 553 592 __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n"); 554 593 555 verify( ! TL_GET( preemption_state ).enabled );594 verify( ! kernelTLS.preemption_state.enabled ); 556 595 enable_interrupts( __cfaabi_dbg_ctx ); 557 verify( TL_GET( preemption_state ).enabled);596 verify( TL_GET( preemption_state.enabled ) ); 558 597 } 559 598 … … 561 600 __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n"); 562 601 563 verify( TL_GET( preemption_state ).enabled);602 verify( TL_GET( preemption_state.enabled ) ); 564 603 disable_interrupts(); 565 verify( ! TL_GET( preemption_state ).enabled );604 verify( ! kernelTLS.preemption_state.enabled ); 566 605 567 606 // SKULLDUGGERY: Notify the mainProcessor it needs to terminates. … … 589 628 590 629 //============================================================================================= 630 // Kernel Quiescing 631 //============================================================================================= 632 633 // void halt(processor * this) with( this ) { 634 // pthread_mutex_lock( &idle.lock ); 635 636 637 638 // // SKULLDUGGERY: Even if spurious wake-up is a thing 639 // // spuriously waking up a kernel thread is not a big deal 640 // // if it is very rare. 641 // pthread_cond_wait( &idle.cond, &idle.lock); 642 // pthread_mutex_unlock( &idle.lock ); 643 // } 644 645 // void wake(processor * this) with( this ) { 646 // pthread_mutex_lock (&idle.lock); 647 // pthread_cond_signal (&idle.cond); 648 // pthread_mutex_unlock(&idle.lock); 649 // } 650 651 //============================================================================================= 591 652 // Unexpected Terminating logic 592 653 //============================================================================================= … … 594 655 595 656 static __spinlock_t kernel_abort_lock; 596 static __spinlock_t kernel_debug_lock;597 657 static bool kernel_abort_called = false; 598 658 599 void * kernel_abort (void) __attribute__ ((__nothrow__)) {659 void * kernel_abort(void) __attribute__ ((__nothrow__)) { 600 660 // abort cannot be recursively entered by the same or different processors because all signal handlers return when 601 661 // the globalAbort flag is true. … … 603 663 604 664 // first task to abort ? 605 if ( ! kernel_abort_called ) { // not first task to abort ? 665 if ( kernel_abort_called ) { // not first task to abort ? 666 unlock( kernel_abort_lock ); 667 668 sigset_t mask; 669 sigemptyset( &mask ); 670 sigaddset( &mask, SIGALRM ); // block SIGALRM signals 671 sigsuspend( &mask ); // block the processor to prevent further damage during abort 672 _exit( EXIT_FAILURE ); // if processor unblocks before it is killed, terminate it 673 } 674 else { 606 675 kernel_abort_called = true; 607 676 unlock( kernel_abort_lock ); 608 677 } 609 else { 610 unlock( kernel_abort_lock ); 611 612 sigset_t mask; 613 sigemptyset( &mask ); 614 sigaddset( &mask, SIGALRM ); // block SIGALRM signals 615 sigaddset( &mask, SIGUSR1 ); // block SIGUSR1 signals 616 sigsuspend( &mask ); // block the processor to prevent further damage during abort 617 _exit( EXIT_FAILURE ); // if processor unblocks before it is killed, terminate it 618 } 619 620 return TL_GET( this_thread ); 678 679 return kernelTLS.this_thread; 621 680 } 622 681 … … 624 683 thread_desc * thrd = kernel_data; 625 684 626 int len = snprintf( abort_text, abort_text_size, "Error occurred while executing task %.256s (%p)", thrd->self_cor.name, thrd ); 627 __cfaabi_dbg_bits_write( abort_text, len ); 628 629 if ( get_coroutine(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 ) ); 685 if(thrd) { 686 int len = snprintf( abort_text, abort_text_size, "Error occurred while executing thread %.256s (%p)", thrd->self_cor.name, thrd ); 631 687 __cfaabi_dbg_bits_write( abort_text, len ); 688 689 if ( get_coroutine(thrd) != kernelTLS.this_coroutine ) { 690 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", kernelTLS.this_coroutine->name, kernelTLS.this_coroutine ); 691 __cfaabi_dbg_bits_write( abort_text, len ); 692 } 693 else { 694 __cfaabi_dbg_bits_write( ".\n", 2 ); 695 } 632 696 } 633 697 else { 634 __cfaabi_dbg_bits_write( ".\n", 2);698 int len = snprintf( abort_text, abort_text_size, "Error occurred outside of any thread.\n" ); 635 699 } 636 700 } 637 701 638 702 int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) { 639 return get_coroutine(TL_GET( this_thread )) == get_coroutine(mainThread) ? 4 : 2; 640 } 703 return get_coroutine(kernelTLS.this_thread) == get_coroutine(mainThread) ? 4 : 2; 704 } 705 706 static __spinlock_t kernel_debug_lock; 641 707 642 708 extern "C" { … … 667 733 if ( count < 0 ) { 668 734 // queue current task 669 append( waiting, (thread_desc *)TL_GET( this_thread ));735 append( waiting, kernelTLS.this_thread ); 670 736 671 737 // atomically release spin lock and block … … 693 759 694 760 //----------------------------------------------------------------------------- 761 // Global Queues 762 void doregister( thread_desc & thrd ) { 763 // lock ( global_thread.lock ); 764 // push_front( global_thread.list, thrd ); 765 // unlock ( global_thread.lock ); 766 } 767 768 void unregister( thread_desc & thrd ) { 769 // lock ( global_thread.lock ); 770 // remove( global_thread.list, thrd ); 771 // unlock( global_thread.lock ); 772 } 773 774 void doregister( cluster & cltr ) { 775 // lock ( global_cluster.lock ); 776 // push_front( global_cluster.list, cltr ); 777 // unlock ( global_cluster.lock ); 778 } 779 780 void unregister( cluster & cltr ) { 781 // lock ( global_cluster.lock ); 782 // remove( global_cluster.list, cltr ); 783 // unlock( global_cluster.lock ); 784 } 785 786 787 void doregister( cluster * cltr, processor * proc ) { 788 // lock (cltr->proc_list_lock __cfaabi_dbg_ctx2); 789 // push_front(cltr->procs, *proc); 790 // unlock (cltr->proc_list_lock); 791 } 792 793 void unregister( cluster * cltr, processor * proc ) { 794 // lock (cltr->proc_list_lock __cfaabi_dbg_ctx2); 795 // remove(cltr->procs, *proc ); 796 // unlock(cltr->proc_list_lock); 797 } 798 799 //----------------------------------------------------------------------------- 695 800 // Debug 696 801 __cfaabi_dbg_debug_do( 697 struct { 698 thread_desc * tail; 699 } __cfaabi_dbg_thread_list = { NULL }; 700 701 void __cfaabi_dbg_thread_register( thread_desc * thrd ) { 702 if( !__cfaabi_dbg_thread_list.tail ) { 703 __cfaabi_dbg_thread_list.tail = thrd; 704 return; 705 } 706 __cfaabi_dbg_thread_list.tail->dbg_next = thrd; 707 thrd->dbg_prev = __cfaabi_dbg_thread_list.tail; 708 __cfaabi_dbg_thread_list.tail = thrd; 709 } 710 711 void __cfaabi_dbg_thread_unregister( thread_desc * thrd ) { 712 thread_desc * prev = thrd->dbg_prev; 713 thread_desc * next = thrd->dbg_next; 714 715 if( next ) { next->dbg_prev = prev; } 716 else { 717 assert( __cfaabi_dbg_thread_list.tail == thrd ); 718 __cfaabi_dbg_thread_list.tail = prev; 719 } 720 721 if( prev ) { prev->dbg_next = next; } 722 723 thrd->dbg_prev = NULL; 724 thrd->dbg_next = NULL; 802 void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) { 803 this.prev_name = prev_name; 804 this.prev_thrd = kernelTLS.this_thread; 725 805 } 726 806 )
Note:
See TracChangeset
for help on using the changeset viewer.