Changes in src/libcfa/concurrency/kernel.c [4aa2fb2:4e6fb8e]
- File:
-
- 1 edited
-
src/libcfa/concurrency/kernel.c (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/kernel.c
r4aa2fb2 r4e6fb8e 59 59 // Global state 60 60 61 thread_local processor * this_processor; 61 volatile thread_local processor * this_processor; 62 volatile thread_local unsigned short disable_preempt_count; 62 63 63 64 coroutine_desc * this_coroutine(void) { … … 142 143 this->preemption_alarm = NULL; 143 144 this->preemption = default_preemption(); 144 this->disable_preempt_count = 1; //Start with interrupts disabled145 145 this->pending_preemption = false; 146 146 … … 154 154 (&this->terminated){}; 155 155 this->is_terminated = false; 156 this->disable_preempt_count = 0; 156 this->preemption_alarm = NULL; 157 this->preemption = default_preemption(); 157 158 this->pending_preemption = false; 159 this->kernel_thread = pthread_self(); 158 160 159 161 this->runner = runner; 160 LIB_DEBUG_PRINT_SAFE("Kernel : constructing processor context %p\n", runner);162 LIB_DEBUG_PRINT_SAFE("Kernel : constructing system processor context %p\n", runner); 161 163 runner{ this }; 162 164 } 165 166 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); ) 163 167 164 168 void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) { … … 168 172 169 173 (&this->proc){ cltr, runner }; 174 175 LIB_DEBUG_DO( assert( validate( &this->alarms ) ) ); 170 176 } 171 177 … … 209 215 if(readyThread) 210 216 { 217 assert( disable_preempt_count > 0 ); 218 211 219 runThread(this, readyThread); 220 221 assert( disable_preempt_count > 0 ); 212 222 213 223 //Some actions need to be taken from the kernel … … 289 299 processor * proc = (processor *) arg; 290 300 this_processor = proc; 301 disable_preempt_count = 1; 291 302 // SKULLDUGGERY: We want to create a context for the processor coroutine 292 303 // which is needed for the 2-step context switch. However, there is no reason … … 311 322 // appropriate stack. 312 323 proc_cor_storage.__cor.state = Active; 313 main( &proc_cor_storage );314 proc_cor_storage.__cor.state = Halted;324 main( &proc_cor_storage ); 325 proc_cor_storage.__cor.state = Halted; 315 326 316 327 // Main routine of the core returned, the core is now fully terminated … … 322 333 void start(processor * this) { 323 334 LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this); 324 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 325 356 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 } // if 363 } // if 326 364 327 365 LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this); … … 333 371 if( !thrd ) return; 334 372 335 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );373 assertf( thrd->next == NULL, "Expected null got %p", thrd->next ); 336 374 337 375 lock( &systemProcessor->proc.cltr->lock ); … … 347 385 } 348 386 349 void ScheduleInternal() { 387 void BlockInternal() { 388 disable_interrupts(); 389 assert( disable_preempt_count > 0 ); 350 390 suspend(); 351 } 352 353 void ScheduleInternal( spinlock * lock ) { 391 assert( disable_preempt_count > 0 ); 392 enable_interrupts( __PRETTY_FUNCTION__ ); 393 } 394 395 void BlockInternal( spinlock * lock ) { 396 disable_interrupts(); 354 397 this_processor->finish.action_code = Release; 355 398 this_processor->finish.lock = lock; 399 assert( disable_preempt_count > 0 ); 356 400 suspend(); 357 } 358 359 void ScheduleInternal( thread_desc * thrd ) { 401 assert( disable_preempt_count > 0 ); 402 enable_interrupts( __PRETTY_FUNCTION__ ); 403 } 404 405 void BlockInternal( thread_desc * thrd ) { 406 disable_interrupts(); 360 407 this_processor->finish.action_code = Schedule; 361 408 this_processor->finish.thrd = thrd; 409 assert( disable_preempt_count > 0 ); 362 410 suspend(); 363 } 364 365 void ScheduleInternal( spinlock * lock, thread_desc * thrd ) { 411 assert( disable_preempt_count > 0 ); 412 enable_interrupts( __PRETTY_FUNCTION__ ); 413 } 414 415 void BlockInternal( spinlock * lock, thread_desc * thrd ) { 416 disable_interrupts(); 366 417 this_processor->finish.action_code = Release_Schedule; 367 418 this_processor->finish.lock = lock; 368 419 this_processor->finish.thrd = thrd; 420 assert( disable_preempt_count > 0 ); 369 421 suspend(); 370 } 371 372 void ScheduleInternal(spinlock ** locks, unsigned short count) { 422 assert( disable_preempt_count > 0 ); 423 enable_interrupts( __PRETTY_FUNCTION__ ); 424 } 425 426 void BlockInternal(spinlock ** locks, unsigned short count) { 427 disable_interrupts(); 373 428 this_processor->finish.action_code = Release_Multi; 374 429 this_processor->finish.locks = locks; 375 430 this_processor->finish.lock_count = count; 431 assert( disable_preempt_count > 0 ); 376 432 suspend(); 377 } 378 379 void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) { 433 assert( disable_preempt_count > 0 ); 434 enable_interrupts( __PRETTY_FUNCTION__ ); 435 } 436 437 void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) { 438 disable_interrupts(); 380 439 this_processor->finish.action_code = Release_Multi_Schedule; 381 440 this_processor->finish.locks = locks; … … 383 442 this_processor->finish.thrds = thrds; 384 443 this_processor->finish.thrd_count = thrd_count; 444 assert( disable_preempt_count > 0 ); 385 445 suspend(); 446 assert( disable_preempt_count > 0 ); 447 enable_interrupts( __PRETTY_FUNCTION__ ); 386 448 } 387 449 … … 403 465 LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n"); 404 466 405 // Enable preemption406 kernel_start_preemption();407 408 467 // Initialize the system cluster 409 468 systemCluster = (cluster *)&systemCluster_storage; … … 425 484 this_processor->current_thread = mainThread; 426 485 this_processor->current_coroutine = &mainThread->cor; 486 disable_preempt_count = 1; 487 488 // Enable preemption 489 kernel_start_preemption(); 427 490 428 491 // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX … … 435 498 // THE SYSTEM IS NOW COMPLETELY RUNNING 436 499 LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n"); 500 501 enable_interrupts( __PRETTY_FUNCTION__ ); 437 502 } 438 503 439 504 void kernel_shutdown(void) { 440 505 LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n"); 506 507 disable_interrupts(); 441 508 442 509 // SKULLDUGGERY: Notify the systemProcessor it needs to terminates. … … 447 514 448 515 // THE SYSTEM IS NOW COMPLETELY STOPPED 516 517 // Disable preemption 518 kernel_stop_preemption(); 449 519 450 520 // Destroy the system processor and its context in reverse order of construction … … 550 620 if( !this->cond ) { 551 621 append( &this->blocked, this_thread() ); 552 ScheduleInternal( &this->lock ); 553 lock( &this->lock ); 554 } 555 unlock( &this->lock ); 622 BlockInternal( &this->lock ); 623 } 624 else { 625 unlock( &this->lock ); 626 } 556 627 } 557 628 … … 561 632 this->cond = true; 562 633 634 disable_interrupts(); 563 635 thread_desc * it; 564 636 while( it = pop_head( &this->blocked) ) { 565 637 ScheduleThread( it ); 566 638 } 639 enable_interrupts( __PRETTY_FUNCTION__ ); 567 640 } 568 641 unlock( &this->lock ); … … 577 650 578 651 void append( __thread_queue_t * this, thread_desc * t ) { 579 verify(this->tail != NULL);652 assert(this->tail != NULL); 580 653 *this->tail = t; 581 654 this->tail = &t->next; … … 599 672 600 673 void push( __condition_stack_t * this, __condition_criterion_t * t ) { 601 verify( !t->next );674 assert( !t->next ); 602 675 t->next = this->top; 603 676 this->top = t;
Note:
See TracChangeset
for help on using the changeset viewer.