Changeset 4e6fb8e for src/libcfa/concurrency
- Timestamp:
- Jun 16, 2017, 4:45:20 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:
- ec35498
- Parents:
- 70c2df8
- Location:
- src/libcfa/concurrency
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/alarm.c
r70c2df8 r4e6fb8e 89 89 } 90 90 91 LIB_DEBUG_DO( bool validate( alarm_list_t * this ) { 92 alarm_node_t ** it = &this->head; 93 while( (*it) ) { 94 it = &(*it)->next; 95 } 96 97 return it == this->tail; 98 }) 99 91 100 static inline void insert_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t p ) { 92 101 assert( !n->next ); … … 98 107 } 99 108 *p = n; 109 110 LIB_DEBUG_DO( assert( validate( this ) ) ); 100 111 } 101 112 … … 107 118 108 119 insert_at( this, n, it ); 120 121 LIB_DEBUG_DO( assert( validate( this ) ) ); 109 122 } 110 123 … … 118 131 head->next = NULL; 119 132 } 133 LIB_DEBUG_DO( assert( validate( this ) ) ); 120 134 return head; 121 135 } … … 123 137 static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) { 124 138 assert( it ); 125 assert( (*it) ->next== n );126 127 (*it) ->next= n->next;139 assert( (*it) == n ); 140 141 (*it) = n->next; 128 142 if( !n-> next ) { 129 143 this->tail = it; 130 144 } 131 145 n->next = NULL; 146 147 LIB_DEBUG_DO( assert( validate( this ) ) ); 132 148 } 133 149 134 150 static inline void remove( alarm_list_t * this, alarm_node_t * n ) { 135 151 alarm_node_t ** it = &this->head; 136 while( (*it) && (*it) ->next!= n ) {152 while( (*it) && (*it) != n ) { 137 153 it = &(*it)->next; 138 154 } 139 155 156 LIB_DEBUG_DO( assert( validate( this ) ) ); 157 140 158 if( *it ) { remove_at( this, n, it ); } 159 160 LIB_DEBUG_DO( assert( validate( this ) ) ); 141 161 } 142 162 … … 145 165 assert( !systemProcessor->pending_alarm ); 146 166 lock( &systemProcessor->alarm_lock ); 167 LIB_DEBUG_DO( assert( validate( &systemProcessor->alarms ) ) ); 147 168 { 148 169 bool first = !systemProcessor->alarms.head; … … 158 179 unlock( &systemProcessor->alarm_lock ); 159 180 this->set = true; 160 enable_interrupts( );181 enable_interrupts( __PRETTY_FUNCTION__ ); 161 182 } 162 183 163 184 void unregister_self( alarm_node_t * this ) { 185 LIB_DEBUG_DO( 186 char text[256]; 187 __attribute__((unused)) int len = snprintf( text, 256, "Kernel : unregister %p start\n", this ); 188 LIB_DEBUG_WRITE( STDERR_FILENO, text, len ); 189 ); 164 190 disable_interrupts(); 165 191 lock( &systemProcessor->alarm_lock ); 192 LIB_DEBUG_DO( assert( validate( &systemProcessor->alarms ) ) ); 166 193 remove( &systemProcessor->alarms, this ); 167 194 unlock( &systemProcessor->alarm_lock ); 168 195 disable_interrupts(); 169 196 this->set = false; 170 } 197 LIB_DEBUG_DO( 198 len = snprintf( text, 256, "Kernel : unregister %p end\n", this ); 199 LIB_DEBUG_WRITE( STDERR_FILENO, text, len ); 200 ); 201 } -
src/libcfa/concurrency/coroutine.c
r70c2df8 r4e6fb8e 32 32 #include "invoke.h" 33 33 34 extern thread_local processor * this_processor;34 extern volatile thread_local processor * this_processor; 35 35 36 36 //----------------------------------------------------------------------------- -
src/libcfa/concurrency/invoke.c
r70c2df8 r4e6fb8e 31 31 extern void __leave_monitor_desc( struct monitor_desc * this ); 32 32 extern void disable_interrupts(); 33 extern void enable_interrupts( );33 extern void enable_interrupts( const char * ); 34 34 35 35 void CtxInvokeCoroutine( … … 69 69 struct monitor_desc* mon = &thrd->mon; 70 70 cor->state = Active; 71 enable_interrupts( );71 enable_interrupts( __PRETTY_FUNCTION__ ); 72 72 73 73 // LIB_DEBUG_PRINTF("Invoke Thread : invoking main %p (args %p)\n", main, this); -
src/libcfa/concurrency/kernel
r70c2df8 r4e6fb8e 90 90 unsigned int preemption; 91 91 92 unsigned short disable_preempt_count;92 bool pending_preemption; 93 93 94 bool pending_preemption;94 char * last_enable; 95 95 }; 96 96 -
src/libcfa/concurrency/kernel.c
r70c2df8 r4e6fb8e 59 59 // Global state 60 60 61 thread_local processor * this_processor; 61 volatile thread_local processor * this_processor; 62 volatile thread_local unsigned short disable_preempt_count; 62 63 63 64 coroutine_desc * this_coroutine(void) { … … 142 143 this->preemption_alarm = NULL; 143 144 this->preemption = default_preemption(); 144 this->disable_preempt_count = 1; //Start with interrupts disabled145 145 this->pending_preemption = false; 146 146 … … 156 156 this->preemption_alarm = NULL; 157 157 this->preemption = default_preemption(); 158 this->disable_preempt_count = 1;159 158 this->pending_preemption = false; 160 159 this->kernel_thread = pthread_self(); … … 164 163 runner{ this }; 165 164 } 165 166 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); ) 166 167 167 168 void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) { … … 171 172 172 173 (&this->proc){ cltr, runner }; 174 175 LIB_DEBUG_DO( assert( validate( &this->alarms ) ) ); 173 176 } 174 177 … … 212 215 if(readyThread) 213 216 { 217 assert( disable_preempt_count > 0 ); 218 214 219 runThread(this, readyThread); 220 221 assert( disable_preempt_count > 0 ); 215 222 216 223 //Some actions need to be taken from the kernel … … 244 251 this->current_thread = dst; 245 252 246 LIB_DEBUG_PRINT_SAFE("Kernel : running %p\n", dst);247 248 253 // Context Switch to the thread 249 254 ThreadCtxSwitch(proc_cor, thrd_cor); … … 294 299 processor * proc = (processor *) arg; 295 300 this_processor = proc; 301 disable_preempt_count = 1; 296 302 // SKULLDUGGERY: We want to create a context for the processor coroutine 297 303 // which is needed for the 2-step context switch. However, there is no reason … … 381 387 void BlockInternal() { 382 388 disable_interrupts(); 389 assert( disable_preempt_count > 0 ); 383 390 suspend(); 384 enable_interrupts(); 391 assert( disable_preempt_count > 0 ); 392 enable_interrupts( __PRETTY_FUNCTION__ ); 385 393 } 386 394 … … 389 397 this_processor->finish.action_code = Release; 390 398 this_processor->finish.lock = lock; 399 assert( disable_preempt_count > 0 ); 391 400 suspend(); 392 enable_interrupts(); 401 assert( disable_preempt_count > 0 ); 402 enable_interrupts( __PRETTY_FUNCTION__ ); 393 403 } 394 404 … … 397 407 this_processor->finish.action_code = Schedule; 398 408 this_processor->finish.thrd = thrd; 409 assert( disable_preempt_count > 0 ); 399 410 suspend(); 400 enable_interrupts(); 411 assert( disable_preempt_count > 0 ); 412 enable_interrupts( __PRETTY_FUNCTION__ ); 401 413 } 402 414 … … 406 418 this_processor->finish.lock = lock; 407 419 this_processor->finish.thrd = thrd; 420 assert( disable_preempt_count > 0 ); 408 421 suspend(); 409 enable_interrupts(); 422 assert( disable_preempt_count > 0 ); 423 enable_interrupts( __PRETTY_FUNCTION__ ); 410 424 } 411 425 … … 415 429 this_processor->finish.locks = locks; 416 430 this_processor->finish.lock_count = count; 431 assert( disable_preempt_count > 0 ); 417 432 suspend(); 418 enable_interrupts(); 433 assert( disable_preempt_count > 0 ); 434 enable_interrupts( __PRETTY_FUNCTION__ ); 419 435 } 420 436 … … 426 442 this_processor->finish.thrds = thrds; 427 443 this_processor->finish.thrd_count = thrd_count; 444 assert( disable_preempt_count > 0 ); 428 445 suspend(); 429 enable_interrupts(); 446 assert( disable_preempt_count > 0 ); 447 enable_interrupts( __PRETTY_FUNCTION__ ); 430 448 } 431 449 … … 466 484 this_processor->current_thread = mainThread; 467 485 this_processor->current_coroutine = &mainThread->cor; 486 disable_preempt_count = 1; 468 487 469 488 // Enable preemption … … 480 499 LIB_DEBUG_PRINT_SAFE("Kernel : Started\n--------------------------------------------------\n\n"); 481 500 482 enable_interrupts( );501 enable_interrupts( __PRETTY_FUNCTION__ ); 483 502 } 484 503 485 504 void kernel_shutdown(void) { 486 505 LIB_DEBUG_PRINT_SAFE("\n--------------------------------------------------\nKernel : Shutting down\n"); 506 507 disable_interrupts(); 487 508 488 509 // SKULLDUGGERY: Notify the systemProcessor it needs to terminates. … … 600 621 append( &this->blocked, this_thread() ); 601 622 BlockInternal( &this->lock ); 602 lock( &this->lock ); 603 } 604 unlock( &this->lock ); 623 } 624 else { 625 unlock( &this->lock ); 626 } 605 627 } 606 628 … … 610 632 this->cond = true; 611 633 634 disable_interrupts(); 612 635 thread_desc * it; 613 636 while( it = pop_head( &this->blocked) ) { 614 637 ScheduleThread( it ); 615 638 } 639 enable_interrupts( __PRETTY_FUNCTION__ ); 616 640 } 617 641 unlock( &this->lock ); -
src/libcfa/concurrency/kernel_private.h
r70c2df8 r4e6fb8e 58 58 extern cluster * systemCluster; 59 59 extern system_proc_t * systemProcessor; 60 extern thread_local processor * this_processor; 60 extern volatile thread_local processor * this_processor; 61 extern volatile thread_local unsigned short disable_preempt_count; 61 62 62 63 extern "C" { 63 64 void disable_interrupts(); 64 65 void enable_interrupts_noRF(); 65 void enable_interrupts( );66 void enable_interrupts( const char * ); 66 67 } 67 68 -
src/libcfa/concurrency/preemption.c
r70c2df8 r4e6fb8e 17 17 #include "preemption.h" 18 18 19 19 20 extern "C" { 20 21 #include <errno.h> 22 #define __USE_GNU 21 23 #include <signal.h> 24 #undef __USE_GNU 22 25 #include <stdio.h> 23 26 #include <string.h> … … 60 63 sigprocmask( SIG_BLOCK, &mask, NULL ); 61 64 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopped\n"); 62 } 65 66 assert( !systemProcessor->alarms.head ); 67 assert( systemProcessor->alarms.tail == &systemProcessor->alarms.head ); 68 } 69 70 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); ) 63 71 64 72 void tick_preemption() { … … 84 92 } 85 93 94 LIB_DEBUG_DO( assert( validate( alarms ) ) ); 95 86 96 if( node->period > 0 ) { 87 97 node->alarm = currtime + node->period; … … 98 108 99 109 LIB_DEBUG_DO( 110 assert( validate( alarms ) ); 100 111 len = snprintf( text, 256, "Ticking preemption done\n" ); 101 112 LIB_DEBUG_WRITE( STDERR_FILENO, text, len ); … … 106 117 LIB_DEBUG_DO( 107 118 char text[256]; 108 __attribute__((unused)) int len = snprintf( text, 256, "Processor : updating preemption to %lu\n", duration );119 __attribute__((unused)) int len = snprintf( text, 256, "Processor : %p updating preemption to %lu\n", this, duration ); 109 120 LIB_DEBUG_WRITE( STDERR_FILENO, text, len ); 110 121 ); … … 139 150 this->proc->preemption_alarm = &this->alarm; 140 151 update_preemption( this->proc, this->proc->preemption ); 141 142 // enable_interrupts();143 152 } 144 153 … … 155 164 extern "C" { 156 165 void disable_interrupts() { 157 __attribute__((unused)) unsigned short prev = __atomic_fetch_add_2( &this_processor->disable_preempt_count, 1, __ATOMIC_SEQ_CST ); 158 assert( prev != (unsigned short) -1 ); 166 __attribute__((unused)) unsigned short new_val = __atomic_add_fetch_2( &disable_preempt_count, 1, __ATOMIC_SEQ_CST ); 167 assert( new_val < (unsigned short)65_000 ); 168 assert( new_val != (unsigned short) 0 ); 159 169 } 160 170 161 171 void enable_interrupts_noRF() { 162 unsigned short prev = __atomic_fetch_add_2( & this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST );172 unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST ); 163 173 assert( prev != (unsigned short) 0 ); 164 174 } 165 175 166 void enable_interrupts( ) {167 unsigned short prev = __atomic_fetch_add_2( & this_processor->disable_preempt_count, -1, __ATOMIC_SEQ_CST );176 void enable_interrupts( const char * func ) { 177 unsigned short prev = __atomic_fetch_add_2( &disable_preempt_count, -1, __ATOMIC_SEQ_CST ); 168 178 assert( prev != (unsigned short) 0 ); 169 179 if( prev == 1 && this_processor->pending_preemption ) { … … 171 181 LIB_DEBUG_DO( 172 182 char text[256]; 173 __attribute__((unused)) int len = snprintf( text, 256, "Executing deferred CtxSwitch \n");183 __attribute__((unused)) int len = snprintf( text, 256, "Executing deferred CtxSwitch on %p\n", this_processor ); 174 184 LIB_DEBUG_WRITE( STDERR_FILENO, text, len ); 175 185 ); 176 186 BlockInternal( this_processor->current_thread ); 177 187 } 188 189 this_processor->last_enable = func; 178 190 } 179 191 } … … 192 204 193 205 static inline bool preemption_ready() { 194 return this_processor->disable_preempt_count == 0;206 return disable_preempt_count == 0; 195 207 } 196 208 … … 207 219 LIB_DEBUG_DO( 208 220 char text[256]; 209 __attribute__((unused)) int len = snprintf( text, 256, "Ctx Switch IRH \n");221 __attribute__((unused)) int len = snprintf( text, 256, "Ctx Switch IRH %p\n", (void *)(cxt->uc_mcontext.gregs[REG_RIP])); 210 222 LIB_DEBUG_WRITE( STDERR_FILENO, text, len ); 211 223 ); … … 214 226 if( preemption_ready() ) { 215 227 LIB_DEBUG_DO( 216 len = snprintf( text, 256, "Ctx Switch IRH : Blocking thread \n");228 len = snprintf( text, 256, "Ctx Switch IRH : Blocking thread %p on %p\n", this_processor->current_thread, this_processor ); 217 229 LIB_DEBUG_WRITE( STDERR_FILENO, text, len ); 218 230 ); … … 232 244 LIB_DEBUG_DO( 233 245 char text[256]; 234 __attribute__((unused)) int len = snprintf( text, 256, "\nAlarm IRH \n");246 __attribute__((unused)) int len = snprintf( text, 256, "\nAlarm IRH %p\n", (void *)(cxt->uc_mcontext.gregs[REG_RIP]) ); 235 247 LIB_DEBUG_WRITE( STDERR_FILENO, text, len ); 236 248 ); -
src/libcfa/concurrency/thread.c
r70c2df8 r4e6fb8e 28 28 } 29 29 30 extern thread_local processor * this_processor;30 extern volatile thread_local processor * this_processor; 31 31 32 32 //-----------------------------------------------------------------------------
Note: See TracChangeset
for help on using the changeset viewer.