- File:
-
- 1 edited
-
libcfa/src/concurrency/kernel.cfa (modified) (29 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel.cfa
r8fc652e0 r6a77224 108 108 static $thread * __next_thread_slow(cluster * this); 109 109 static void __run_thread(processor * this, $thread * dst); 110 static void __wake_one( cluster * cltr);110 static void __wake_one(struct __processor_id_t * id, 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 __cfaabi_tls.rand_seed ^= rdtscl();125 __cfaabi_tls.ready_rng.fwd_seed = 25214903917_l64u * (rdtscl() ^ (uintptr_t)&runner);124 kernelTLS.rand_seed ^= rdtscl(); 125 kernelTLS.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 __cfaabi_tls.this_thread = mainThread;219 kernelTLS.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( ! __preemption_enabled());232 /* paranoid */ verify( ! kernelTLS.preemption_state.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( ! __preemption_enabled());252 /* paranoid */ verify( kernelTLS ().this_thread == thrd_dst );249 kernelTLS.this_thread = thrd_dst; 250 251 /* paranoid */ verify( ! kernelTLS.preemption_state.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( ! __preemption_enabled());269 /* paranoid */ verify( kernelTLS.this_thread == thrd_dst ); 270 /* paranoid */ verify( ! kernelTLS.preemption_state.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( thrd_dst );284 __schedule_thread( (__processor_id_t*)this, thrd_dst ); 285 285 break RUNNING; 286 286 } … … 315 315 proc_cor->state = Active; 316 316 317 /* paranoid */ verify( ! __preemption_enabled());317 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 318 318 } 319 319 320 320 // KERNEL_ONLY 321 321 void returnToKernel() { 322 /* paranoid */ verify( ! __preemption_enabled());323 $coroutine * proc_cor = get_coroutine(kernelTLS ().this_processor->runner);324 $thread * thrd_src = kernelTLS ().this_thread;322 /* paranoid */ verify( ! kernelTLS.preemption_state.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( ! __preemption_enabled());352 /* paranoid */ verify( ! kernelTLS.preemption_state.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( $thread * thrd ) { 361 /* paranoid */ verify( ! __preemption_enabled() ); 360 void __schedule_thread( struct __processor_id_t * id, $thread * thrd ) { 362 361 /* paranoid */ verify( thrd ); 363 362 /* paranoid */ verify( thrd->state != Halted ); 364 /* paranoid */ verify( kernelTLS().this_proc_id );363 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 365 364 /* paranoid */ #if defined( __CFA_WITH_VERIFY__ ) 366 365 /* paranoid */ if( thrd->state == Blocked || thrd->state == Start ) assertf( thrd->preempted == __NO_PREEMPTION, … … 375 374 if (thrd->preempted == __NO_PREEMPTION) thrd->state = Ready; 376 375 377 ready_schedule_lock ();376 ready_schedule_lock ( id ); 378 377 push( thrd->curr_cluster, thrd ); 379 __wake_one( thrd->curr_cluster);380 ready_schedule_unlock( );381 382 /* paranoid */ verify( ! __preemption_enabled());378 __wake_one(id, thrd->curr_cluster); 379 ready_schedule_unlock( id ); 380 381 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 383 382 } 384 383 385 384 // KERNEL ONLY 386 385 static inline $thread * __next_thread(cluster * this) with( *this ) { 387 /* paranoid */ verify( ! __preemption_enabled() ); 388 /* paranoid */ verify( kernelTLS().this_proc_id ); 389 390 ready_schedule_lock(); 386 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 387 388 ready_schedule_lock ( (__processor_id_t*)kernelTLS.this_processor ); 391 389 $thread * thrd = pop( this ); 392 ready_schedule_unlock(); 393 394 /* paranoid */ verify( kernelTLS().this_proc_id ); 395 /* paranoid */ verify( ! __preemption_enabled() ); 390 ready_schedule_unlock( (__processor_id_t*)kernelTLS.this_processor ); 391 392 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 396 393 return thrd; 397 394 } … … 399 396 // KERNEL ONLY 400 397 static inline $thread * __next_thread_slow(cluster * this) with( *this ) { 401 /* paranoid */ verify( ! __preemption_enabled() ); 402 /* paranoid */ verify( kernelTLS().this_proc_id ); 403 404 ready_schedule_lock(); 398 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 399 400 ready_schedule_lock ( (__processor_id_t*)kernelTLS.this_processor ); 405 401 $thread * thrd = pop_slow( this ); 406 ready_schedule_unlock(); 407 408 /* paranoid */ verify( kernelTLS().this_proc_id ); 409 /* paranoid */ verify( ! __preemption_enabled() ); 402 ready_schedule_unlock( (__processor_id_t*)kernelTLS.this_processor ); 403 404 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 410 405 return thrd; 411 406 } 412 407 413 void unpark( $thread * thrd ) { 414 if( !thrd ) return; 415 408 // KERNEL ONLY unpark with out disabling interrupts 409 void __unpark( struct __processor_id_t * id, $thread * thrd ) { 416 410 int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST); 417 411 switch(old_ticket) { … … 423 417 /* paranoid */ verify( thrd->state == Blocked ); 424 418 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 419 // Wake lost the race, 420 __schedule_thread( id, thrd ); 441 421 break; 442 422 default: … … 446 426 } 447 427 428 void unpark( $thread * thrd ) { 429 if( !thrd ) return; 430 431 disable_interrupts(); 432 __unpark( (__processor_id_t*)kernelTLS.this_processor, thrd ); 433 enable_interrupts( __cfaabi_dbg_ctx ); 434 } 435 448 436 void park( void ) { 449 /* paranoid */ verify( __preemption_enabled());437 /* paranoid */ verify( kernelTLS.preemption_state.enabled ); 450 438 disable_interrupts(); 451 /* paranoid */ verify( ! __preemption_enabled());452 /* paranoid */ verify( kernelTLS ().this_thread->preempted == __NO_PREEMPTION );439 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 440 /* paranoid */ verify( kernelTLS.this_thread->preempted == __NO_PREEMPTION ); 453 441 454 442 returnToKernel(); 455 443 456 /* paranoid */ verify( ! __preemption_enabled());444 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 457 445 enable_interrupts( __cfaabi_dbg_ctx ); 458 /* paranoid */ verify( __preemption_enabled());446 /* paranoid */ verify( kernelTLS.preemption_state.enabled ); 459 447 460 448 } … … 465 453 // Should never return 466 454 void __cfactx_thrd_leave() { 467 $thread * thrd = active_thread();455 $thread * thrd = TL_GET( this_thread ); 468 456 $monitor * this = &thrd->self_mon; 469 457 … … 474 462 475 463 thrd->state = Halted; 476 if( TICKET_RUNNING != thrd->ticket ) { abort( "Thread terminated with pending unpark" ); } 464 477 465 if( thrd != this->owner || this->recursion != 1) { abort( "Thread internal monitor has unbalanced recursion" ); } 478 466 479 467 // Leave the thread 480 /* paranoid */ verify( ! __preemption_enabled());468 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 481 469 returnToKernel(); 482 470 abort(); … … 488 476 // KERNEL ONLY 489 477 bool force_yield( __Preemption_Reason reason ) { 490 /* paranoid */ verify( __preemption_enabled());478 /* paranoid */ verify( kernelTLS.preemption_state.enabled ); 491 479 disable_interrupts(); 492 /* paranoid */ verify( ! __preemption_enabled());493 494 $thread * thrd = kernelTLS ().this_thread;480 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 481 482 $thread * thrd = kernelTLS.this_thread; 495 483 /* paranoid */ verify(thrd->state == Active); 496 484 … … 506 494 } 507 495 508 /* paranoid */ verify( ! __preemption_enabled());496 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 509 497 enable_interrupts_noPoll(); 510 /* paranoid */ verify( __preemption_enabled());498 /* paranoid */ verify( kernelTLS.preemption_state.enabled ); 511 499 512 500 return preempted; … … 517 505 //============================================================================================= 518 506 // Wake a thread from the front if there are any 519 static void __wake_one( cluster * this) {520 /* paranoid */ verify( ! __preemption_enabled());521 /* paranoid */ verify( ready_schedule_islocked( ) );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 ) ); 522 510 523 511 // Check if there is a sleeping processor … … 537 525 #endif 538 526 539 /* paranoid */ verify( ready_schedule_islocked( ) );540 /* paranoid */ verify( ! __preemption_enabled());527 /* paranoid */ verify( ready_schedule_islocked( id ) ); 528 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 541 529 542 530 return; … … 548 536 549 537 disable_interrupts(); 550 /* paranoid */ verify( ! __preemption_enabled());538 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 551 539 post( this->idle ); 552 540 enable_interrupts( __cfaabi_dbg_ctx ); … … 554 542 555 543 static void push (__cluster_idles & this, processor & proc) { 556 /* paranoid */ verify( ! __preemption_enabled());544 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 557 545 lock( this ); 558 546 this.idle++; … … 561 549 insert_first(this.list, proc); 562 550 unlock( this ); 563 /* paranoid */ verify( ! __preemption_enabled());551 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 564 552 } 565 553 566 554 static void remove(__cluster_idles & this, processor & proc) { 567 /* paranoid */ verify( ! __preemption_enabled());555 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 568 556 lock( this ); 569 557 this.idle--; … … 572 560 remove(proc); 573 561 unlock( this ); 574 /* paranoid */ verify( ! __preemption_enabled());562 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 575 563 } 576 564 … … 616 604 } 617 605 618 return __cfaabi_tls.this_thread;606 return kernelTLS.this_thread; 619 607 } 620 608 … … 641 629 642 630 int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) { 643 return get_coroutine(kernelTLS ().this_thread) == get_coroutine(mainThread) ? 4 : 2;631 return get_coroutine(kernelTLS.this_thread) == get_coroutine(mainThread) ? 4 : 2; 644 632 } 645 633 … … 673 661 if ( count < 0 ) { 674 662 // queue current task 675 append( waiting, active_thread());663 append( waiting, kernelTLS.this_thread ); 676 664 677 665 // atomically release spin lock and block … … 723 711 void __cfaabi_dbg_record_lock(__spinlock_t & this, const char prev_name[]) { 724 712 this.prev_name = prev_name; 725 this.prev_thrd = kernelTLS ().this_thread;713 this.prev_thrd = kernelTLS.this_thread; 726 714 } 727 715 } … … 740 728 this.print_halts = true; 741 729 } 742 743 void print_stats_now( cluster & this, int flags ) {744 __print_stats( this.stats, this.print_stats, true, this.name, (void*)&this );745 }746 730 #endif 747 731 // Local Variables: //
Note:
See TracChangeset
for help on using the changeset viewer.