Changeset e60e0dc
- Timestamp:
- Jul 17, 2017, 3:54:02 PM (7 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:
- 5bd0aad
- Parents:
- b706db1
- Location:
- src/libcfa/concurrency
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/alarm.c
rb706db1 re60e0dc 153 153 154 154 void register_self( alarm_node_t * this ) { 155 alarm_list_t * alarms = &event_kernel->alarms; 156 155 157 disable_interrupts(); 156 verify( !systemProcessor->pending_alarm ); 157 lock( &systemProcessor->alarm_lock DEBUG_CTX2 ); 158 lock( &event_kernel->lock DEBUG_CTX2 ); 158 159 { 159 verify( validate( &systemProcessor->alarms ) );160 bool first = ! systemProcessor->alarms.head;160 verify( validate( alarms ) ); 161 bool first = !alarms->head; 161 162 162 insert( &systemProcessor->alarms, this ); 163 if( systemProcessor->pending_alarm ) { 164 tick_preemption(); 165 } 163 insert( alarms, this ); 166 164 if( first ) { 167 __kernel_set_timer( systemProcessor->alarms.head->alarm - __kernel_get_time() );165 __kernel_set_timer( alarms->head->alarm - __kernel_get_time() ); 168 166 } 169 167 } 170 unlock( & systemProcessor->alarm_lock );168 unlock( &event_kernel->lock ); 171 169 this->set = true; 172 170 enable_interrupts( DEBUG_CTX ); … … 174 172 175 173 void unregister_self( alarm_node_t * this ) { 176 // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : unregister %p start\n", this );177 174 disable_interrupts(); 178 lock( & systemProcessor->alarm_lock DEBUG_CTX2 );175 lock( &event_kernel->lock DEBUG_CTX2 ); 179 176 { 180 verify( validate( & systemProcessor->alarms ) );181 remove( & systemProcessor->alarms, this );177 verify( validate( &event_kernel->alarms ) ); 178 remove( &event_kernel->alarms, this ); 182 179 } 183 unlock( & systemProcessor->alarm_lock );180 unlock( &event_kernel->lock ); 184 181 enable_interrupts( DEBUG_CTX ); 185 182 this->set = false; 186 // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Kernel : unregister %p end\n", this );187 183 } -
src/libcfa/concurrency/kernel
rb706db1 re60e0dc 28 28 //----------------------------------------------------------------------------- 29 29 // Locks 30 bool try_lock ( spinlock * DEBUG_CTX_PARAM2 ); 31 void lock ( spinlock * DEBUG_CTX_PARAM2 );32 void lock_yield( spinlock * DEBUG_CTX_PARAM2 ); 33 void unlock ( spinlock * ); 30 void lock ( spinlock * DEBUG_CTX_PARAM2 ); // Lock the spinlock, spin if already acquired 31 void lock_yield( spinlock * DEBUG_CTX_PARAM2 ); // Lock the spinlock, yield repeatedly if already acquired 32 bool try_lock ( spinlock * DEBUG_CTX_PARAM2 ); // Lock the spinlock, return false if already acquired 33 void unlock ( spinlock * ); // Unlock the spinlock 34 34 35 35 struct semaphore { … … 48 48 // Cluster 49 49 struct cluster { 50 __thread_queue_t ready_queue; 51 spinlock lock; 50 spinlock ready_queue_lock; // Ready queue locks 51 __thread_queue_t ready_queue; // Ready queue for threads 52 unsigned long long int preemption; // Preemption rate on this cluster 52 53 }; 53 54 … … 76 77 static inline void ^?{}(FinishAction * this) {} 77 78 79 // Processor 80 // Wrapper around kernel threads 78 81 struct processor { 79 struct processorCtx_t * runner; 80 cluster * cltr; 81 pthread_t kernel_thread; 82 // Main state 83 struct processorCtx_t * runner; // Coroutine ctx who does keeps the state of the processor 84 cluster * cltr; // Cluster from which to get threads 85 pthread_t kernel_thread; // Handle to pthreads 82 86 83 semaphore terminated; 84 volatile bool is_terminated; 87 // Termination 88 volatile bool do_terminate; // Set to true to notify the processor should terminate 89 semaphore terminated; // Termination synchronisation 85 90 86 struct FinishAction finish; 91 // RunThread data 92 struct FinishAction finish; // Action to do after a thread is ran 87 93 88 struct alarm_node_t * preemption_alarm; 89 unsigned int preemption; 94 // Preemption data 95 struct alarm_node_t * preemption_alarm; // Node which is added in the discrete event simulaiton 96 bool pending_preemption; // If true, a preemption was triggered in an unsafe region, the processor must preempt as soon as possible 90 97 91 bool pending_preemption; 92 93 char * last_enable; 98 #ifdef __CFA_DEBUG__ 99 char * last_enable; // Last function to enable preemption on this processor 100 #endif 94 101 }; 95 102 -
src/libcfa/concurrency/kernel.c
rb706db1 re60e0dc 47 47 KERNEL_STORAGE(cluster, systemCluster); 48 48 KERNEL_STORAGE(system_proc_t, systemProcessor); 49 KERNEL_STORAGE(event_kernel_t, event_kernel); 49 50 KERNEL_STORAGE(thread_desc, mainThread); 50 51 KERNEL_STORAGE(machine_context_t, mainThreadCtx); … … 52 53 cluster * systemCluster; 53 54 system_proc_t * systemProcessor; 55 event_kernel_t * event_kernel; 54 56 thread_desc * mainThread; 55 57 … … 131 133 this->cltr = cltr; 132 134 (&this->terminated){ 0 }; 133 this-> is_terminated= false;135 this->do_terminate = false; 134 136 this->preemption_alarm = NULL; 135 this->preemption = default_preemption();136 137 this->pending_preemption = false; 137 138 … … 142 143 this->cltr = cltr; 143 144 (&this->terminated){ 0 }; 144 this-> is_terminated= false;145 this->do_terminate = false; 145 146 this->preemption_alarm = NULL; 146 this->preemption = default_preemption();147 147 this->pending_preemption = false; 148 148 this->kernel_thread = pthread_self(); … … 156 156 157 157 void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) { 158 (&this->proc){ cltr, runner }; 159 } 160 161 void ?{}(event_kernel_t * this) { 158 162 (&this->alarms){}; 159 (&this->alarm_lock){}; 160 this->pending_alarm = false; 161 162 (&this->proc){ cltr, runner }; 163 (&this->lock){}; 163 164 164 165 verify( validate( &this->alarms ) ); … … 166 167 167 168 void ^?{}(processor * this) { 168 if( ! this-> is_terminated) {169 if( ! this->do_terminate ) { 169 170 LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", this); 170 this-> is_terminated= true;171 this->do_terminate = true; 171 172 P( &this->terminated ); 172 173 pthread_join( this->kernel_thread, NULL ); … … 176 177 void ?{}(cluster * this) { 177 178 ( &this->ready_queue ){}; 178 ( &this->lock ){}; 179 ( &this->ready_queue_lock ){}; 180 181 this->preemption = default_preemption(); 179 182 } 180 183 … … 199 202 200 203 thread_desc * readyThread = NULL; 201 for( unsigned int spin_count = 0; ! this-> is_terminated; spin_count++ )204 for( unsigned int spin_count = 0; ! this->do_terminate; spin_count++ ) 202 205 { 203 206 readyThread = nextThread( this->cltr ); … … 343 346 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 344 347 345 lock( &systemProcessor->proc.cltr-> lock DEBUG_CTX2 );348 lock( &systemProcessor->proc.cltr->ready_queue_lock DEBUG_CTX2 ); 346 349 append( &systemProcessor->proc.cltr->ready_queue, thrd ); 347 unlock( &systemProcessor->proc.cltr-> lock );350 unlock( &systemProcessor->proc.cltr->ready_queue_lock ); 348 351 349 352 verify( disable_preempt_count > 0 ); … … 352 355 thread_desc * nextThread(cluster * this) { 353 356 verify( disable_preempt_count > 0 ); 354 lock( &this-> lock DEBUG_CTX2 );357 lock( &this->ready_queue_lock DEBUG_CTX2 ); 355 358 thread_desc * head = pop_head( &this->ready_queue ); 356 unlock( &this-> lock );359 unlock( &this->ready_queue_lock ); 357 360 verify( disable_preempt_count > 0 ); 358 361 return head; … … 470 473 systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtxStorage }; 471 474 475 // Initialize the event kernel 476 event_kernel = (event_kernel_t *)&event_kernelStorage; 477 event_kernel{}; 478 472 479 // Add the main thread to the ready queue 473 480 // once resume is called on systemProcessor->runner the mainThread needs to be scheduled like any normal thread … … 504 511 // When its coroutine terminates, it return control to the mainThread 505 512 // which is currently here 506 systemProcessor->proc. is_terminated= true;513 systemProcessor->proc.do_terminate = true; 507 514 suspend(); 508 515 -
src/libcfa/concurrency/kernel_private.h
rb706db1 re60e0dc 45 45 thread_desc * nextThread(cluster * this); 46 46 47 //Block current thread and release/wake-up the following resources 47 48 void BlockInternal(void); 48 49 void BlockInternal(spinlock * lock); … … 67 68 struct system_proc_t { 68 69 processor proc; 70 }; 69 71 72 struct event_kernel_t { 70 73 alarm_list_t alarms; 71 spinlock alarm_lock; 72 73 bool pending_alarm; 74 spinlock lock; 74 75 }; 75 76 76 77 extern cluster * systemCluster; 77 78 extern system_proc_t * systemProcessor; 79 extern event_kernel_t * event_kernel; 80 78 81 extern volatile thread_local processor * this_processor; 79 82 extern volatile thread_local coroutine_desc * this_coroutine; -
src/libcfa/concurrency/preemption.c
rb706db1 re60e0dc 66 66 67 67 void tick_preemption() { 68 alarm_list_t * alarms = & systemProcessor->alarms;68 alarm_list_t * alarms = &event_kernel->alarms; 69 69 __cfa_time_t currtime = __kernel_get_time(); 70 70 … … 189 189 } 190 190 191 static inline void defer_alarm() {192 systemProcessor->pending_alarm = true;193 }194 195 191 static void preempt( processor * this ) { 196 192 pthread_kill( this->kernel_thread, SIGUSR1 ); … … 236 232 this->proc = proc; 237 233 this->proc->preemption_alarm = &this->alarm; 238 update_preemption( this->proc, this->proc-> preemption );234 update_preemption( this->proc, this->proc->cltr->preemption ); 239 235 } 240 236 … … 283 279 case SI_KERNEL: 284 280 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n"); 285 lock( & systemProcessor->alarm_lock DEBUG_CTX2 );281 lock( &event_kernel->lock DEBUG_CTX2 ); 286 282 tick_preemption(); 287 unlock( & systemProcessor->alarm_lock );283 unlock( &event_kernel->lock ); 288 284 break; 289 285 case SI_QUEUE:
Note: See TracChangeset
for help on using the changeset viewer.