Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/preemption.cfa

    rd3ab183 rc84b4be  
    3939// FwdDeclarations : timeout handlers
    4040static void preempt( processor   * this );
    41 static void timeout( $thread * this );
     41static void timeout( thread_desc * this );
    4242
    4343// FwdDeclarations : Signal handlers
    4444static void sigHandler_ctxSwitch( __CFA_SIGPARMS__ );
    45 static void sigHandler_alarm    ( __CFA_SIGPARMS__ );
    4645static void sigHandler_segv     ( __CFA_SIGPARMS__ );
    4746static void sigHandler_ill      ( __CFA_SIGPARMS__ );
     
    8483// Get next expired node
    8584static inline alarm_node_t * get_expired( alarm_list_t * alarms, Time currtime ) {
    86         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
     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
    8887        return pop(alarms);                                                                     // Otherwise just pop head
    8988}
     
    9897        while( node = get_expired( alarms, currtime ) ) {
    9998                // __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                 }
    10499
    105100                // Check if this is a kernel
     
    112107
    113108                // Check if this is a periodic alarm
     109                Duration period = node->period;
    114110                if( period > 0 ) {
    115111                        // __cfaabi_dbg_print_buffer_local( " KERNEL: alarm period is %lu.\n", period.tv );
     
    117113                        insert( alarms, node );             // Reinsert the node for the next time it triggers
    118114                }
     115                else {
     116                        node->set = false;                  // Node is one-shot, just mark it as not pending
     117                }
    119118        }
    120119
    121120        // 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 capped = 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);
    126125                // itimerval tim  = { caped };
    127126                // __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);
    128127
    129                 __kernel_set_timer( capped );
     128                __kernel_set_timer( caped );
    130129        }
    131130}
     
    185184
    186185        // Enable interrupts by decrementing the counter
    187         // If counter reaches 0, execute any pending __cfactx_switch
     186        // If counter reaches 0, execute any pending CtxSwitch
    188187        void enable_interrupts( __cfaabi_dbg_ctx_param ) {
    189188                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
    190190
    191191                with( kernelTLS.preemption_state ){
     
    209209                                if( proc->pending_preemption ) {
    210210                                        proc->pending_preemption = false;
    211                                         force_yield( __POLL_PREEMPTION );
     211                                        BlockInternal( thrd );
    212212                                }
    213213                        }
     
    219219
    220220        // Disable interrupts by incrementint the counter
    221         // Don't execute any pending __cfactx_switch even if counter reaches 0
     221        // Don't execute any pending CtxSwitch even if counter reaches 0
    222222        void enable_interrupts_noPoll() {
    223223                unsigned short prev = kernelTLS.preemption_state.disable_count;
     
    257257
    258258        if ( pthread_sigmask( SIG_BLOCK, &mask, 0p ) == -1 ) {
    259                 abort( "internal error, pthread_sigmask" );
     259            abort( "internal error, pthread_sigmask" );
    260260        }
    261261}
     
    268268
    269269// reserved for future use
    270 static void timeout( $thread * this ) {
    271         __unpark( this __cfaabi_dbg_ctx2 );
     270static void timeout( thread_desc * this ) {
     271        //TODO : implement waking threads
    272272}
    273273
    274274// KERNEL ONLY
    275 // Check if a __cfactx_switch signal handler shoud defer
     275// Check if a CtxSwitch signal handler shoud defer
    276276// If true  : preemption is safe
    277277// If false : preemption is unsafe and marked as pending
     
    303303
    304304        // 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
    307306
    308307        signal_block( SIGALRM );
    309308
    310         alarm_stack = __create_pthread( &alarm_thread, alarm_loop, 0p );
     309        alarm_stack = create_pthread( &alarm_thread, alarm_loop, 0p );
    311310}
    312311
     
    395394        // Preemption can occur here
    396395
    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
    402397}
    403398
Note: See TracChangeset for help on using the changeset viewer.