Changes in / [5bd0aad:59e86eb]
- Location:
- src
- Files:
-
- 6 edited
-
libcfa/concurrency/alarm.c (modified) (2 diffs)
-
libcfa/concurrency/kernel (modified) (3 diffs)
-
libcfa/concurrency/kernel.c (modified) (12 diffs)
-
libcfa/concurrency/kernel_private.h (modified) (2 diffs)
-
libcfa/concurrency/preemption.c (modified) (4 diffs)
-
tests/test.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/alarm.c
r5bd0aad r59e86eb 153 153 154 154 void register_self( alarm_node_t * this ) { 155 alarm_list_t * alarms = &event_kernel->alarms; 155 disable_interrupts(); 156 verify( !systemProcessor->pending_alarm ); 157 lock( &systemProcessor->alarm_lock DEBUG_CTX2 ); 158 { 159 verify( validate( &systemProcessor->alarms ) ); 160 bool first = !systemProcessor->alarms.head; 156 161 157 disable_interrupts(); 158 lock( &event_kernel->lock DEBUG_CTX2 ); 159 { 160 verify( validate( alarms ) ); 161 bool first = !alarms->head; 162 163 insert( alarms, this ); 162 insert( &systemProcessor->alarms, this ); 163 if( systemProcessor->pending_alarm ) { 164 tick_preemption(); 165 } 164 166 if( first ) { 165 __kernel_set_timer( alarms->head->alarm - __kernel_get_time() );167 __kernel_set_timer( systemProcessor->alarms.head->alarm - __kernel_get_time() ); 166 168 } 167 169 } 168 unlock( & event_kernel->lock );170 unlock( &systemProcessor->alarm_lock ); 169 171 this->set = true; 170 172 enable_interrupts( DEBUG_CTX ); … … 172 174 173 175 void unregister_self( alarm_node_t * this ) { 176 // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : unregister %p start\n", this ); 174 177 disable_interrupts(); 175 lock( & event_kernel->lock DEBUG_CTX2 );178 lock( &systemProcessor->alarm_lock DEBUG_CTX2 ); 176 179 { 177 verify( validate( & event_kernel->alarms ) );178 remove( & event_kernel->alarms, this );180 verify( validate( &systemProcessor->alarms ) ); 181 remove( &systemProcessor->alarms, this ); 179 182 } 180 unlock( & event_kernel->lock );183 unlock( &systemProcessor->alarm_lock ); 181 184 enable_interrupts( DEBUG_CTX ); 182 185 this->set = false; 186 // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Kernel : unregister %p end\n", this ); 183 187 } -
src/libcfa/concurrency/kernel
r5bd0aad r59e86eb 28 28 //----------------------------------------------------------------------------- 29 29 // Locks 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 acquired32 bool try_lock ( spinlock * DEBUG_CTX_PARAM2 ); // Lock the spinlock, return false if already acquired 33 void unlock ( spinlock * ); // Unlock the spinlock30 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 * ); 34 34 35 35 struct semaphore { … … 48 48 // Cluster 49 49 struct cluster { 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 50 __thread_queue_t ready_queue; 51 spinlock lock; 53 52 }; 54 53 … … 77 76 static inline void ^?{}(FinishAction * this) {} 78 77 79 // Processor80 // Wrapper around kernel threads81 78 struct processor { 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 79 struct processorCtx_t * runner; 80 cluster * cltr; 81 pthread_t kernel_thread; 86 82 87 // Termination 88 volatile bool do_terminate; // Set to true to notify the processor should terminate 89 semaphore terminated; // Termination synchronisation 83 semaphore terminated; 84 volatile bool is_terminated; 90 85 91 // RunThread data 92 struct FinishAction finish; // Action to do after a thread is ran 86 struct FinishAction finish; 93 87 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 88 struct alarm_node_t * preemption_alarm; 89 unsigned int preemption; 97 90 98 #ifdef __CFA_DEBUG__ 99 char * last_enable; // Last function to enable preemption on this processor 100 #endif 91 bool pending_preemption; 92 93 char * last_enable; 101 94 }; 102 95 -
src/libcfa/concurrency/kernel.c
r5bd0aad r59e86eb 47 47 KERNEL_STORAGE(cluster, systemCluster); 48 48 KERNEL_STORAGE(system_proc_t, systemProcessor); 49 KERNEL_STORAGE(event_kernel_t, event_kernel);50 49 KERNEL_STORAGE(thread_desc, mainThread); 51 50 KERNEL_STORAGE(machine_context_t, mainThreadCtx); … … 53 52 cluster * systemCluster; 54 53 system_proc_t * systemProcessor; 55 event_kernel_t * event_kernel;56 54 thread_desc * mainThread; 57 55 … … 133 131 this->cltr = cltr; 134 132 (&this->terminated){ 0 }; 135 this-> do_terminate= false;133 this->is_terminated = false; 136 134 this->preemption_alarm = NULL; 135 this->preemption = default_preemption(); 137 136 this->pending_preemption = false; 138 137 … … 143 142 this->cltr = cltr; 144 143 (&this->terminated){ 0 }; 145 this-> do_terminate= false;144 this->is_terminated = false; 146 145 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->alarms){}; 159 (&this->alarm_lock){}; 160 this->pending_alarm = false; 161 158 162 (&this->proc){ cltr, runner }; 159 }160 161 void ?{}(event_kernel_t * this) {162 (&this->alarms){};163 (&this->lock){};164 163 165 164 verify( validate( &this->alarms ) ); … … 167 166 168 167 void ^?{}(processor * this) { 169 if( ! this-> do_terminate) {168 if( ! this->is_terminated ) { 170 169 LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", this); 171 this-> do_terminate= true;170 this->is_terminated = true; 172 171 P( &this->terminated ); 173 172 pthread_join( this->kernel_thread, NULL ); … … 177 176 void ?{}(cluster * this) { 178 177 ( &this->ready_queue ){}; 179 ( &this->ready_queue_lock ){}; 180 181 this->preemption = default_preemption(); 178 ( &this->lock ){}; 182 179 } 183 180 … … 202 199 203 200 thread_desc * readyThread = NULL; 204 for( unsigned int spin_count = 0; ! this-> do_terminate; spin_count++ )201 for( unsigned int spin_count = 0; ! this->is_terminated; spin_count++ ) 205 202 { 206 203 readyThread = nextThread( this->cltr ); … … 346 343 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 347 344 348 lock( &systemProcessor->proc.cltr-> ready_queue_lock DEBUG_CTX2 );345 lock( &systemProcessor->proc.cltr->lock DEBUG_CTX2 ); 349 346 append( &systemProcessor->proc.cltr->ready_queue, thrd ); 350 unlock( &systemProcessor->proc.cltr-> ready_queue_lock );347 unlock( &systemProcessor->proc.cltr->lock ); 351 348 352 349 verify( disable_preempt_count > 0 ); … … 355 352 thread_desc * nextThread(cluster * this) { 356 353 verify( disable_preempt_count > 0 ); 357 lock( &this-> ready_queue_lock DEBUG_CTX2 );354 lock( &this->lock DEBUG_CTX2 ); 358 355 thread_desc * head = pop_head( &this->ready_queue ); 359 unlock( &this-> ready_queue_lock );356 unlock( &this->lock ); 360 357 verify( disable_preempt_count > 0 ); 361 358 return head; … … 473 470 systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtxStorage }; 474 471 475 // Initialize the event kernel476 event_kernel = (event_kernel_t *)&event_kernelStorage;477 event_kernel{};478 479 472 // Add the main thread to the ready queue 480 473 // once resume is called on systemProcessor->runner the mainThread needs to be scheduled like any normal thread … … 511 504 // When its coroutine terminates, it return control to the mainThread 512 505 // which is currently here 513 systemProcessor->proc. do_terminate= true;506 systemProcessor->proc.is_terminated = true; 514 507 suspend(); 515 508 -
src/libcfa/concurrency/kernel_private.h
r5bd0aad r59e86eb 45 45 thread_desc * nextThread(cluster * this); 46 46 47 //Block current thread and release/wake-up the following resources48 47 void BlockInternal(void); 49 48 void BlockInternal(spinlock * lock); … … 68 67 struct system_proc_t { 69 68 processor proc; 70 };71 69 72 struct event_kernel_t {73 70 alarm_list_t alarms; 74 spinlock lock; 71 spinlock alarm_lock; 72 73 bool pending_alarm; 75 74 }; 76 75 77 76 extern cluster * systemCluster; 78 77 extern system_proc_t * systemProcessor; 79 extern event_kernel_t * event_kernel;80 81 78 extern volatile thread_local processor * this_processor; 82 79 extern volatile thread_local coroutine_desc * this_coroutine; -
src/libcfa/concurrency/preemption.c
r5bd0aad r59e86eb 66 66 67 67 void tick_preemption() { 68 alarm_list_t * alarms = & event_kernel->alarms;68 alarm_list_t * alarms = &systemProcessor->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 191 195 static void preempt( processor * this ) { 192 196 pthread_kill( this->kernel_thread, SIGUSR1 ); … … 232 236 this->proc = proc; 233 237 this->proc->preemption_alarm = &this->alarm; 234 update_preemption( this->proc, this->proc-> cltr->preemption );238 update_preemption( this->proc, this->proc->preemption ); 235 239 } 236 240 … … 279 283 case SI_KERNEL: 280 284 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n"); 281 lock( & event_kernel->lock DEBUG_CTX2 );285 lock( &systemProcessor->alarm_lock DEBUG_CTX2 ); 282 286 tick_preemption(); 283 unlock( & event_kernel->lock );287 unlock( &systemProcessor->alarm_lock ); 284 288 break; 285 289 case SI_QUEUE: -
src/tests/test.py
r5bd0aad r59e86eb 221 221 if retcode == TestResult.SUCCESS: result_txt = "Done" 222 222 elif retcode == TestResult.TIMEOUT: result_txt = "TIMEOUT" 223 else : result_txt = "ERROR code %d" % retcode223 else : result_txt = "ERROR" 224 224 else : 225 225 if retcode == TestResult.SUCCESS: result_txt = "PASSED" 226 226 elif retcode == TestResult.TIMEOUT: result_txt = "TIMEOUT" 227 else : result_txt = "FAILED with code %d" % retcode227 else : result_txt = "FAILED" 228 228 229 229 #print result with error if needed
Note:
See TracChangeset
for help on using the changeset viewer.