- File:
-
- 1 edited
-
libcfa/src/concurrency/preemption.cfa (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/preemption.cfa
rc84b4be rd3ab183 39 39 // FwdDeclarations : timeout handlers 40 40 static void preempt( processor * this ); 41 static void timeout( thread_desc* this );41 static void timeout( $thread * this ); 42 42 43 43 // FwdDeclarations : Signal handlers 44 44 static void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ); 45 static void sigHandler_alarm ( __CFA_SIGPARMS__ ); 45 46 static void sigHandler_segv ( __CFA_SIGPARMS__ ); 46 47 static void sigHandler_ill ( __CFA_SIGPARMS__ ); … … 83 84 // Get next expired node 84 85 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 null86 if( ! & (*alarms)`first ) return 0p; // If no alarms return null 87 if( (*alarms)`first.alarm >= currtime ) return 0p; // If alarms head not expired return null 87 88 return pop(alarms); // Otherwise just pop head 88 89 } … … 97 98 while( node = get_expired( alarms, currtime ) ) { 98 99 // __cfaabi_dbg_print_buffer_decl( " KERNEL: preemption tick.\n" ); 100 Duration period = node->period; 101 if( period == 0) { 102 node->set = false; // Node is one-shot, just mark it as not pending 103 } 99 104 100 105 // Check if this is a kernel … … 107 112 108 113 // Check if this is a periodic alarm 109 Duration period = node->period;110 114 if( period > 0 ) { 111 115 // __cfaabi_dbg_print_buffer_local( " KERNEL: alarm period is %lu.\n", period.tv ); … … 113 117 insert( alarms, node ); // Reinsert the node for the next time it triggers 114 118 } 115 else {116 node->set = false; // Node is one-shot, just mark it as not pending117 }118 119 } 119 120 120 121 // If there are still alarms pending, reset the timer 121 if( alarms->head) {122 //__cfaabi_dbg_print_buffer_decl( " KERNEL: @%ju(%ju) resetting alarm to %ju.\n", currtime.tv, __kernel_get_time().tv, (alarms->head->alarm - currtime).tv);123 Duration delta = alarms->head->alarm - currtime;124 Duration cap ed = max(delta, 50`us);122 if( & (*alarms)`first ) { 123 __cfaabi_dbg_print_buffer_decl( " KERNEL: @%ju(%ju) resetting alarm to %ju.\n", currtime.tv, __kernel_get_time().tv, (alarms->head->alarm - currtime).tv); 124 Duration delta = (*alarms)`first.alarm - currtime; 125 Duration capped = max(delta, 50`us); 125 126 // itimerval tim = { caped }; 126 127 // __cfaabi_dbg_print_buffer_local( " Values are %lu, %lu, %lu %lu.\n", delta.tv, caped.tv, tim.it_value.tv_sec, tim.it_value.tv_usec); 127 128 128 __kernel_set_timer( cap ed );129 __kernel_set_timer( capped ); 129 130 } 130 131 } … … 184 185 185 186 // Enable interrupts by decrementing the counter 186 // If counter reaches 0, execute any pending CtxSwitch187 // If counter reaches 0, execute any pending __cfactx_switch 187 188 void enable_interrupts( __cfaabi_dbg_ctx_param ) { 188 189 processor * proc = kernelTLS.this_processor; // Cache the processor now since interrupts can start happening after the atomic store 189 thread_desc * thrd = kernelTLS.this_thread; // Cache the thread now since interrupts can start happening after the atomic store190 190 191 191 with( kernelTLS.preemption_state ){ … … 209 209 if( proc->pending_preemption ) { 210 210 proc->pending_preemption = false; 211 BlockInternal( thrd);211 force_yield( __POLL_PREEMPTION ); 212 212 } 213 213 } … … 219 219 220 220 // Disable interrupts by incrementint the counter 221 // Don't execute any pending CtxSwitch even if counter reaches 0221 // Don't execute any pending __cfactx_switch even if counter reaches 0 222 222 void enable_interrupts_noPoll() { 223 223 unsigned short prev = kernelTLS.preemption_state.disable_count; … … 257 257 258 258 if ( pthread_sigmask( SIG_BLOCK, &mask, 0p ) == -1 ) { 259 abort( "internal error, pthread_sigmask" );259 abort( "internal error, pthread_sigmask" ); 260 260 } 261 261 } … … 268 268 269 269 // reserved for future use 270 static void timeout( thread_desc* this ) {271 //TODO : implement waking threads270 static void timeout( $thread * this ) { 271 __unpark( this __cfaabi_dbg_ctx2 ); 272 272 } 273 273 274 274 // KERNEL ONLY 275 // Check if a CtxSwitch signal handler shoud defer275 // Check if a __cfactx_switch signal handler shoud defer 276 276 // If true : preemption is safe 277 277 // If false : preemption is unsafe and marked as pending … … 303 303 304 304 // Setup proper signal handlers 305 __cfaabi_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO | SA_RESTART ); // CtxSwitch handler 305 __cfaabi_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO | SA_RESTART ); // __cfactx_switch handler 306 __cfaabi_sigaction( SIGALRM, sigHandler_alarm , SA_SIGINFO | SA_RESTART ); // debug handler 306 307 307 308 signal_block( SIGALRM ); 308 309 309 alarm_stack = create_pthread( &alarm_thread, alarm_loop, 0p );310 alarm_stack = __create_pthread( &alarm_thread, alarm_loop, 0p ); 310 311 } 311 312 … … 394 395 // Preemption can occur here 395 396 396 BlockInternal( kernelTLS.this_thread ); // Do the actual CtxSwitch 397 force_yield( __ALARM_PREEMPTION ); // Do the actual __cfactx_switch 398 } 399 400 static void sigHandler_alarm( __CFA_SIGPARMS__ ) { 401 abort("SIGALRM should never reach the signal handler"); 397 402 } 398 403
Note:
See TracChangeset
for help on using the changeset viewer.