Ignore:
Timestamp:
May 25, 2018, 2:51:06 PM (6 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
new-env, with_gc
Children:
cdc4d43
Parents:
3ef35bd (diff), 58e822a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge remote-tracking branch 'origin/master' into with_gc

File:
1 edited

Legend:

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

    r3ef35bd reba74ba  
    1515
    1616#include "preemption.h"
     17#include <assert.h>
    1718
    1819extern "C" {
     
    9192        //Loop throught every thing expired
    9293        while( node = get_expired( alarms, currtime ) ) {
     94                // __cfaabi_dbg_print_buffer_decl( " KERNEL: preemption tick.\n" );
    9395
    9496                // Check if this is a kernel
     
    103105                Duration period = node->period;
    104106                if( period > 0 ) {
     107                        // __cfaabi_dbg_print_buffer_local( " KERNEL: alarm period is %lu.\n", period.tv );
    105108                        node->alarm = currtime + period;    // Alarm is periodic, add currtime to it (used cached current time)
    106109                        insert( alarms, node );             // Reinsert the node for the next time it triggers
     
    112115
    113116        // If there are still alarms pending, reset the timer
    114         if( alarms->head ) { __kernel_set_timer( alarms->head->alarm - currtime ); }
     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        }
    115126}
    116127
     
    150161        void disable_interrupts() {
    151162                with( kernelTLS.preemption_state ) {
    152                         enabled = false;
     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
    153173                        __attribute__((unused)) unsigned short new_val = disable_count + 1;
    154174                        disable_count = new_val;
     
    160180        // If counter reaches 0, execute any pending CtxSwitch
    161181        void enable_interrupts( __cfaabi_dbg_ctx_param ) {
    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
     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
    164184
    165185                with( kernelTLS.preemption_state ){
     
    170190                        // Check if we need to prempt the thread because an interrupt was missed
    171191                        if( prev == 1 ) {
    172                                 enabled = true;
     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);
    173201                                if( proc->pending_preemption ) {
    174202                                        proc->pending_preemption = false;
     
    189217                verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
    190218                if( prev == 1 ) {
    191                         kernelTLS.preemption_state.enabled = true;
     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);
    192227                }
    193228        }
     
    335370        if( !preemption_ready() ) { return; }
    336371
    337         __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p).\n", kernelTLS.this_processor, kernelTLS.this_thread );
     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) );
    338373
    339374        // Sync flag : prevent recursive calls to the signal handler
    340375        kernelTLS.preemption_state.in_progress = true;
    341376
    342         // We are about to CtxSwitch out of the signal handler, let other handlers in
    343         signal_unblock( SIGUSR1 );
     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        }
    344382
    345383        // TODO: this should go in finish action
     
    377415                                case EAGAIN :
    378416                                case EINTR :
     417                                        {__cfaabi_dbg_print_buffer_decl( " KERNEL: Spurious wakeup %d.\n", err );}
    379418                                        continue;
    380419                        case EINVAL :
     
    424463        sigset_t oldset;
    425464        int ret;
    426         ret = sigprocmask(0, NULL, &oldset);
     465        ret = pthread_sigmask(0, NULL, &oldset);
    427466        if(ret != 0) { abort("ERROR sigprocmask returned %d", ret); }
    428467
    429468        ret = sigismember(&oldset, SIGUSR1);
    430469        if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
    431 
    432470        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"); }
    433479}
    434480
Note: See TracChangeset for help on using the changeset viewer.