Changes in src/libcfa/concurrency/kernel.c [de94a60:01963df]
- File:
-
- 1 edited
-
src/libcfa/concurrency/kernel.c (modified) (42 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/kernel.c
rde94a60 r01963df 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Apr 9 16:11:46201813 // Update Count : 2 412 // Last Modified On : Fri Mar 30 18:26:11 2018 13 // Update Count : 23 14 14 // 15 15 … … 25 25 26 26 //CFA Includes 27 #include "time"28 27 #include "kernel_private.h" 29 28 #include "preemption.h" … … 42 41 KERNEL_STORAGE(cluster, mainCluster); 43 42 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;53 50 54 51 //----------------------------------------------------------------------------- … … 59 56 // volatile thread_local unsigned short disable_preempt_count = 1; 60 57 61 thread_local struct KernelThreadData kernelT LS= {58 thread_local struct KernelThreadData kernelThreadData = { 62 59 NULL, 63 60 NULL, … … 67 64 68 65 //----------------------------------------------------------------------------- 69 // Struct to steal stack66 // Main thread construction 70 67 struct current_stack_info_t { 71 68 machine_context_t ctx; … … 92 89 } 93 90 94 //-----------------------------------------------------------------------------95 // Main thread construction96 91 void ?{}( coStack_t & this, current_stack_info_t * info) with( this ) { 97 92 size = info->size; … … 115 110 self_cor{ info }; 116 111 curr_cor = &self_cor; 117 curr_cluster = mainCluster;118 112 self_mon.owner = &this; 119 113 self_mon.recursion = 1; 120 114 self_mon_p = &self_mon; 121 115 next = NULL; 122 123 node.next = NULL; 124 node.prev = NULL; 125 doregister(this); 116 __cfaabi_dbg_debug_do( 117 dbg_next = NULL; 118 dbg_prev = NULL; 119 __cfaabi_dbg_thread_register(&this); 120 ) 126 121 127 122 monitors{ &self_mon_p, 1, (fptr_t)0 }; … … 130 125 //----------------------------------------------------------------------------- 131 126 // Processor coroutine 132 void ?{}(processorCtx_t & this) { 133 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; 134 134 } 135 135 … … 140 140 } 141 141 142 void ?{}(processor & this, const char * name, cluster & cltr) with( this ) { 143 this.name = name; 144 this.cltr = &cltr; 142 void ?{}(processor & this) { 143 this{ mainCluster }; 144 } 145 146 void ?{}(processor & this, cluster * cltr) with( this ) { 147 this.cltr = cltr; 145 148 terminated{ 0 }; 146 149 do_terminate = false; … … 152 155 } 153 156 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 154 170 void ^?{}(processor & this) with( this ){ 155 171 if( ! do_terminate ) { … … 157 173 terminate(&this); 158 174 verify(this.do_terminate); 159 verify( kernelTLS.this_processor!= &this);175 verify(TL_GET( this_processor ) != &this); 160 176 P( terminated ); 161 verify( kernelTLS.this_processor!= &this);177 verify(TL_GET( this_processor ) != &this); 162 178 pthread_join( kernel_thread, NULL ); 163 179 } 164 180 } 165 181 166 void ?{}(cluster & this, const char * name, Duration preemption_rate) with( this ) { 167 this.name = name; 168 this.preemption_rate = preemption_rate; 182 void ?{}(cluster & this) with( this ) { 169 183 ready_queue{}; 170 184 ready_queue_lock{}; 171 185 172 procs{ __get }; 173 idles{ __get }; 174 175 doregister(this); 186 preemption_rate = default_preemption(); 176 187 } 177 188 178 189 void ^?{}(cluster & this) { 179 unregister(this); 190 180 191 } 181 192 … … 190 201 __cfaabi_dbg_print_safe("Kernel : core %p starting\n", this); 191 202 192 doregister(this->cltr, this);193 194 203 { 195 204 // Setup preemption data … … 205 214 if(readyThread) 206 215 { 207 verify( ! kernelTLS.preemption_state.enabled );216 verify( ! TL_GET( preemption_state ).enabled ); 208 217 209 218 runThread(this, readyThread); 210 219 211 verify( ! kernelTLS.preemption_state.enabled );220 verify( ! TL_GET( preemption_state ).enabled ); 212 221 213 222 //Some actions need to be taken from the kernel … … 225 234 } 226 235 227 unregister(this->cltr, this);228 229 236 V( this->terminated ); 230 237 … … 232 239 } 233 240 234 // KERNEL ONLY235 241 // runThread runs a thread by context switching 236 242 // from the processor coroutine to the target thread … … 240 246 coroutine_desc * thrd_cor = dst->curr_cor; 241 247 242 // Reset the terminating actions here248 //Reset the terminating actions here 243 249 this->finish.action_code = No_Action; 244 250 245 // Update global state246 kernelTLS.this_thread = dst;251 //Update global state 252 TL_SET( this_thread, dst ); 247 253 248 254 // Context Switch to the thread … … 251 257 } 252 258 253 // KERNEL_ONLY254 259 void returnToKernel() { 255 coroutine_desc * proc_cor = get_coroutine( kernelTLS.this_processor->runner);256 coroutine_desc * thrd_cor = kernelTLS.this_thread->curr_cor = kernelTLS.this_coroutine;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 ); 257 262 ThreadCtxSwitch(thrd_cor, proc_cor); 258 263 } 259 264 260 // KERNEL_ONLY261 265 // Once a thread has finished running, some of 262 266 // its final actions must be executed from the kernel 263 267 void finishRunning(processor * this) with( this->finish ) { 264 268 if( action_code == Release ) { 265 verify( ! kernelTLS.preemption_state.enabled );269 verify( ! TL_GET( preemption_state ).enabled ); 266 270 unlock( *lock ); 267 271 } … … 270 274 } 271 275 else if( action_code == Release_Schedule ) { 272 verify( ! kernelTLS.preemption_state.enabled );276 verify( ! TL_GET( preemption_state ).enabled ); 273 277 unlock( *lock ); 274 278 ScheduleThread( thrd ); 275 279 } 276 280 else if( action_code == Release_Multi ) { 277 verify( ! kernelTLS.preemption_state.enabled );281 verify( ! TL_GET( preemption_state ).enabled ); 278 282 for(int i = 0; i < lock_count; i++) { 279 283 unlock( *locks[i] ); … … 299 303 } 300 304 301 // KERNEL_ONLY302 305 // Context invoker for processors 303 306 // This is the entry point for processors (kernel threads) … … 305 308 void * CtxInvokeProcessor(void * arg) { 306 309 processor * proc = (processor *) arg; 307 kernelTLS.this_processor = proc; 308 kernelTLS.this_coroutine = NULL; 309 kernelTLS.this_thread = NULL; 310 kernelTLS.preemption_state.[enabled, disable_count] = [false, 1]; 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; 311 315 // SKULLDUGGERY: We want to create a context for the processor coroutine 312 316 // which is needed for the 2-step context switch. However, there is no reason … … 320 324 321 325 //Set global state 322 kernelTLS.this_coroutine = get_coroutine(proc->runner);323 kernelTLS.this_thread = NULL;326 TL_SET( this_coroutine, get_coroutine(proc->runner) ); 327 TL_SET( this_thread, NULL ); 324 328 325 329 //We now have a proper context from which to schedule threads … … 348 352 } 349 353 350 // KERNEL_ONLY351 354 void kernel_first_resume(processor * this) { 352 coroutine_desc * src = kernelTLS.this_coroutine;355 coroutine_desc * src = TL_GET( this_coroutine ); 353 356 coroutine_desc * dst = get_coroutine(this->runner); 354 357 355 verify( ! kernelTLS.preemption_state.enabled );358 verify( ! TL_GET( preemption_state ).enabled ); 356 359 357 360 create_stack(&dst->stack, dst->stack.size); 358 361 CtxStart(&this->runner, CtxInvokeCoroutine); 359 362 360 verify( ! kernelTLS.preemption_state.enabled );363 verify( ! TL_GET( preemption_state ).enabled ); 361 364 362 365 dst->last = src; … … 367 370 368 371 // set new coroutine that task is executing 369 kernelTLS.this_coroutine = dst;372 TL_SET( this_coroutine, dst ); 370 373 371 374 // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch. … … 384 387 src->state = Active; 385 388 386 verify( ! kernelTLS.preemption_state.enabled );389 verify( ! TL_GET( preemption_state ).enabled ); 387 390 } 388 391 389 392 //----------------------------------------------------------------------------- 390 393 // Scheduler routines 391 392 // KERNEL ONLY393 394 void ScheduleThread( thread_desc * thrd ) { 395 // if( ! thrd ) return; 394 396 verify( thrd ); 395 397 verify( thrd->self_cor.state != Halted ); 396 398 397 verify( ! kernelTLS.preemption_state.enabled );399 verify( ! TL_GET( preemption_state ).enabled ); 398 400 399 401 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 400 402 401 with( * thrd->curr_cluster ) {403 with( *TL_GET( this_processor )->cltr ) { 402 404 lock ( ready_queue_lock __cfaabi_dbg_ctx2 ); 403 405 append( ready_queue, thrd ); … … 405 407 } 406 408 407 verify( ! kernelTLS.preemption_state.enabled ); 408 } 409 410 // KERNEL ONLY 409 verify( ! TL_GET( preemption_state ).enabled ); 410 } 411 411 412 thread_desc * nextThread(cluster * this) with( *this ) { 412 verify( ! kernelTLS.preemption_state.enabled );413 verify( ! TL_GET( preemption_state ).enabled ); 413 414 lock( ready_queue_lock __cfaabi_dbg_ctx2 ); 414 415 thread_desc * head = pop_head( ready_queue ); 415 416 unlock( ready_queue_lock ); 416 verify( ! kernelTLS.preemption_state.enabled );417 verify( ! TL_GET( preemption_state ).enabled ); 417 418 return head; 418 419 } … … 420 421 void BlockInternal() { 421 422 disable_interrupts(); 422 verify( ! kernelTLS.preemption_state.enabled );423 verify( ! TL_GET( preemption_state ).enabled ); 423 424 returnToKernel(); 424 verify( ! kernelTLS.preemption_state.enabled );425 verify( ! TL_GET( preemption_state ).enabled ); 425 426 enable_interrupts( __cfaabi_dbg_ctx ); 426 427 } … … 428 429 void BlockInternal( __spinlock_t * lock ) { 429 430 disable_interrupts(); 430 with( *kernelTLS.this_processor ) { 431 finish.action_code = Release; 432 finish.lock = lock; 433 } 434 435 verify( ! kernelTLS.preemption_state.enabled ); 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 ); 436 435 returnToKernel(); 437 verify( ! kernelTLS.preemption_state.enabled );436 verify( ! TL_GET( preemption_state ).enabled ); 438 437 439 438 enable_interrupts( __cfaabi_dbg_ctx ); … … 442 441 void BlockInternal( thread_desc * thrd ) { 443 442 disable_interrupts(); 444 with( * kernelTLS.this_processor ) { 445 finish.action_code = Schedule; 446 finish.thrd = thrd; 447 } 448 449 verify( ! kernelTLS.preemption_state.enabled ); 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 ); 450 447 returnToKernel(); 451 verify( ! kernelTLS.preemption_state.enabled );448 verify( ! TL_GET( preemption_state ).enabled ); 452 449 453 450 enable_interrupts( __cfaabi_dbg_ctx ); … … 457 454 assert(thrd); 458 455 disable_interrupts(); 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 ); 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 ); 466 461 returnToKernel(); 467 verify( ! kernelTLS.preemption_state.enabled );462 verify( ! TL_GET( preemption_state ).enabled ); 468 463 469 464 enable_interrupts( __cfaabi_dbg_ctx ); … … 472 467 void BlockInternal(__spinlock_t * locks [], unsigned short count) { 473 468 disable_interrupts(); 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 ); 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 ); 481 474 returnToKernel(); 482 verify( ! kernelTLS.preemption_state.enabled );475 verify( ! TL_GET( preemption_state ).enabled ); 483 476 484 477 enable_interrupts( __cfaabi_dbg_ctx ); … … 487 480 void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) { 488 481 disable_interrupts(); 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 ); 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 ); 498 489 returnToKernel(); 499 verify( ! kernelTLS.preemption_state.enabled );490 verify( ! TL_GET( preemption_state ).enabled ); 500 491 501 492 enable_interrupts( __cfaabi_dbg_ctx ); 502 493 } 503 494 504 // KERNEL ONLY505 495 void LeaveThread(__spinlock_t * lock, thread_desc * 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 } 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; 512 500 513 501 returnToKernel(); … … 520 508 // Kernel boot procedures 521 509 void kernel_startup(void) { 522 verify( ! kernelTLS.preemption_state.enabled );510 verify( ! TL_GET( preemption_state ).enabled ); 523 511 __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 cluster531 mainCluster = (cluster *)&storage_mainCluster;532 (*mainCluster){"Main Cluster"};533 534 __cfaabi_dbg_print_safe("Kernel : Main cluster ready\n");535 512 536 513 // Start by initializing the main thread … … 543 520 __cfaabi_dbg_print_safe("Kernel : Main thread ready\n"); 544 521 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 } 522 // Initialize the main cluster 523 mainCluster = (cluster *)&storage_mainCluster; 524 (*mainCluster){}; 525 526 __cfaabi_dbg_print_safe("Kernel : main cluster ready\n"); 566 527 567 528 // Initialize the main processor and the main processor ctx 568 529 // (the coroutine that contains the processing control flow) 569 530 mainProcessor = (processor *)&storage_mainProcessor; 570 (*mainProcessor){ };531 (*mainProcessor){ mainCluster, *(processorCtx_t *)&storage_mainProcessorCtx }; 571 532 572 533 //initialize the global state variables 573 kernelTLS.this_processor = mainProcessor;574 kernelTLS.this_thread = mainThread;575 kernelTLS.this_coroutine = &mainThread->self_cor;534 TL_SET( this_processor, mainProcessor ); 535 TL_SET( this_thread, mainThread ); 536 TL_SET( this_coroutine, &mainThread->self_cor ); 576 537 577 538 // Enable preemption … … 585 546 // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that 586 547 // mainThread is on the ready queue when this call is made. 587 kernel_first_resume( kernelTLS.this_processor);548 kernel_first_resume( TL_GET( this_processor ) ); 588 549 589 550 … … 592 553 __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n"); 593 554 594 verify( ! kernelTLS.preemption_state.enabled );555 verify( ! TL_GET( preemption_state ).enabled ); 595 556 enable_interrupts( __cfaabi_dbg_ctx ); 596 verify( TL_GET( preemption_state .enabled ));557 verify( TL_GET( preemption_state ).enabled ); 597 558 } 598 559 … … 600 561 __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n"); 601 562 602 verify( TL_GET( preemption_state .enabled ));563 verify( TL_GET( preemption_state ).enabled ); 603 564 disable_interrupts(); 604 verify( ! kernelTLS.preemption_state.enabled );565 verify( ! TL_GET( preemption_state ).enabled ); 605 566 606 567 // SKULLDUGGERY: Notify the mainProcessor it needs to terminates. … … 628 589 629 590 //============================================================================================= 630 // Kernel Quiescing631 //=============================================================================================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 thing639 // // spuriously waking up a kernel thread is not a big deal640 // // 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 //=============================================================================================652 591 // Unexpected Terminating logic 653 592 //============================================================================================= … … 655 594 656 595 static __spinlock_t kernel_abort_lock; 596 static __spinlock_t kernel_debug_lock; 657 597 static bool kernel_abort_called = false; 658 598 659 void * kernel_abort (void) __attribute__ ((__nothrow__)) {599 void * kernel_abort (void) __attribute__ ((__nothrow__)) { 660 600 // abort cannot be recursively entered by the same or different processors because all signal handlers return when 661 601 // the globalAbort flag is true. … … 663 603 664 604 // first task to abort ? 665 if ( kernel_abort_called ) { // not first task to abort ? 605 if ( ! kernel_abort_called ) { // not first task to abort ? 606 kernel_abort_called = true; 607 unlock( kernel_abort_lock ); 608 } 609 else { 666 610 unlock( kernel_abort_lock ); 667 611 668 612 sigset_t mask; 669 613 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 { 675 kernel_abort_called = true; 676 unlock( kernel_abort_lock ); 677 } 678 679 return kernelTLS.this_thread; 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 ); 680 621 } 681 622 … … 683 624 thread_desc * thrd = kernel_data; 684 625 685 if(thrd) { 686 int len = snprintf( abort_text, abort_text_size, "Error occurred while executing thread %.256s (%p)", thrd->self_cor.name, thrd ); 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 ) ); 687 631 __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 }696 632 } 697 633 else { 698 int len = snprintf( abort_text, abort_text_size, "Error occurred outside of any thread.\n");634 __cfaabi_dbg_bits_write( ".\n", 2 ); 699 635 } 700 636 } 701 637 702 638 int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) { 703 return get_coroutine(kernelTLS.this_thread) == get_coroutine(mainThread) ? 4 : 2; 704 } 705 706 static __spinlock_t kernel_debug_lock; 639 return get_coroutine(TL_GET( this_thread )) == get_coroutine(mainThread) ? 4 : 2; 640 } 707 641 708 642 extern "C" { … … 733 667 if ( count < 0 ) { 734 668 // queue current task 735 append( waiting, kernelTLS.this_thread);669 append( waiting, (thread_desc *)TL_GET( this_thread ) ); 736 670 737 671 // atomically release spin lock and block … … 759 693 760 694 //----------------------------------------------------------------------------- 761 // Global Queues762 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 //-----------------------------------------------------------------------------800 695 // Debug 801 696 __cfaabi_dbg_debug_do( 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; 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; 805 725 } 806 726 )
Note:
See TracChangeset
for help on using the changeset viewer.