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