Changeset 33218c6 for src/libcfa/concurrency/kernel.c
- Timestamp:
- Jul 26, 2017, 12:19:41 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- b947fb2
- Parents:
- e0a653d (diff), ea91c42 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/kernel.c
re0a653d r33218c6 1 // -*- Mode: CFA -*-2 1 // 3 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 10 9 // Author : Thierry Delisle 11 10 // Created On : Tue Jan 17 12:27:26 2017 12 // Last Modified By : Thierry Delisle13 // Last Modified On : --14 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 21 22:33:18 2017 13 // Update Count : 2 15 14 // 16 15 … … 42 41 //----------------------------------------------------------------------------- 43 42 // Kernel storage 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); 43 KERNEL_STORAGE(cluster, mainCluster); 44 KERNEL_STORAGE(processor, mainProcessor); 45 KERNEL_STORAGE(processorCtx_t, mainProcessorCtx); 46 KERNEL_STORAGE(thread_desc, mainThread); 50 47 KERNEL_STORAGE(machine_context_t, mainThreadCtx); 51 48 52 cluster * systemCluster;53 system_proc_t * systemProcessor;49 cluster * mainCluster; 50 processor * mainProcessor; 54 51 thread_desc * mainThread; 55 52 … … 57 54 // Global state 58 55 59 volatile thread_local processor * this_processor; 60 volatile thread_local coroutine_desc * this_coroutine; 61 volatile thread_local thread_desc * this_thread; 56 thread_local coroutine_desc * volatile this_coroutine; 57 thread_local thread_desc * volatile this_thread; 58 thread_local processor * volatile this_processor; 59 60 volatile thread_local bool preemption_in_progress = 0; 62 61 volatile thread_local unsigned short disable_preempt_count = 1; 63 62 … … 84 83 85 84 this->limit = (void *)(((intptr_t)this->base) - this->size); 86 this->context = & mainThreadCtxStorage;85 this->context = &storage_mainThreadCtx; 87 86 this->top = this->base; 88 87 } … … 124 123 125 124 void ?{}(processor * this) { 126 this{ systemCluster };125 this{ mainCluster }; 127 126 } 128 127 … … 130 129 this->cltr = cltr; 131 130 (&this->terminated){ 0 }; 132 this-> is_terminated= false;131 this->do_terminate = false; 133 132 this->preemption_alarm = NULL; 134 this->preemption = default_preemption();135 133 this->pending_preemption = false; 136 134 … … 141 139 this->cltr = cltr; 142 140 (&this->terminated){ 0 }; 143 this-> is_terminated= false;141 this->do_terminate = false; 144 142 this->preemption_alarm = NULL; 145 this->preemption = default_preemption();146 143 this->pending_preemption = false; 147 144 this->kernel_thread = pthread_self(); 148 145 149 146 this->runner = runner; 150 LIB_DEBUG_PRINT_SAFE("Kernel : constructing systemprocessor context %p\n", runner);147 LIB_DEBUG_PRINT_SAFE("Kernel : constructing main processor context %p\n", runner); 151 148 runner{ this }; 152 149 } 153 150 154 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )155 156 void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) {157 (&this->alarms){};158 (&this->alarm_lock){};159 this->pending_alarm = false;160 161 (&this->proc){ cltr, runner };162 163 verify( validate( &this->alarms ) );164 }165 166 151 void ^?{}(processor * this) { 167 if( ! this-> is_terminated) {152 if( ! this->do_terminate ) { 168 153 LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", this); 169 this-> is_terminated= true;154 this->do_terminate = true; 170 155 P( &this->terminated ); 171 156 pthread_join( this->kernel_thread, NULL ); … … 175 160 void ?{}(cluster * this) { 176 161 ( &this->ready_queue ){}; 177 ( &this->lock ){}; 162 ( &this->ready_queue_lock ){}; 163 164 this->preemption = default_preemption(); 178 165 } 179 166 … … 198 185 199 186 thread_desc * readyThread = NULL; 200 for( unsigned int spin_count = 0; ! this-> is_terminated; spin_count++ )187 for( unsigned int spin_count = 0; ! this->do_terminate; spin_count++ ) 201 188 { 202 189 readyThread = nextThread( this->cltr ); … … 342 329 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 343 330 344 lock( &systemProcessor->proc.cltr->lock DEBUG_CTX2 );345 append( & systemProcessor->proc.cltr->ready_queue, thrd );346 unlock( & systemProcessor->proc.cltr->lock );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 ); 347 334 348 335 verify( disable_preempt_count > 0 ); … … 351 338 thread_desc * nextThread(cluster * this) { 352 339 verify( disable_preempt_count > 0 ); 353 lock( &this-> lock DEBUG_CTX2 );340 lock( &this->ready_queue_lock DEBUG_CTX2 ); 354 341 thread_desc * head = pop_head( &this->ready_queue ); 355 unlock( &this-> lock );342 unlock( &this->ready_queue_lock ); 356 343 verify( disable_preempt_count > 0 ); 357 344 return head; … … 451 438 // Start by initializing the main thread 452 439 // SKULLDUGGERY: the mainThread steals the process main thread 453 // which will then be scheduled by the systemProcessor normally454 mainThread = (thread_desc *)& mainThreadStorage;440 // which will then be scheduled by the mainProcessor normally 441 mainThread = (thread_desc *)&storage_mainThread; 455 442 current_stack_info_t info; 456 443 mainThread{ &info }; … … 458 445 LIB_DEBUG_PRINT_SAFE("Kernel : Main thread ready\n"); 459 446 460 // Initialize the systemcluster461 systemCluster = (cluster *)&systemClusterStorage;462 systemCluster{};463 464 LIB_DEBUG_PRINT_SAFE("Kernel : Systemcluster ready\n");465 466 // Initialize the system processor and the systemprocessor ctx447 // Initialize the main cluster 448 mainCluster = (cluster *)&storage_mainCluster; 449 mainCluster{}; 450 451 LIB_DEBUG_PRINT_SAFE("Kernel : main cluster ready\n"); 452 453 // Initialize the main processor and the main processor ctx 467 454 // (the coroutine that contains the processing control flow) 468 systemProcessor = (system_proc_t *)&systemProcessorStorage; 469 systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtxStorage }; 470 471 // Add the main thread to the ready queue 472 // once resume is called on systemProcessor->runner the mainThread needs to be scheduled like any normal thread 473 ScheduleThread(mainThread); 455 mainProcessor = (processor *)&storage_mainProcessor; 456 mainProcessor{ mainCluster, (processorCtx_t *)&storage_mainProcessorCtx }; 474 457 475 458 //initialize the global state variables 476 this_processor = &systemProcessor->proc;459 this_processor = mainProcessor; 477 460 this_thread = mainThread; 478 461 this_coroutine = &mainThread->cor; 479 disable_preempt_count = 1;480 462 481 463 // Enable preemption 482 464 kernel_start_preemption(); 483 465 484 // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX 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 471 // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that 486 472 // mainThread is on the ready queue when this call is made. 487 resume( systemProcessor->proc.runner );473 resume( mainProcessor->runner ); 488 474 489 475 … … 500 486 disable_interrupts(); 501 487 502 // SKULLDUGGERY: Notify the systemProcessor it needs to terminates.488 // SKULLDUGGERY: Notify the mainProcessor it needs to terminates. 503 489 // When its coroutine terminates, it return control to the mainThread 504 490 // which is currently here 505 systemProcessor->proc.is_terminated= true;491 mainProcessor->do_terminate = true; 506 492 suspend(); 507 493 … … 511 497 kernel_stop_preemption(); 512 498 513 // Destroy the systemprocessor and its context in reverse order of construction499 // Destroy the main processor and its context in reverse order of construction 514 500 // These were manually constructed so we need manually destroy them 515 ^( systemProcessor->proc.runner){};516 ^( systemProcessor){};501 ^(mainProcessor->runner){}; 502 ^(mainProcessor){}; 517 503 518 504 // Final step, destroy the main thread since it is no longer needed … … 698 684 return top; 699 685 } 686 700 687 // Local Variables: // 701 688 // mode: c //
Note:
See TracChangeset
for help on using the changeset viewer.