Ignore:
File:
1 edited

Legend:

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

    rc457dc41 ra3821fa  
    1818
    1919#include "preemption.hfa"
    20 
    2120#include <assert.h>
    2221
     
    2726#include <limits.h>                                                                             // PTHREAD_STACK_MIN
    2827
    29 #include "bits/debug.hfa"
    3028#include "bits/signal.hfa"
    3129#include "kernel_private.hfa"
     
    107105static inline alarm_node_t * get_expired( alarm_list_t * alarms, Time currtime ) {
    108106        if( ! & (*alarms)`first ) return 0p;                                            // If no alarms return null
    109         if( (*alarms)`first.timeval >= currtime ) return 0p;    // If alarms head not expired return null
     107        if( (*alarms)`first.alarm >= currtime ) return 0p;      // If alarms head not expired return null
    110108        return pop(alarms);                                                                     // Otherwise just pop head
    111109}
     
    143141                if( period > 0 ) {
    144142                        __cfadbg_print_buffer_local( preemption, " KERNEL: alarm period is %lu.\n", period`ns );
    145                         node->timeval = currtime + period;  // Alarm is periodic, add currtime to it (used cached current time)
     143                        node->alarm = currtime + period;    // Alarm is periodic, add currtime to it (used cached current time)
    146144                        insert( alarms, node );             // Reinsert the node for the next time it triggers
    147145                }
     
    150148        // If there are still alarms pending, reset the timer
    151149        if( & (*alarms)`first ) {
    152                 Duration delta = (*alarms)`first.timeval - currtime;
    153                 __kernel_set_timer( delta );
     150                Duration delta = (*alarms)`first.alarm - currtime;
     151                Duration capped = max(delta, 50`us);
     152                __kernel_set_timer( capped );
    154153        }
    155154}
     
    161160        // Alarms need to be enabled
    162161        if ( duration > 0 && ! alarm->set ) {
    163                 alarm->initial = duration;
    164                 alarm->period  = duration;
     162                alarm->alarm = __kernel_get_time() + duration;
     163                alarm->period = duration;
    165164                register_self( alarm );
    166165        }
     
    168167        else if ( duration == 0 && alarm->set ) {
    169168                unregister_self( alarm );
    170                 alarm->initial = 0;
    171                 alarm->period  = 0;
     169                alarm->alarm = 0;
     170                alarm->period = 0;
    172171        }
    173172        // If alarm is different from previous, change it
    174173        else if ( duration > 0 && alarm->period != duration ) {
    175174                unregister_self( alarm );
    176                 alarm->initial = duration;
    177                 alarm->period  = duration;
     175                alarm->alarm = __kernel_get_time() + duration;
     176                alarm->period = duration;
    178177                register_self( alarm );
    179178        }
     
    600599
    601600        // Notify the alarm thread of the shutdown
    602         sigval val;
    603         val.sival_int = 0;
     601        sigval val = { 1 };
    604602        pthread_sigqueue( alarm_thread, SIGALRM, val );
    605603
     
    621619// Used by thread to control when they want to receive preemption signals
    622620void ?{}( preemption_scope & this, processor * proc ) {
    623         (this.alarm){ proc, 0`s, 0`s };
     621        (this.alarm){ proc, (Time){ 0 }, 0`s };
    624622        this.proc = proc;
    625623        this.proc->preemption_alarm = &this.alarm;
     
    689687// Waits on SIGALRM and send SIGUSR1 to whom ever needs it
    690688static void * alarm_loop( __attribute__((unused)) void * args ) {
    691         unsigned id = register_proc_id();
     689        __processor_id_t id;
     690        register_proc_id(&id);
     691        __cfaabi_tls.this_proc_id = &id;
     692
    692693
    693694        // Block sigalrms to control when they arrive
     
    706707                siginfo_t info;
    707708                int sig = sigwaitinfo( &mask, &info );
    708 
    709                 __cfadbg_print_buffer_decl ( preemption, " KERNEL: sigwaitinfo returned %d, c: %d, v: %d\n", sig, info.si_code, info.si_value.sival_int );
    710                 __cfadbg_print_buffer_local( preemption, " KERNEL: SI_QUEUE %d, SI_TIMER %d, SI_KERNEL %d\n", SI_QUEUE, SI_TIMER, SI_KERNEL );
    711709
    712710                if( sig < 0 ) {
     
    716714                                case EAGAIN :
    717715                                case EINTR :
    718                                         {__cfadbg_print_buffer_local( preemption, " KERNEL: Spurious wakeup %d.\n", err );}
     716                                        {__cfaabi_dbg_print_buffer_decl( " KERNEL: Spurious wakeup %d.\n", err );}
    719717                                        continue;
    720718                                case EINVAL :
     
    728726                assertf(sig == SIGALRM, "Kernel Internal Error, sigwait: Unexpected signal %d (%d : %d)\n", sig, info.si_code, info.si_value.sival_int);
    729727
     728                // __cfaabi_dbg_print_safe( "Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int );
    730729                // Switch on the code (a.k.a. the sender) to
    731730                switch( info.si_code )
    732731                {
    733                 // Signal was not sent by the kernel but by an other thread
    734                 case SI_QUEUE:
    735                         // other threads may signal the alarm thread to shut it down
    736                         // or to manual cause the preemption tick
    737                         // use info.si_value and handle the case here
    738                         switch( info.si_value.sival_int ) {
    739                         case 0:
    740                                 goto EXIT;
    741                         default:
    742                                 abort( "SI_QUEUE with val %d", info.si_value.sival_int);
    743                         }
    744                         // fallthrough
    745732                // Timers can apparently be marked as sent for the kernel
    746733                // In either case, tick preemption
     
    752739                        unlock( event_kernel->lock );
    753740                        break;
     741                // Signal was not sent by the kernel but by an other thread
     742                case SI_QUEUE:
     743                        // For now, other thread only signal the alarm thread to shut it down
     744                        // If this needs to change use info.si_value and handle the case here
     745                        goto EXIT;
    754746                }
    755747        }
     
    757749EXIT:
    758750        __cfaabi_dbg_print_safe( "Kernel : Preemption thread stopping\n" );
    759         unregister_proc_id(id);
     751        register_proc_id(&id);
    760752
    761753        return 0p;
Note: See TracChangeset for help on using the changeset viewer.