Ignore:
File:
1 edited

Legend:

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

    r13073be rade5272  
    1515
    1616#include "preemption.h"
    17 #include <assert.h>
    1817
    1918extern "C" {
     
    9291        //Loop throught every thing expired
    9392        while( node = get_expired( alarms, currtime ) ) {
    94                 // __cfaabi_dbg_print_buffer_decl( " KERNEL: preemption tick.\n" );
    9593
    9694                // Check if this is a kernel
     
    105103                Duration period = node->period;
    106104                if( period > 0 ) {
    107                         // __cfaabi_dbg_print_buffer_local( " KERNEL: alarm period is %lu.\n", period.tv );
    108105                        node->alarm = currtime + period;    // Alarm is periodic, add currtime to it (used cached current time)
    109106                        insert( alarms, node );             // Reinsert the node for the next time it triggers
     
    115112
    116113        // If there are still alarms pending, reset the timer
    117         if( alarms->head ) {
    118                 __cfaabi_dbg_print_buffer_decl( " KERNEL: @%lu(%lu) resetting alarm to %lu.\n", currtime.tv, __kernel_get_time().tv, (alarms->head->alarm - currtime).tv);
    119                 Duration delta = alarms->head->alarm - currtime;
    120                 Duration caped = max(delta, 50`us);
    121                 // itimerval tim  = { caped };
    122                 // __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);
    123 
    124                 __kernel_set_timer( caped );
    125         }
     114        if( alarms->head ) { __kernel_set_timer( alarms->head->alarm - currtime ); }
    126115}
    127116
     
    161150        void disable_interrupts() {
    162151                with( kernelTLS.preemption_state ) {
    163                         static_assert(__atomic_always_lock_free(sizeof(enabled), &enabled), "Must be lock-free");
    164 
    165                         // Set enabled flag to false
    166                         // should be atomic to avoid preemption in the middle of the operation.
    167                         // use memory order RELAXED since there is no inter-thread on this variable requirements
    168                         __atomic_store_n(&enabled, false, __ATOMIC_RELAXED);
    169 
    170                         // Signal the compiler that a fence is needed but only for signal handlers
    171                         __atomic_signal_fence(__ATOMIC_ACQUIRE);
    172 
     152                        enabled = false;
    173153                        __attribute__((unused)) unsigned short new_val = disable_count + 1;
    174154                        disable_count = new_val;
     
    180160        // If counter reaches 0, execute any pending CtxSwitch
    181161        void enable_interrupts( __cfaabi_dbg_ctx_param ) {
    182                 processor   * proc = kernelTLS.this_processor; // Cache the processor now since interrupts can start happening after the atomic store
    183                 thread_desc * thrd = kernelTLS.this_thread;       // Cache the thread now since interrupts can start happening after the atomic store
     162                processor   * proc = kernelTLS.this_processor; // Cache the processor now since interrupts can start happening after the atomic add
     163                thread_desc * thrd = kernelTLS.this_thread;       // Cache the thread now since interrupts can start happening after the atomic add
    184164
    185165                with( kernelTLS.preemption_state ){
     
    190170                        // Check if we need to prempt the thread because an interrupt was missed
    191171                        if( prev == 1 ) {
    192                                 static_assert(__atomic_always_lock_free(sizeof(enabled), &enabled), "Must be lock-free");
    193 
    194                                 // Set enabled flag to true
    195                                 // should be atomic to avoid preemption in the middle of the operation.
    196                                 // use memory order RELAXED since there is no inter-thread on this variable requirements
    197                                 __atomic_store_n(&enabled, true, __ATOMIC_RELAXED);
    198 
    199                                 // Signal the compiler that a fence is needed but only for signal handlers
    200                                 __atomic_signal_fence(__ATOMIC_RELEASE);
     172                                enabled = true;
    201173                                if( proc->pending_preemption ) {
    202174                                        proc->pending_preemption = false;
     
    217189                verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
    218190                if( prev == 1 ) {
    219                         static_assert(__atomic_always_lock_free(sizeof(kernelTLS.preemption_state.enabled), &kernelTLS.preemption_state.enabled), "Must be lock-free");
    220                         // Set enabled flag to true
    221                         // should be atomic to avoid preemption in the middle of the operation.
    222                         // use memory order RELAXED since there is no inter-thread on this variable requirements
    223                         __atomic_store_n(&kernelTLS.preemption_state.enabled, true, __ATOMIC_RELAXED);
    224 
    225                         // Signal the compiler that a fence is needed but only for signal handlers
    226                         __atomic_signal_fence(__ATOMIC_RELEASE);
     191                        kernelTLS.preemption_state.enabled = true;
    227192                }
    228193        }
     
    370335        if( !preemption_ready() ) { return; }
    371336
    372         __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p @ %p).\n", kernelTLS.this_processor, kernelTLS.this_thread, (void *)(cxt->uc_mcontext.CFA_REG_IP) );
     337        __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p).\n", kernelTLS.this_processor, kernelTLS.this_thread );
    373338
    374339        // Sync flag : prevent recursive calls to the signal handler
    375340        kernelTLS.preemption_state.in_progress = true;
    376341
    377         // Clear sighandler mask before context switching.
    378         static_assert( sizeof( sigset_t ) == sizeof( cxt->uc_sigmask ), "Expected cxt->uc_sigmask to be of sigset_t" );
    379         if ( pthread_sigmask( SIG_SETMASK, (sigset_t *)&(cxt->uc_sigmask), NULL ) == -1 ) {
    380                 abort( "internal error, sigprocmask" );
    381         }
     342        // We are about to CtxSwitch out of the signal handler, let other handlers in
     343        signal_unblock( SIGUSR1 );
    382344
    383345        // TODO: this should go in finish action
     
    415377                                case EAGAIN :
    416378                                case EINTR :
    417                                         {__cfaabi_dbg_print_buffer_decl( " KERNEL: Spurious wakeup %d.\n", err );}
    418379                                        continue;
    419380                        case EINVAL :
     
    463424        sigset_t oldset;
    464425        int ret;
    465         ret = pthread_sigmask(0, NULL, &oldset);
     426        ret = sigprocmask(0, NULL, &oldset);
    466427        if(ret != 0) { abort("ERROR sigprocmask returned %d", ret); }
    467428
    468429        ret = sigismember(&oldset, SIGUSR1);
    469430        if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
     431
    470432        if(ret == 1) { abort("ERROR SIGUSR1 is disabled"); }
    471 
    472         ret = sigismember(&oldset, SIGALRM);
    473         if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
    474         if(ret == 0) { abort("ERROR SIGALRM is enabled"); }
    475 
    476         ret = sigismember(&oldset, SIGTERM);
    477         if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
    478         if(ret == 1) { abort("ERROR SIGTERM is disabled"); }
    479433}
    480434
Note: See TracChangeset for help on using the changeset viewer.