Changes in src/libcfa/concurrency/kernel.c [6b0b624:d6ff3ff]
- File:
-
- 1 edited
-
src/libcfa/concurrency/kernel.c (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/kernel.c
r6b0b624 rd6ff3ff 1 // -*- Mode: CFA -*- 1 2 // 2 3 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 9 10 // Author : Thierry Delisle 10 11 // Created On : Tue Jan 17 12:27:26 2017 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Jul 21 22:33:18 201713 // Update Count : 212 // Last Modified By : Thierry Delisle 13 // Last Modified On : -- 14 // Update Count : 0 14 15 // 15 16 … … 41 42 //----------------------------------------------------------------------------- 42 43 // Kernel storage 43 KERNEL_STORAGE(cluster, mainCluster); 44 KERNEL_STORAGE(processor, mainProcessor); 45 KERNEL_STORAGE(processorCtx_t, mainProcessorCtx); 46 KERNEL_STORAGE(thread_desc, mainThread); 44 #define KERNEL_STORAGE(T,X) static char X##Storage[sizeof(T)] 45 46 KERNEL_STORAGE(processorCtx_t, systemProcessorCtx); 47 KERNEL_STORAGE(cluster, systemCluster); 48 KERNEL_STORAGE(system_proc_t, systemProcessor); 49 KERNEL_STORAGE(thread_desc, mainThread); 47 50 KERNEL_STORAGE(machine_context_t, mainThreadCtx); 48 51 49 cluster * mainCluster;50 processor * mainProcessor;52 cluster * systemCluster; 53 system_proc_t * systemProcessor; 51 54 thread_desc * mainThread; 52 55 … … 54 57 // Global state 55 58 56 thread_local coroutine_desc * volatile this_coroutine; 57 thread_local thread_desc * volatile this_thread; 58 thread_local processor * volatile this_processor; 59 59 volatile thread_local processor * this_processor; 60 volatile thread_local coroutine_desc * this_coroutine; 61 volatile thread_local thread_desc * this_thread; 60 62 volatile thread_local bool preemption_in_progress = 0; 61 63 volatile thread_local unsigned short disable_preempt_count = 1; … … 83 85 84 86 this->limit = (void *)(((intptr_t)this->base) - this->size); 85 this->context = & storage_mainThreadCtx;87 this->context = &mainThreadCtxStorage; 86 88 this->top = this->base; 87 89 } … … 123 125 124 126 void ?{}(processor * this) { 125 this{ mainCluster };127 this{ systemCluster }; 126 128 } 127 129 … … 129 131 this->cltr = cltr; 130 132 (&this->terminated){ 0 }; 131 this-> do_terminate= false;133 this->is_terminated = false; 132 134 this->preemption_alarm = NULL; 135 this->preemption = default_preemption(); 133 136 this->pending_preemption = false; 134 137 … … 139 142 this->cltr = cltr; 140 143 (&this->terminated){ 0 }; 141 this-> do_terminate= false;144 this->is_terminated = false; 142 145 this->preemption_alarm = NULL; 146 this->preemption = default_preemption(); 143 147 this->pending_preemption = false; 144 148 this->kernel_thread = pthread_self(); 145 149 146 150 this->runner = runner; 147 LIB_DEBUG_PRINT_SAFE("Kernel : constructing mainprocessor context %p\n", runner);151 LIB_DEBUG_PRINT_SAFE("Kernel : constructing system processor context %p\n", runner); 148 152 runner{ this }; 149 153 } 150 154 155 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); ) 156 157 void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) { 158 (&this->alarms){}; 159 (&this->alarm_lock){}; 160 this->pending_alarm = false; 161 162 (&this->proc){ cltr, runner }; 163 164 verify( validate( &this->alarms ) ); 165 } 166 151 167 void ^?{}(processor * this) { 152 if( ! this-> do_terminate) {168 if( ! this->is_terminated ) { 153 169 LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", this); 154 this-> do_terminate= true;170 this->is_terminated = true; 155 171 P( &this->terminated ); 156 172 pthread_join( this->kernel_thread, NULL ); … … 160 176 void ?{}(cluster * this) { 161 177 ( &this->ready_queue ){}; 162 ( &this->ready_queue_lock ){}; 163 164 this->preemption = default_preemption(); 178 ( &this->lock ){}; 165 179 } 166 180 … … 185 199 186 200 thread_desc * readyThread = NULL; 187 for( unsigned int spin_count = 0; ! this-> do_terminate; spin_count++ )201 for( unsigned int spin_count = 0; ! this->is_terminated; spin_count++ ) 188 202 { 189 203 readyThread = nextThread( this->cltr ); … … 329 343 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 330 344 331 lock( &this_processor->cltr->ready_queue_lock DEBUG_CTX2 );332 append( & this_processor->cltr->ready_queue, thrd );333 unlock( & this_processor->cltr->ready_queue_lock );345 lock( &systemProcessor->proc.cltr->lock DEBUG_CTX2 ); 346 append( &systemProcessor->proc.cltr->ready_queue, thrd ); 347 unlock( &systemProcessor->proc.cltr->lock ); 334 348 335 349 verify( disable_preempt_count > 0 ); … … 338 352 thread_desc * nextThread(cluster * this) { 339 353 verify( disable_preempt_count > 0 ); 340 lock( &this-> ready_queue_lock DEBUG_CTX2 );354 lock( &this->lock DEBUG_CTX2 ); 341 355 thread_desc * head = pop_head( &this->ready_queue ); 342 unlock( &this-> ready_queue_lock );356 unlock( &this->lock ); 343 357 verify( disable_preempt_count > 0 ); 344 358 return head; … … 438 452 // Start by initializing the main thread 439 453 // SKULLDUGGERY: the mainThread steals the process main thread 440 // which will then be scheduled by the mainProcessor normally441 mainThread = (thread_desc *)& storage_mainThread;454 // which will then be scheduled by the systemProcessor normally 455 mainThread = (thread_desc *)&mainThreadStorage; 442 456 current_stack_info_t info; 443 457 mainThread{ &info }; … … 445 459 LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n"); 446 460 447 // Initialize the maincluster448 mainCluster = (cluster *)&storage_mainCluster;449 mainCluster{};450 451 LIB_DEBUG_PRINT_SAFE("Kernel : maincluster ready\n");452 453 // Initialize the main processor and the mainprocessor ctx461 // Initialize the system cluster 462 systemCluster = (cluster *)&systemClusterStorage; 463 systemCluster{}; 464 465 LIB_DEBUG_PRINT_SAFE("Kernel : System cluster ready\n"); 466 467 // Initialize the system processor and the system processor ctx 454 468 // (the coroutine that contains the processing control flow) 455 mainProcessor = (processor *)&storage_mainProcessor; 456 mainProcessor{ mainCluster, (processorCtx_t *)&storage_mainProcessorCtx }; 469 systemProcessor = (system_proc_t *)&systemProcessorStorage; 470 systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtxStorage }; 471 472 // Add the main thread to the ready queue 473 // once resume is called on systemProcessor->runner the mainThread needs to be scheduled like any normal thread 474 ScheduleThread(mainThread); 457 475 458 476 //initialize the global state variables 459 this_processor = mainProcessor;477 this_processor = &systemProcessor->proc; 460 478 this_thread = mainThread; 461 479 this_coroutine = &mainThread->cor; 480 disable_preempt_count = 1; 462 481 463 482 // Enable preemption 464 483 kernel_start_preemption(); 465 484 466 // Add the main thread to the ready queue 467 // once resume is called on mainProcessor->runner the mainThread needs to be scheduled like any normal thread 468 ScheduleThread(mainThread); 469 470 // SKULLDUGGERY: Force a context switch to the main processor to set the main thread's context to the current UNIX 485 // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX 471 486 // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that 472 487 // mainThread is on the ready queue when this call is made. 473 resume( mainProcessor->runner );488 resume( systemProcessor->proc.runner ); 474 489 475 490 … … 486 501 disable_interrupts(); 487 502 488 // SKULLDUGGERY: Notify the mainProcessor it needs to terminates.503 // SKULLDUGGERY: Notify the systemProcessor it needs to terminates. 489 504 // When its coroutine terminates, it return control to the mainThread 490 505 // which is currently here 491 mainProcessor->do_terminate= true;506 systemProcessor->proc.is_terminated = true; 492 507 suspend(); 493 508 … … 497 512 kernel_stop_preemption(); 498 513 499 // Destroy the mainprocessor and its context in reverse order of construction514 // Destroy the system processor and its context in reverse order of construction 500 515 // These were manually constructed so we need manually destroy them 501 ^( mainProcessor->runner){};502 ^( mainProcessor){};516 ^(systemProcessor->proc.runner){}; 517 ^(systemProcessor){}; 503 518 504 519 // Final step, destroy the main thread since it is no longer needed … … 684 699 return top; 685 700 } 686 687 701 // Local Variables: // 688 702 // mode: c //
Note:
See TracChangeset
for help on using the changeset viewer.