- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/preemption.cfa
r2026bb6 rac2b598 10 10 // Created On : Mon Jun 5 14:20:42 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T ue Jun 5 17:35:49 201813 // Update Count : 3712 // Last Modified On : Thu Dec 5 16:34:05 2019 13 // Update Count : 43 14 14 // 15 15 … … 24 24 #include <string.h> 25 25 #include <unistd.h> 26 #include <limits.h> // PTHREAD_STACK_MIN 26 27 } 27 28 … … 38 39 // FwdDeclarations : timeout handlers 39 40 static void preempt( processor * this ); 40 static void timeout( thread_desc* this );41 static void timeout( $thread * this ); 41 42 42 43 // FwdDeclarations : Signal handlers … … 64 65 event_kernel_t * event_kernel; // kernel public handle to even kernel 65 66 static pthread_t alarm_thread; // pthread handle to alarm thread 67 static void * alarm_stack; // pthread stack for alarm thread 66 68 67 69 static void ?{}(event_kernel_t & this) with( this ) { … … 81 83 // Get next expired node 82 84 static inline alarm_node_t * get_expired( alarm_list_t * alarms, Time currtime ) { 83 if( !alarms->head ) return NULL;// If no alarms return null84 if( alarms->head->alarm >= currtime ) return NULL;// If alarms head not expired return null85 return pop(alarms); 85 if( !alarms->head ) return 0p; // If no alarms return null 86 if( alarms->head->alarm >= currtime ) return 0p; // If alarms head not expired return null 87 return pop(alarms); // Otherwise just pop head 86 88 } 87 89 88 90 // Tick one frame of the Discrete Event Simulation for alarms 89 91 static void tick_preemption() { 90 alarm_node_t * node = NULL;// Used in the while loop but cannot be declared in the while condition91 alarm_list_t * alarms = &event_kernel->alarms; 92 Time currtime = __kernel_get_time(); // Check current time once so weeverything "happens at once"92 alarm_node_t * node = 0p; // Used in the while loop but cannot be declared in the while condition 93 alarm_list_t * alarms = &event_kernel->alarms; // Local copy for ease of reading 94 Time currtime = __kernel_get_time(); // Check current time once so everything "happens at once" 93 95 94 96 //Loop throught every thing expired … … 182 184 183 185 // Enable interrupts by decrementing the counter 184 // If counter reaches 0, execute any pending CtxSwitch186 // If counter reaches 0, execute any pending __cfactx_switch 185 187 void enable_interrupts( __cfaabi_dbg_ctx_param ) { 186 188 processor * proc = kernelTLS.this_processor; // Cache the processor now since interrupts can start happening after the atomic store 187 thread_desc * thrd = kernelTLS.this_thread; // Cache the thread now since interrupts can start happening after the atomic store188 189 189 190 with( kernelTLS.preemption_state ){ … … 207 208 if( proc->pending_preemption ) { 208 209 proc->pending_preemption = false; 209 BlockInternal( thrd);210 force_yield( __POLL_PREEMPTION ); 210 211 } 211 212 } … … 217 218 218 219 // Disable interrupts by incrementint the counter 219 // Don't execute any pending CtxSwitch even if counter reaches 0220 // Don't execute any pending __cfactx_switch even if counter reaches 0 220 221 void enable_interrupts_noPoll() { 221 222 unsigned short prev = kernelTLS.preemption_state.disable_count; … … 243 244 sigaddset( &mask, sig ); 244 245 245 if ( pthread_sigmask( SIG_UNBLOCK, &mask, NULL) == -1 ) {246 if ( pthread_sigmask( SIG_UNBLOCK, &mask, 0p ) == -1 ) { 246 247 abort( "internal error, pthread_sigmask" ); 247 248 } … … 254 255 sigaddset( &mask, sig ); 255 256 256 if ( pthread_sigmask( SIG_BLOCK, &mask, NULL) == -1 ) {257 if ( pthread_sigmask( SIG_BLOCK, &mask, 0p ) == -1 ) { 257 258 abort( "internal error, pthread_sigmask" ); 258 259 } … … 266 267 267 268 // reserved for future use 268 static void timeout( thread_desc* this ) {269 static void timeout( $thread * this ) { 269 270 //TODO : implement waking threads 270 271 } 271 272 272 273 // KERNEL ONLY 273 // Check if a CtxSwitch signal handler shoud defer274 // Check if a __cfactx_switch signal handler shoud defer 274 275 // If true : preemption is safe 275 276 // If false : preemption is unsafe and marked as pending … … 301 302 302 303 // Setup proper signal handlers 303 __cfaabi_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO | SA_RESTART ); // CtxSwitch handler304 __cfaabi_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO | SA_RESTART ); // __cfactx_switch handler 304 305 305 306 signal_block( SIGALRM ); 306 307 307 pthread_create( &alarm_thread, NULL, alarm_loop, NULL);308 alarm_stack = __create_pthread( &alarm_thread, alarm_loop, 0p ); 308 309 } 309 310 … … 316 317 sigset_t mask; 317 318 sigfillset( &mask ); 318 sigprocmask( SIG_BLOCK, &mask, NULL);319 sigprocmask( SIG_BLOCK, &mask, 0p ); 319 320 320 321 // Notify the alarm thread of the shutdown … … 323 324 324 325 // Wait for the preemption thread to finish 325 pthread_join( alarm_thread, NULL ); 326 327 pthread_join( alarm_thread, 0p ); 328 free( alarm_stack ); 326 329 327 330 // Preemption is now fully stopped … … 380 383 static_assert( sizeof( sigset_t ) == sizeof( cxt->uc_sigmask ), "Expected cxt->uc_sigmask to be of sigset_t" ); 381 384 #endif 382 if ( pthread_sigmask( SIG_SETMASK, (sigset_t *)&(cxt->uc_sigmask), NULL) == -1 ) {385 if ( pthread_sigmask( SIG_SETMASK, (sigset_t *)&(cxt->uc_sigmask), 0p ) == -1 ) { 383 386 abort( "internal error, sigprocmask" ); 384 387 } … … 390 393 // Preemption can occur here 391 394 392 BlockInternal( kernelTLS.this_thread ); // Do the actual CtxSwitch395 force_yield( __ALARM_PREEMPTION ); // Do the actual __cfactx_switch 393 396 } 394 397 … … 399 402 sigset_t mask; 400 403 sigfillset(&mask); 401 if ( pthread_sigmask( SIG_BLOCK, &mask, NULL) == -1 ) {404 if ( pthread_sigmask( SIG_BLOCK, &mask, 0p ) == -1 ) { 402 405 abort( "internal error, pthread_sigmask" ); 403 406 } … … 420 423 {__cfaabi_dbg_print_buffer_decl( " KERNEL: Spurious wakeup %d.\n", err );} 421 424 continue; 422 425 case EINVAL : 423 426 abort( "Timeout was invalid." ); 424 427 default: … … 453 456 EXIT: 454 457 __cfaabi_dbg_print_safe( "Kernel : Preemption thread stopping\n" ); 455 return NULL;458 return 0p; 456 459 } 457 460 … … 466 469 sigset_t oldset; 467 470 int ret; 468 ret = pthread_sigmask(0, NULL, &oldset);471 ret = pthread_sigmask(0, 0p, &oldset); 469 472 if(ret != 0) { abort("ERROR sigprocmask returned %d", ret); } 470 473
Note:
See TracChangeset
for help on using the changeset viewer.