- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel.cfa
r6a77224 r8fc652e0 108 108 static $thread * __next_thread_slow(cluster * this); 109 109 static void __run_thread(processor * this, $thread * dst); 110 static void __wake_one( struct __processor_id_t * id,cluster * cltr);110 static void __wake_one(cluster * cltr); 111 111 112 112 static void push (__cluster_idles & idles, processor & proc); … … 122 122 // Because of a bug, we couldn't initialized the seed on construction 123 123 // Do it here 124 kernelTLS.rand_seed ^= rdtscl();125 kernelTLS.ready_rng.fwd_seed = 25214903917_l64u * (rdtscl() ^ (uintptr_t)&runner);124 __cfaabi_tls.rand_seed ^= rdtscl(); 125 __cfaabi_tls.ready_rng.fwd_seed = 25214903917_l64u * (rdtscl() ^ (uintptr_t)&runner); 126 126 __tls_rand_advance_bck(); 127 127 … … 217 217 // and it make sense for it to be set in all other cases except here 218 218 // fake it 219 kernelTLS.this_thread = mainThread;219 __cfaabi_tls.this_thread = mainThread; 220 220 } 221 221 … … 230 230 // from the processor coroutine to the target thread 231 231 static void __run_thread(processor * this, $thread * thrd_dst) { 232 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);232 /* paranoid */ verify( ! __preemption_enabled() ); 233 233 /* paranoid */ verifyf( thrd_dst->state == Ready || thrd_dst->preempted != __NO_PREEMPTION, "state : %d, preempted %d\n", thrd_dst->state, thrd_dst->preempted); 234 234 /* paranoid */ verifyf( thrd_dst->link.next == 0p, "Expected null got %p", thrd_dst->link.next ); … … 247 247 248 248 // Update global state 249 kernelTLS .this_thread = thrd_dst;250 251 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);252 /* paranoid */ verify( kernelTLS .this_thread == thrd_dst );249 kernelTLS().this_thread = thrd_dst; 250 251 /* paranoid */ verify( ! __preemption_enabled() ); 252 /* paranoid */ verify( kernelTLS().this_thread == thrd_dst ); 253 253 /* paranoid */ verify( thrd_dst->context.SP ); 254 254 /* paranoid */ verify( thrd_dst->state != Halted ); … … 267 267 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ), "ERROR : Destination $thread %p has been corrupted.\n StackPointer too small.\n", thrd_dst ); 268 268 /* paranoid */ verify( thrd_dst->context.SP ); 269 /* paranoid */ verify( kernelTLS .this_thread == thrd_dst );270 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);269 /* paranoid */ verify( kernelTLS().this_thread == thrd_dst ); 270 /* paranoid */ verify( ! __preemption_enabled() ); 271 271 272 272 // Reset global state 273 kernelTLS .this_thread = 0p;273 kernelTLS().this_thread = 0p; 274 274 275 275 // We just finished running a thread, there are a few things that could have happened. … … 282 282 if(unlikely(thrd_dst->preempted != __NO_PREEMPTION)) { 283 283 // The thread was preempted, reschedule it and reset the flag 284 __schedule_thread( (__processor_id_t*)this,thrd_dst );284 __schedule_thread( thrd_dst ); 285 285 break RUNNING; 286 286 } … … 315 315 proc_cor->state = Active; 316 316 317 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);317 /* paranoid */ verify( ! __preemption_enabled() ); 318 318 } 319 319 320 320 // KERNEL_ONLY 321 321 void returnToKernel() { 322 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);323 $coroutine * proc_cor = get_coroutine(kernelTLS .this_processor->runner);324 $thread * thrd_src = kernelTLS .this_thread;322 /* paranoid */ verify( ! __preemption_enabled() ); 323 $coroutine * proc_cor = get_coroutine(kernelTLS().this_processor->runner); 324 $thread * thrd_src = kernelTLS().this_thread; 325 325 326 326 #if !defined(__CFA_NO_STATISTICS__) 327 struct processor * last_proc = kernelTLS .this_processor;327 struct processor * last_proc = kernelTLS().this_processor; 328 328 #endif 329 329 … … 345 345 346 346 #if !defined(__CFA_NO_STATISTICS__) 347 if(last_proc != kernelTLS .this_processor) {347 if(last_proc != kernelTLS().this_processor) { 348 348 __tls_stats()->ready.threads.migration++; 349 349 } 350 350 #endif 351 351 352 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);352 /* paranoid */ verify( ! __preemption_enabled() ); 353 353 /* paranoid */ verifyf( ((uintptr_t)thrd_src->context.SP) < ((uintptr_t)__get_stack(thrd_src->curr_cor)->base ), "ERROR : Returning $thread %p has been corrupted.\n StackPointer too small.\n", thrd_src ); 354 354 /* paranoid */ verifyf( ((uintptr_t)thrd_src->context.SP) > ((uintptr_t)__get_stack(thrd_src->curr_cor)->limit), "ERROR : Returning $thread %p has been corrupted.\n StackPointer too large.\n", thrd_src ); … … 358 358 // Scheduler routines 359 359 // KERNEL ONLY 360 void __schedule_thread( struct __processor_id_t * id, $thread * thrd ) { 360 void __schedule_thread( $thread * thrd ) { 361 /* paranoid */ verify( ! __preemption_enabled() ); 361 362 /* paranoid */ verify( thrd ); 362 363 /* paranoid */ verify( thrd->state != Halted ); 363 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );364 /* paranoid */ verify( kernelTLS().this_proc_id ); 364 365 /* paranoid */ #if defined( __CFA_WITH_VERIFY__ ) 365 366 /* paranoid */ if( thrd->state == Blocked || thrd->state == Start ) assertf( thrd->preempted == __NO_PREEMPTION, … … 374 375 if (thrd->preempted == __NO_PREEMPTION) thrd->state = Ready; 375 376 376 ready_schedule_lock ( id);377 ready_schedule_lock(); 377 378 push( thrd->curr_cluster, thrd ); 378 __wake_one( id,thrd->curr_cluster);379 ready_schedule_unlock( id);380 381 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);379 __wake_one(thrd->curr_cluster); 380 ready_schedule_unlock(); 381 382 /* paranoid */ verify( ! __preemption_enabled() ); 382 383 } 383 384 384 385 // KERNEL ONLY 385 386 static inline $thread * __next_thread(cluster * this) with( *this ) { 386 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 387 388 ready_schedule_lock ( (__processor_id_t*)kernelTLS.this_processor ); 387 /* paranoid */ verify( ! __preemption_enabled() ); 388 /* paranoid */ verify( kernelTLS().this_proc_id ); 389 390 ready_schedule_lock(); 389 391 $thread * thrd = pop( this ); 390 ready_schedule_unlock( (__processor_id_t*)kernelTLS.this_processor ); 391 392 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 392 ready_schedule_unlock(); 393 394 /* paranoid */ verify( kernelTLS().this_proc_id ); 395 /* paranoid */ verify( ! __preemption_enabled() ); 393 396 return thrd; 394 397 } … … 396 399 // KERNEL ONLY 397 400 static inline $thread * __next_thread_slow(cluster * this) with( *this ) { 398 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 399 400 ready_schedule_lock ( (__processor_id_t*)kernelTLS.this_processor ); 401 /* paranoid */ verify( ! __preemption_enabled() ); 402 /* paranoid */ verify( kernelTLS().this_proc_id ); 403 404 ready_schedule_lock(); 401 405 $thread * thrd = pop_slow( this ); 402 ready_schedule_unlock( (__processor_id_t*)kernelTLS.this_processor ); 403 404 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 406 ready_schedule_unlock(); 407 408 /* paranoid */ verify( kernelTLS().this_proc_id ); 409 /* paranoid */ verify( ! __preemption_enabled() ); 405 410 return thrd; 406 411 } 407 412 408 // KERNEL ONLY unpark with out disabling interrupts 409 void __unpark( struct __processor_id_t * id, $thread * thrd ) { 413 void unpark( $thread * thrd ) { 414 if( !thrd ) return; 415 410 416 int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST); 411 417 switch(old_ticket) { … … 417 423 /* paranoid */ verify( thrd->state == Blocked ); 418 424 419 // Wake lost the race, 420 __schedule_thread( id, thrd ); 425 { 426 /* paranoid */ verify( publicTLS_get(this_proc_id) ); 427 bool full = publicTLS_get(this_proc_id)->full_proc; 428 if(full) disable_interrupts(); 429 430 /* paranoid */ verify( ! __preemption_enabled() ); 431 432 // Wake lost the race, 433 __schedule_thread( thrd ); 434 435 /* paranoid */ verify( ! __preemption_enabled() ); 436 437 if(full) enable_interrupts( __cfaabi_dbg_ctx ); 438 /* paranoid */ verify( publicTLS_get(this_proc_id) ); 439 } 440 421 441 break; 422 442 default: … … 426 446 } 427 447 428 void unpark( $thread * thrd ) { 429 if( !thrd ) return; 430 448 void park( void ) { 449 /* paranoid */ verify( __preemption_enabled() ); 431 450 disable_interrupts(); 432 __unpark( (__processor_id_t*)kernelTLS.this_processor, thrd ); 451 /* paranoid */ verify( ! __preemption_enabled() ); 452 /* paranoid */ verify( kernelTLS().this_thread->preempted == __NO_PREEMPTION ); 453 454 returnToKernel(); 455 456 /* paranoid */ verify( ! __preemption_enabled() ); 433 457 enable_interrupts( __cfaabi_dbg_ctx ); 434 } 435 436 void park( void ) { 437 /* paranoid */ verify( kernelTLS.preemption_state.enabled ); 438 disable_interrupts(); 439 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 440 /* paranoid */ verify( kernelTLS.this_thread->preempted == __NO_PREEMPTION ); 441 442 returnToKernel(); 443 444 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 445 enable_interrupts( __cfaabi_dbg_ctx ); 446 /* paranoid */ verify( kernelTLS.preemption_state.enabled ); 458 /* paranoid */ verify( __preemption_enabled() ); 447 459 448 460 } … … 453 465 // Should never return 454 466 void __cfactx_thrd_leave() { 455 $thread * thrd = TL_GET( this_thread);467 $thread * thrd = active_thread(); 456 468 $monitor * this = &thrd->self_mon; 457 469 … … 462 474 463 475 thrd->state = Halted; 464 476 if( TICKET_RUNNING != thrd->ticket ) { abort( "Thread terminated with pending unpark" ); } 465 477 if( thrd != this->owner || this->recursion != 1) { abort( "Thread internal monitor has unbalanced recursion" ); } 466 478 467 479 // Leave the thread 468 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);480 /* paranoid */ verify( ! __preemption_enabled() ); 469 481 returnToKernel(); 470 482 abort(); … … 476 488 // KERNEL ONLY 477 489 bool force_yield( __Preemption_Reason reason ) { 478 /* paranoid */ verify( kernelTLS.preemption_state.enabled);490 /* paranoid */ verify( __preemption_enabled() ); 479 491 disable_interrupts(); 480 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);481 482 $thread * thrd = kernelTLS .this_thread;492 /* paranoid */ verify( ! __preemption_enabled() ); 493 494 $thread * thrd = kernelTLS().this_thread; 483 495 /* paranoid */ verify(thrd->state == Active); 484 496 … … 494 506 } 495 507 496 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);508 /* paranoid */ verify( ! __preemption_enabled() ); 497 509 enable_interrupts_noPoll(); 498 /* paranoid */ verify( kernelTLS.preemption_state.enabled);510 /* paranoid */ verify( __preemption_enabled() ); 499 511 500 512 return preempted; … … 505 517 //============================================================================================= 506 518 // Wake a thread from the front if there are any 507 static void __wake_one( struct __processor_id_t * id,cluster * this) {508 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);509 /* paranoid */ verify( ready_schedule_islocked( id) );519 static void __wake_one(cluster * this) { 520 /* paranoid */ verify( ! __preemption_enabled() ); 521 /* paranoid */ verify( ready_schedule_islocked() ); 510 522 511 523 // Check if there is a sleeping processor … … 525 537 #endif 526 538 527 /* paranoid */ verify( ready_schedule_islocked( id) );528 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);539 /* paranoid */ verify( ready_schedule_islocked() ); 540 /* paranoid */ verify( ! __preemption_enabled() ); 529 541 530 542 return; … … 536 548 537 549 disable_interrupts(); 538 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);550 /* paranoid */ verify( ! __preemption_enabled() ); 539 551 post( this->idle ); 540 552 enable_interrupts( __cfaabi_dbg_ctx ); … … 542 554 543 555 static void push (__cluster_idles & this, processor & proc) { 544 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);556 /* paranoid */ verify( ! __preemption_enabled() ); 545 557 lock( this ); 546 558 this.idle++; … … 549 561 insert_first(this.list, proc); 550 562 unlock( this ); 551 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);563 /* paranoid */ verify( ! __preemption_enabled() ); 552 564 } 553 565 554 566 static void remove(__cluster_idles & this, processor & proc) { 555 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);567 /* paranoid */ verify( ! __preemption_enabled() ); 556 568 lock( this ); 557 569 this.idle--; … … 560 572 remove(proc); 561 573 unlock( this ); 562 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled);574 /* paranoid */ verify( ! __preemption_enabled() ); 563 575 } 564 576 … … 604 616 } 605 617 606 return kernelTLS.this_thread;618 return __cfaabi_tls.this_thread; 607 619 } 608 620 … … 629 641 630 642 int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) { 631 return get_coroutine(kernelTLS .this_thread) == get_coroutine(mainThread) ? 4 : 2;643 return get_coroutine(kernelTLS().this_thread) == get_coroutine(mainThread) ? 4 : 2; 632 644 } 633 645 … … 661 673 if ( count < 0 ) { 662 674 // queue current task 663 append( waiting, kernelTLS.this_thread);675 append( waiting, active_thread() ); 664 676 665 677 // atomically release spin lock and block … … 711 723 void __cfaabi_dbg_record_lock(__spinlock_t & this, const char prev_name[]) { 712 724 this.prev_name = prev_name; 713 this.prev_thrd = kernelTLS .this_thread;725 this.prev_thrd = kernelTLS().this_thread; 714 726 } 715 727 } … … 728 740 this.print_halts = true; 729 741 } 742 743 void print_stats_now( cluster & this, int flags ) { 744 __print_stats( this.stats, this.print_stats, true, this.name, (void*)&this ); 745 } 730 746 #endif 731 747 // Local Variables: //
Note: See TracChangeset
for help on using the changeset viewer.