- File:
-
- 1 edited
-
libcfa/src/concurrency/preemption.cfa (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/preemption.cfa
rd3ab183 rc84b4be 39 39 // FwdDeclarations : timeout handlers 40 40 static void preempt( processor * this ); 41 static void timeout( $thread* this );41 static void timeout( thread_desc * this ); 42 42 43 43 // FwdDeclarations : Signal handlers 44 44 static void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ); 45 static void sigHandler_alarm ( __CFA_SIGPARMS__ );46 45 static void sigHandler_segv ( __CFA_SIGPARMS__ ); 47 46 static void sigHandler_ill ( __CFA_SIGPARMS__ ); … … 84 83 // Get next expired node 85 84 static inline alarm_node_t * get_expired( alarm_list_t * alarms, Time currtime ) { 86 if( ! & (*alarms)`first) return 0p; // If no alarms return null87 if( (*alarms)`first.alarm >= currtime ) return 0p; // If alarms head not expired return null85 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 88 87 return pop(alarms); // Otherwise just pop head 89 88 } … … 98 97 while( node = get_expired( alarms, currtime ) ) { 99 98 // __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 pending103 }104 99 105 100 // Check if this is a kernel … … 112 107 113 108 // Check if this is a periodic alarm 109 Duration period = node->period; 114 110 if( period > 0 ) { 115 111 // __cfaabi_dbg_print_buffer_local( " KERNEL: alarm period is %lu.\n", period.tv ); … … 117 113 insert( alarms, node ); // Reinsert the node for the next time it triggers 118 114 } 115 else { 116 node->set = false; // Node is one-shot, just mark it as not pending 117 } 119 118 } 120 119 121 120 // If there are still alarms pending, reset the timer 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 cap ped = max(delta, 50`us);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 caped = max(delta, 50`us); 126 125 // itimerval tim = { caped }; 127 126 // __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); 128 127 129 __kernel_set_timer( cap ped );128 __kernel_set_timer( caped ); 130 129 } 131 130 } … … 185 184 186 185 // Enable interrupts by decrementing the counter 187 // If counter reaches 0, execute any pending __cfactx_switch186 // If counter reaches 0, execute any pending CtxSwitch 188 187 void enable_interrupts( __cfaabi_dbg_ctx_param ) { 189 188 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 store 190 190 191 191 with( kernelTLS.preemption_state ){ … … 209 209 if( proc->pending_preemption ) { 210 210 proc->pending_preemption = false; 211 force_yield( __POLL_PREEMPTION);211 BlockInternal( thrd ); 212 212 } 213 213 } … … 219 219 220 220 // Disable interrupts by incrementint the counter 221 // Don't execute any pending __cfactx_switch even if counter reaches 0221 // Don't execute any pending CtxSwitch 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* this ) {271 __unpark( this __cfaabi_dbg_ctx2 );270 static void timeout( thread_desc * this ) { 271 //TODO : implement waking threads 272 272 } 273 273 274 274 // KERNEL ONLY 275 // Check if a __cfactx_switch signal handler shoud defer275 // Check if a CtxSwitch 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 ); // __cfactx_switch handler 306 __cfaabi_sigaction( SIGALRM, sigHandler_alarm , SA_SIGINFO | SA_RESTART ); // debug handler 305 __cfaabi_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO | SA_RESTART ); // CtxSwitch handler 307 306 308 307 signal_block( SIGALRM ); 309 308 310 alarm_stack = __create_pthread( &alarm_thread, alarm_loop, 0p );309 alarm_stack = create_pthread( &alarm_thread, alarm_loop, 0p ); 311 310 } 312 311 … … 395 394 // Preemption can occur here 396 395 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"); 396 BlockInternal( kernelTLS.this_thread ); // Do the actual CtxSwitch 402 397 } 403 398
Note:
See TracChangeset
for help on using the changeset viewer.