Changes in src/libcfa/concurrency/kernel.c [0b33412:4aa2fb2]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/kernel.c
r0b33412 r4aa2fb2 59 59 // Global state 60 60 61 volatile thread_local processor * this_processor; 62 volatile thread_local unsigned short disable_preempt_count; 61 thread_local processor * this_processor; 63 62 64 63 coroutine_desc * this_coroutine(void) { … … 143 142 this->preemption_alarm = NULL; 144 143 this->preemption = default_preemption(); 144 this->disable_preempt_count = 1; //Start with interrupts disabled 145 145 this->pending_preemption = false; 146 146 … … 154 154 (&this->terminated){}; 155 155 this->is_terminated = false; 156 this->preemption_alarm = NULL; 157 this->preemption = default_preemption(); 156 this->disable_preempt_count = 0; 158 157 this->pending_preemption = false; 159 this->kernel_thread = pthread_self();160 158 161 159 this->runner = runner; 162 LIB_DEBUG_PRINT_SAFE("Kernel : constructing systemprocessor context %p\n", runner);160 LIB_DEBUG_PRINT_SAFE("Kernel : constructing processor context %p\n", runner); 163 161 runner{ this }; 164 162 } 165 166 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )167 163 168 164 void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) { … … 172 168 173 169 (&this->proc){ cltr, runner }; 174 175 verify( validate( &this->alarms ) );176 170 } 177 171 … … 215 209 if(readyThread) 216 210 { 217 verify( disable_preempt_count > 0 );218 219 211 runThread(this, readyThread); 220 221 verify( disable_preempt_count > 0 );222 212 223 213 //Some actions need to be taken from the kernel … … 299 289 processor * proc = (processor *) arg; 300 290 this_processor = proc; 301 disable_preempt_count = 1;302 291 // SKULLDUGGERY: We want to create a context for the processor coroutine 303 292 // which is needed for the 2-step context switch. However, there is no reason … … 333 322 void start(processor * this) { 334 323 LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this); 335 336 // SIGALRM must only be caught by the system processor 337 sigset_t old_mask; 338 bool is_system_proc = this_processor == &systemProcessor->proc; 339 if ( is_system_proc ) { 340 // Child kernel-thread inherits the signal mask from the parent kernel-thread. So one special case for the 341 // system processor creating the user processor => toggle the blocking SIGALRM on system processor, create user 342 // processor, and toggle back (below) previous signal mask of the system processor. 343 344 sigset_t new_mask; 345 sigemptyset( &new_mask ); 346 sigemptyset( &old_mask ); 347 sigaddset( &new_mask, SIGALRM ); 348 349 if ( sigprocmask( SIG_BLOCK, &new_mask, &old_mask ) == -1 ) { 350 abortf( "internal error, sigprocmask" ); 351 } 352 353 assert( ! sigismember( &old_mask, SIGALRM ) ); 354 } 355 324 356 325 pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this ); 357 358 // Toggle back previous signal mask of system processor.359 if ( is_system_proc ) {360 if ( sigprocmask( SIG_SETMASK, &old_mask, NULL ) == -1 ) {361 abortf( "internal error, sigprocmask" );362 } // if363 } // if364 326 365 327 LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this); … … 385 347 } 386 348 387 void BlockInternal() { 388 disable_interrupts(); 389 verify( disable_preempt_count > 0 ); 349 void ScheduleInternal() { 390 350 suspend(); 391 verify( disable_preempt_count > 0 ); 392 enable_interrupts( __PRETTY_FUNCTION__ ); 393 } 394 395 void BlockInternal( spinlock * lock ) { 396 disable_interrupts(); 351 } 352 353 void ScheduleInternal( spinlock * lock ) { 397 354 this_processor->finish.action_code = Release; 398 355 this_processor->finish.lock = lock; 399 400 verify( disable_preempt_count > 0 );401 356 suspend(); 402 verify( disable_preempt_count > 0 ); 403 404 enable_interrupts( __PRETTY_FUNCTION__ ); 405 } 406 407 void BlockInternal( thread_desc * thrd ) { 408 disable_interrupts(); 357 } 358 359 void ScheduleInternal( thread_desc * thrd ) { 409 360 this_processor->finish.action_code = Schedule; 410 361 this_processor->finish.thrd = thrd; 411 412 verify( disable_preempt_count > 0 );413 362 suspend(); 414 verify( disable_preempt_count > 0 ); 415 416 enable_interrupts( __PRETTY_FUNCTION__ ); 417 } 418 419 void BlockInternal( spinlock * lock, thread_desc * thrd ) { 420 disable_interrupts(); 363 } 364 365 void ScheduleInternal( spinlock * lock, thread_desc * thrd ) { 421 366 this_processor->finish.action_code = Release_Schedule; 422 367 this_processor->finish.lock = lock; 423 368 this_processor->finish.thrd = thrd; 424 425 verify( disable_preempt_count > 0 );426 369 suspend(); 427 verify( disable_preempt_count > 0 ); 428 429 enable_interrupts( __PRETTY_FUNCTION__ ); 430 } 431 432 void BlockInternal(spinlock ** locks, unsigned short count) { 433 disable_interrupts(); 370 } 371 372 void ScheduleInternal(spinlock ** locks, unsigned short count) { 434 373 this_processor->finish.action_code = Release_Multi; 435 374 this_processor->finish.locks = locks; 436 375 this_processor->finish.lock_count = count; 437 438 verify( disable_preempt_count > 0 );439 376 suspend(); 440 verify( disable_preempt_count > 0 ); 441 442 enable_interrupts( __PRETTY_FUNCTION__ ); 443 } 444 445 void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) { 446 disable_interrupts(); 377 } 378 379 void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) { 447 380 this_processor->finish.action_code = Release_Multi_Schedule; 448 381 this_processor->finish.locks = locks; … … 450 383 this_processor->finish.thrds = thrds; 451 384 this_processor->finish.thrd_count = thrd_count; 452 453 verify( disable_preempt_count > 0 );454 385 suspend(); 455 verify( disable_preempt_count > 0 );456 457 enable_interrupts( __PRETTY_FUNCTION__ );458 386 } 459 387 … … 475 403 LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n"); 476 404 405 // Enable preemption 406 kernel_start_preemption(); 407 477 408 // Initialize the system cluster 478 409 systemCluster = (cluster *)&systemCluster_storage; … … 494 425 this_processor->current_thread = mainThread; 495 426 this_processor->current_coroutine = &mainThread->cor; 496 disable_preempt_count = 1;497 498 // Enable preemption499 kernel_start_preemption();500 427 501 428 // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX … … 508 435 // THE SYSTEM IS NOW COMPLETELY RUNNING 509 436 LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n"); 510 511 enable_interrupts( __PRETTY_FUNCTION__ );512 437 } 513 438 514 439 void kernel_shutdown(void) { 515 440 LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n"); 516 517 disable_interrupts();518 441 519 442 // SKULLDUGGERY: Notify the systemProcessor it needs to terminates. … … 524 447 525 448 // THE SYSTEM IS NOW COMPLETELY STOPPED 526 527 // Disable preemption528 kernel_stop_preemption();529 449 530 450 // Destroy the system processor and its context in reverse order of construction … … 630 550 if( !this->cond ) { 631 551 append( &this->blocked, this_thread() ); 632 BlockInternal( &this->lock ); 633 } 634 else { 635 unlock( &this->lock ); 636 } 552 ScheduleInternal( &this->lock ); 553 lock( &this->lock ); 554 } 555 unlock( &this->lock ); 637 556 } 638 557 … … 642 561 this->cond = true; 643 562 644 disable_interrupts();645 563 thread_desc * it; 646 564 while( it = pop_head( &this->blocked) ) { 647 565 ScheduleThread( it ); 648 566 } 649 enable_interrupts( __PRETTY_FUNCTION__ );650 567 } 651 568 unlock( &this->lock );
Note: See TracChangeset
for help on using the changeset viewer.