Changeset cd17862
- Timestamp:
- Jul 4, 2017, 4:48:46 PM (6 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, 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:
- 11dbfe1
- Parents:
- 47ecf2b
- Location:
- src/libcfa/concurrency
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/kernel.c
r47ecf2b rcd17862 324 324 LIB_DEBUG_PRINT_SAFE("Kernel : Starting core %p\n", this); 325 325 326 // SIGALRM must only be caught by the system processor327 sigset_t old_mask;328 bool is_system_proc = this_processor == &systemProcessor->proc;329 if ( is_system_proc ) {330 // Child kernel-thread inherits the signal mask from the parent kernel-thread. So one special case for the331 // system processor creating the user processor => toggle the blocking SIGALRM on system processor, create user332 // processor, and toggle back (below) previous signal mask of the system processor.333 334 sigset_t new_mask;335 sigemptyset( &new_mask );336 sigemptyset( &old_mask );337 sigaddset( &new_mask, SIGALRM );338 339 if ( pthread_sigmask( SIG_BLOCK, &new_mask, &old_mask ) == -1 ) {340 abortf( "internal error, pthread_sigmask" );341 }342 343 assert( ! sigismember( &old_mask, SIGALRM ) );344 }345 346 326 pthread_create( &this->kernel_thread, NULL, CtxInvokeProcessor, (void*)this ); 347 348 // Toggle back previous signal mask of system processor.349 if ( is_system_proc ) {350 if ( pthread_sigmask( SIG_SETMASK, &old_mask, NULL ) == -1 ) {351 abortf( "internal error, pthread_sigmask" );352 } // if353 } // if354 327 355 328 LIB_DEBUG_PRINT_SAFE("Kernel : core %p started\n", this); -
src/libcfa/concurrency/preemption.c
r47ecf2b rcd17862 52 52 53 53 static void __kernel_sigaction( int sig, void (*handler)(__CFA_SIGPARMS__), int flags ); 54 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); ) 55 56 #ifdef __x86_64__ 57 #define CFA_REG_IP REG_RIP 58 #else 59 #define CFA_REG_IP REG_EIP 60 #endif 61 54 62 55 63 //============================================================================================= 56 64 // Kernel Preemption logic 57 65 //============================================================================================= 58 59 void kernel_start_preemption() {60 LIB_DEBUG_PRINT_SAFE("Kernel : Starting preemption\n");61 __kernel_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO );62 __kernel_sigaction( SIGALRM, sigHandler_alarm , SA_SIGINFO );63 __kernel_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO );64 __kernel_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO );65 // __kernel_sigaction( SIGABRT, sigHandler_abort , SA_SIGINFO );66 }67 68 void kernel_stop_preemption() {69 //Block all signals, we are no longer in a position to handle them70 sigset_t mask;71 sigfillset( &mask );72 sigprocmask( SIG_BLOCK, &mask, NULL );73 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopped\n");74 75 // assert( !systemProcessor->alarms.head );76 // assert( systemProcessor->alarms.tail == &systemProcessor->alarms.head );77 }78 79 LIB_DEBUG_DO( bool validate( alarm_list_t * this ); )80 66 81 67 void tick_preemption() { … … 141 127 } 142 128 143 void ?{}( preemption_scope * this, processor * proc ) { 144 (&this->alarm){ proc }; 145 this->proc = proc; 146 this->proc->preemption_alarm = &this->alarm; 147 update_preemption( this->proc, this->proc->preemption ); 148 } 149 150 void ^?{}( preemption_scope * this ) { 151 disable_interrupts(); 152 153 update_preemption( this->proc, 0 ); 154 } 155 156 //============================================================================================= 157 // Kernel Signal logic 129 //============================================================================================= 130 // Kernel Signal Tools 158 131 //============================================================================================= 159 132 … … 187 160 188 161 static inline void signal_unblock( int sig ) { 189 LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Unblock %d on %p\n", sig, this_processor );190 191 162 sigset_t mask; 192 163 sigemptyset( &mask ); … … 195 166 if ( pthread_sigmask( SIG_UNBLOCK, &mask, NULL ) == -1 ) { 196 167 abortf( "internal error, pthread_sigmask" ); 197 } // if198 } 199 200 //static inline void signal_block( int sig ) {201 //sigset_t mask;202 //sigemptyset( &mask );203 //sigaddset( &mask, sig );204 205 //if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) {206 //abortf( "internal error, pthread_sigmask" );207 // } // if 208 //}168 } 169 } 170 171 static inline void signal_block( int sig ) { 172 sigset_t mask; 173 sigemptyset( &mask ); 174 sigaddset( &mask, sig ); 175 176 if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) { 177 abortf( "internal error, pthread_sigmask" ); 178 } 179 } 209 180 210 181 static inline bool preemption_ready() { … … 220 191 } 221 192 222 extern "C" { 223 __attribute__((noinline)) void __debug_break() { 224 pthread_kill( pthread_self(), SIGTRAP ); 225 } 226 } 227 228 #ifdef __x86_64__ 229 #define CFA_REG_IP REG_RIP 230 #else 231 #define CFA_REG_IP REG_EIP 232 #endif 193 static void preempt( processor * this ) { 194 pthread_kill( this->kernel_thread, SIGUSR1 ); 195 } 196 197 static void timeout( thread_desc * this ) { 198 //TODO : implement waking threads 199 } 200 201 //============================================================================================= 202 // Kernel Signal Startup/Shutdown logic 203 //============================================================================================= 204 205 static pthread_t alarm_thread; 206 void * alarm_loop( __attribute__((unused)) void * args ); 207 208 void kernel_start_preemption() { 209 LIB_DEBUG_PRINT_SAFE("Kernel : Starting preemption\n"); 210 __kernel_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO ); 211 __kernel_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO ); 212 __kernel_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO ); 213 214 signal_block( SIGALRM ); 215 216 pthread_create( &alarm_thread, NULL, alarm_loop, NULL ); 217 } 218 219 void kernel_stop_preemption() { 220 sigset_t mask; 221 sigfillset( &mask ); 222 sigprocmask( SIG_BLOCK, &mask, NULL ); 223 224 pthread_kill( alarm_thread, SIGINT ); 225 pthread_join( alarm_thread, NULL ); 226 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption stopped\n"); 227 } 228 229 void ?{}( preemption_scope * this, processor * proc ) { 230 (&this->alarm){ proc }; 231 this->proc = proc; 232 this->proc->preemption_alarm = &this->alarm; 233 update_preemption( this->proc, this->proc->preemption ); 234 } 235 236 void ^?{}( preemption_scope * this ) { 237 disable_interrupts(); 238 239 update_preemption( this->proc, 0 ); 240 } 241 242 //============================================================================================= 243 // Kernel Signal Handlers 244 //============================================================================================= 233 245 234 246 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) { 235 247 LIB_DEBUG_DO( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); ) 236 verify( this_processor != systemProcessor );237 238 248 if( preemption_ready() ) { 239 249 signal_unblock( SIGUSR1 ); … … 245 255 } 246 256 247 void sigHandler_alarm( __CFA_SIGPARMS__ ) { 248 LIB_DEBUG_DO( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); ) 249 verify( this_processor == systemProcessor ); 250 251 if( try_lock( &systemProcessor->alarm_lock DEBUG_CTX2 ) ) { 252 tick_preemption(); 253 systemProcessor->pending_alarm = false; 254 unlock( &systemProcessor->alarm_lock ); 255 } 256 else { 257 defer_alarm(); 258 } 259 260 signal_unblock( SIGALRM ); 261 262 if( preemption_ready() && this_processor->pending_preemption ) { 263 264 this_processor->pending_preemption = false; 265 BlockInternal( (thread_desc*)this_thread ); 266 } 267 } 268 269 static void preempt( processor * this ) { 270 if( this != systemProcessor ) { 271 pthread_kill( this->kernel_thread, SIGUSR1 ); 272 } 273 else { 274 defer_ctxSwitch(); 275 } 276 } 277 278 static void timeout( thread_desc * this ) { 279 //TODO : implement waking threads 257 // void sigHandler_alarm( __CFA_SIGPARMS__ ) { 258 // LIB_DEBUG_DO( last_interrupt = (void *)(cxt->uc_mcontext.gregs[CFA_REG_IP]); ) 259 // verify( this_processor == systemProcessor ); 260 261 // if( try_lock( &systemProcessor->alarm_lock DEBUG_CTX2 ) ) { 262 // tick_preemption(); 263 // systemProcessor->pending_alarm = false; 264 // unlock( &systemProcessor->alarm_lock ); 265 // } 266 // else { 267 // defer_alarm(); 268 // } 269 270 // signal_unblock( SIGALRM ); 271 272 // if( preemption_ready() && this_processor->pending_preemption ) { 273 274 // this_processor->pending_preemption = false; 275 // BlockInternal( (thread_desc*)this_thread ); 276 // } 277 // } 278 279 void * alarm_loop( __attribute__((unused)) void * args ) { 280 sigset_t mask; 281 sigemptyset( &mask ); 282 sigaddset( &mask, SIGALRM ); 283 sigaddset( &mask, SIGUSR2 ); 284 sigaddset( &mask, SIGINT ); 285 286 if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) { 287 abortf( "internal error, pthread_sigmask" ); 288 } 289 290 while( true ) { 291 int sig; 292 if( sigwait( &mask, &sig ) != 0 ) { 293 abortf( "internal error, sigwait" ); 294 } 295 296 switch( sig) { 297 case SIGALRM: 298 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n"); 299 lock( &systemProcessor->alarm_lock DEBUG_CTX2 ); 300 tick_preemption(); 301 unlock( &systemProcessor->alarm_lock ); 302 break; 303 case SIGUSR2: 304 //TODO other actions 305 break; 306 case SIGINT: 307 LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread stopping\n"); 308 return NULL; 309 default: 310 abortf( "internal error, sigwait returned sig %d", sig ); 311 break; 312 } 313 } 280 314 } 281 315
Note: See TracChangeset
for help on using the changeset viewer.