- File:
-
- 1 edited
-
src/libcfa/concurrency/kernel.c (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/kernel.c
rc81ebf9 r82ff5845 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(); 158 this->disable_preempt_count = 1; 157 159 this->pending_preemption = false; 160 this->kernel_thread = pthread_self(); 158 161 159 162 this->runner = runner; 160 LIB_DEBUG_PRINT_SAFE("Kernel : constructing processor context %p\n", runner);163 LIB_DEBUG_PRINT_SAFE("Kernel : constructing system processor context %p\n", runner); 161 164 runner{ this }; 162 165 } … … 240 243 //Update global state 241 244 this->current_thread = dst; 245 246 LIB_DEBUG_PRINT_SAFE("Kernel : running %p\n", dst); 242 247 243 248 // Context Switch to the thread … … 322 327 void start(processor * this) { 323 328 LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this); 324 329 330 // SIGALRM must only be caught by the system processor 331 sigset_t old_mask; 332 bool is_system_proc = this_processor == &systemProcessor->proc; 333 if ( is_system_proc ) { 334 // Child kernel-thread inherits the signal mask from the parent kernel-thread. So one special case for the 335 // system processor creating the user processor => toggle the blocking SIGALRM on system processor, create user 336 // processor, and toggle back (below) previous signal mask of the system processor. 337 338 sigset_t new_mask; 339 sigemptyset( &new_mask ); 340 sigemptyset( &old_mask ); 341 sigaddset( &new_mask, SIGALRM ); 342 343 if ( sigprocmask( SIG_BLOCK, &new_mask, &old_mask ) == -1 ) { 344 abortf( "internal error, sigprocmask" ); 345 } 346 347 assert( ! sigismember( &old_mask, SIGALRM ) ); 348 } 349 325 350 pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this ); 351 352 // Toggle back previous signal mask of system processor. 353 if ( is_system_proc ) { 354 if ( sigprocmask( SIG_SETMASK, &old_mask, NULL ) == -1 ) { 355 abortf( "internal error, sigprocmask" ); 356 } // if 357 } // if 326 358 327 359 LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this); … … 347 379 } 348 380 349 void ScheduleInternal() { 381 void BlockInternal() { 382 disable_interrupts(); 350 383 suspend(); 351 } 352 353 void ScheduleInternal( spinlock * lock ) { 384 enable_interrupts(); 385 } 386 387 void BlockInternal( spinlock * lock ) { 388 disable_interrupts(); 354 389 this_processor->finish.action_code = Release; 355 390 this_processor->finish.lock = lock; 356 391 suspend(); 357 } 358 359 void ScheduleInternal( thread_desc * thrd ) { 392 enable_interrupts(); 393 } 394 395 void BlockInternal( thread_desc * thrd ) { 396 disable_interrupts(); 360 397 this_processor->finish.action_code = Schedule; 361 398 this_processor->finish.thrd = thrd; 362 399 suspend(); 363 } 364 365 void ScheduleInternal( spinlock * lock, thread_desc * thrd ) { 400 enable_interrupts(); 401 } 402 403 void BlockInternal( spinlock * lock, thread_desc * thrd ) { 404 disable_interrupts(); 366 405 this_processor->finish.action_code = Release_Schedule; 367 406 this_processor->finish.lock = lock; 368 407 this_processor->finish.thrd = thrd; 369 408 suspend(); 370 } 371 372 void ScheduleInternal(spinlock ** locks, unsigned short count) { 409 enable_interrupts(); 410 } 411 412 void BlockInternal(spinlock ** locks, unsigned short count) { 413 disable_interrupts(); 373 414 this_processor->finish.action_code = Release_Multi; 374 415 this_processor->finish.locks = locks; 375 416 this_processor->finish.lock_count = count; 376 417 suspend(); 377 } 378 379 void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) { 418 enable_interrupts(); 419 } 420 421 void BlockInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) { 422 disable_interrupts(); 380 423 this_processor->finish.action_code = Release_Multi_Schedule; 381 424 this_processor->finish.locks = locks; … … 384 427 this_processor->finish.thrd_count = thrd_count; 385 428 suspend(); 429 enable_interrupts(); 386 430 } 387 431 … … 403 447 LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n"); 404 448 405 // Enable preemption406 kernel_start_preemption();407 408 449 // Initialize the system cluster 409 450 systemCluster = (cluster *)&systemCluster_storage; … … 426 467 this_processor->current_coroutine = &mainThread->cor; 427 468 469 // Enable preemption 470 kernel_start_preemption(); 471 428 472 // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX 429 473 // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that … … 435 479 // THE SYSTEM IS NOW COMPLETELY RUNNING 436 480 LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n"); 481 482 enable_interrupts(); 437 483 } 438 484 … … 447 493 448 494 // THE SYSTEM IS NOW COMPLETELY STOPPED 495 496 // Disable preemption 497 kernel_stop_preemption(); 449 498 450 499 // Destroy the system processor and its context in reverse order of construction … … 550 599 if( !this->cond ) { 551 600 append( &this->blocked, this_thread() ); 552 ScheduleInternal( &this->lock );601 BlockInternal( &this->lock ); 553 602 lock( &this->lock ); 554 603 }
Note:
See TracChangeset
for help on using the changeset viewer.