Ignore:
File:
1 edited

Legend:

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

    r5a05946 r6b33e89  
    1010// Created On       : Mon Jun 5 14:20:42 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jan  9 08:42:59 2023
    13 // Update Count     : 60
     12// Last Modified On : Fri Apr 25 07:24:39 2025
     13// Update Count     : 63
    1414//
    1515
     
    3939__attribute__((weak)) Duration default_preemption() libcfa_public {
    4040        const char * preempt_rate_s = getenv("CFA_DEFAULT_PREEMPTION");
    41         if(!preempt_rate_s) {
     41        if ( !preempt_rate_s) {
    4242                __cfadbg_print_safe(preemption, "No CFA_DEFAULT_PREEMPTION in ENV\n");
    4343                return __CFA_DEFAULT_PREEMPTION__;
     
    4646        char * endptr = 0p;
    4747        long int preempt_rate_l = strtol(preempt_rate_s, &endptr, 10);
    48         if(preempt_rate_l < 0 || preempt_rate_l > 65535) {
     48        if (preempt_rate_l < 0 || preempt_rate_l > 65535) {
    4949                __cfadbg_print_safe(preemption, "CFA_DEFAULT_PREEMPTION out of range : %ld\n", preempt_rate_l);
    5050                return __CFA_DEFAULT_PREEMPTION__;
    5151        }
    52         if('\0' != *endptr) {
     52        if ('\0' != *endptr) {
    5353                __cfadbg_print_safe(preemption, "CFA_DEFAULT_PREEMPTION not a decimal number : %s\n", preempt_rate_s);
    5454                return __CFA_DEFAULT_PREEMPTION__;
     
    6464// FwdDeclarations : Signal handlers
    6565static void sigHandler_ctxSwitch( __CFA_SIGPARMS__ );
    66 static void sigHandler_alarm    ( __CFA_SIGPARMS__ );
    67 static void sigHandler_segv     ( __CFA_SIGPARMS__ );
    68 static void sigHandler_ill      ( __CFA_SIGPARMS__ );
    69 static void sigHandler_fpe      ( __CFA_SIGPARMS__ );
    70 static void sigHandler_abort    ( __CFA_SIGPARMS__ );
     66static void sigHandler_alarm( __CFA_SIGPARMS__ );
     67static void sigHandler_segv( __CFA_SIGPARMS__ );
     68static void sigHandler_ill( __CFA_SIGPARMS__ );
     69static void sigHandler_fpe( __CFA_SIGPARMS__ );
     70static void sigHandler_abort( __CFA_SIGPARMS__ );
    7171
    7272// FwdDeclarations : alarm thread main
     
    8686#endif
    8787
    88 KERNEL_STORAGE(event_kernel_t, event_kernel);         // private storage for event kernel
    89 event_kernel_t * event_kernel;                        // kernel public handle to even kernel
    90 static pthread_t alarm_thread;                        // pthread handle to alarm thread
    91 static void * alarm_stack;                                                        // pthread stack for alarm thread
     88KERNEL_STORAGE(event_kernel_t, event_kernel);                   // private storage for event kernel
     89event_kernel_t * event_kernel;                                                  // kernel public handle to even kernel
     90static pthread_t alarm_thread;                                                  // pthread handle to alarm thread
     91static void * alarm_stack;                                                              // pthread stack for alarm thread
    9292
    9393static void ?{}(event_kernel_t & this) with( this ) {
     
    102102// Get next expired node
    103103static inline alarm_node_t * get_expired( alarm_list_t * alarms, Time currtime ) {
    104         if( ! & (*alarms)`first ) return 0p;                                            // If no alarms return null
    105         if( (*alarms)`first.deadline >= currtime ) return 0p;   // If alarms head not expired return null
    106         return pop(alarms);                                                                     // Otherwise just pop head
     104        if ( ! & first( *alarms ) ) return 0p;                            // If no alarms return null
     105        if ( first( *alarms ).deadline >= currtime ) return 0p; // If alarms head not expired return null
     106        return pop(alarms);                                                                       // Otherwise just pop head
    107107}
    108108
     
    117117                __cfadbg_print_buffer_decl( preemption, " KERNEL: preemption tick %lu\n", currtime.tn);
    118118                Duration period = node->period;
    119                 if( period == 0 ) {
    120                         node->set = false;                  // Node is one-shot, just mark it as not pending
     119                if ( period == 0 ) {
     120                        node->set = false;                                // Node is one-shot, just mark it as not pending
    121121                }
    122122
     
    125125
    126126                // Check if this is a kernel
    127                 if( node->type == Kernel ) {
     127                if ( node->type == Kernel ) {
    128128                        preempt( node->proc );
    129129                }
    130                 else if( node->type == User ) {
     130                else if ( node->type == User ) {
    131131                        __cfadbg_print_buffer_local( preemption, " KERNEL: alarm unparking %p.\n", node->thrd );
    132132                        timeout( node->thrd );
     
    137137
    138138                // Check if this is a periodic alarm
    139                 if( period > 0 ) {
     139                if ( period > 0 ) {
    140140                        __cfadbg_print_buffer_local( preemption, " KERNEL: alarm period is %lu.\n", period`ns );
    141141                        node->deadline = currtime + period;  // Alarm is periodic, add currtime to it (used cached current time)
    142                         insert( alarms, node );            // Reinsert the node for the next time it triggers
     142                        insert( alarms, node );                  // Reinsert the node for the next time it triggers
    143143                }
    144144        }
    145145
    146146        // If there are still alarms pending, reset the timer
    147         if( & (*alarms)`first ) {
    148                 Duration delta = (*alarms)`first.deadline - currtime;
     147        if ( & first( *alarms ) ) {
     148                Duration delta = first( *alarms ).deadline - currtime;
    149149                __kernel_set_timer( delta );
    150150        }
     
    283283                __attribute__((unused)) unsigned short new_val = disable_count + 1;
    284284                disable_count = new_val;
    285                 verify( new_val < 65_000u );              // If this triggers someone is disabling interrupts without enabling them
     285                verify( new_val < 65_000u );                      // If this triggers someone is disabling interrupts without enabling them
    286286        }
    287287
     
    301301
    302302                        // Check if we need to prempt the thread because an interrupt was missed
    303                         if( prev == 1 ) {
     303                        if ( prev == 1 ) {
    304304                                #if GCC_VERSION > 50000
    305305                                        static_assert(__atomic_always_lock_free(sizeof(enabled), &enabled), "Must be lock-free");
     
    313313                                // Signal the compiler that a fence is needed but only for signal handlers
    314314                                __atomic_signal_fence(__ATOMIC_RELEASE);
    315                                 if( poll && proc->pending_preemption ) {
     315                                if ( poll && proc->pending_preemption ) {
    316316                                        proc->pending_preemption = false;
    317317                                        force_yield( __POLL_PREEMPTION );
     
    334334                // Signal the compiler that a fence is needed but only for signal handlers
    335335                __atomic_signal_fence(__ATOMIC_RELEASE);
    336                 if( unlikely( proc->pending_preemption ) ) {
     336                if ( unlikely( proc->pending_preemption ) ) {
    337337                        proc->pending_preemption = false;
    338338                        force_yield( __POLL_PREEMPTION );
     
    347347void __cfaabi_check_preemption() libcfa_public {
    348348        bool ready = __preemption_enabled();
    349         if(!ready) { abort("Preemption should be ready"); }
     349        if ( !ready) { abort("Preemption should be ready"); }
    350350
    351351        sigset_t oldset;
    352352        int ret;
    353353        ret = __cfaabi_pthread_sigmask(0, ( const sigset_t * ) 0p, &oldset);  // workaround trac#208: cast should be unnecessary
    354         if(ret != 0) { abort("ERROR sigprocmask returned %d", ret); }
     354        if (ret != 0) { abort("ERROR sigprocmask returned %d", ret); }
    355355
    356356        ret = sigismember(&oldset, SIGUSR1);
    357         if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
    358         if(ret == 1) { abort("ERROR SIGUSR1 is disabled"); }
     357        if (ret <  0) { abort("ERROR sigismember returned %d", ret); }
     358        if (ret == 1) { abort("ERROR SIGUSR1 is disabled"); }
    359359
    360360        ret = sigismember(&oldset, SIGALRM);
    361         if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
    362         if(ret == 0) { abort("ERROR SIGALRM is enabled"); }
     361        if (ret <  0) { abort("ERROR sigismember returned %d", ret); }
     362        if (ret == 0) { abort("ERROR SIGALRM is enabled"); }
    363363
    364364        ret = sigismember(&oldset, SIGTERM);
    365         if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
    366         if(ret == 1) { abort("ERROR SIGTERM is disabled"); }
     365        if (ret <  0) { abort("ERROR sigismember returned %d", ret); }
     366        if (ret == 1) { abort("ERROR SIGTERM is disabled"); }
    367367}
    368368
     
    385385
    386386        if ( __cfaabi_pthread_sigmask( SIG_UNBLOCK, &mask, 0p ) == -1 ) {
    387             abort( "internal error, pthread_sigmask" );
     387                abort( "internal error, pthread_sigmask" );
    388388        }
    389389}
     
    415415        int ret;
    416416        ret = __cfaabi_pthread_sigmask(0, ( const sigset_t * ) 0p, &oldset);  // workaround trac#208: cast should be unnecessary
    417         if(ret != 0) { abort("ERROR sigprocmask returned %d", ret); }
     417        if (ret != 0) { abort("ERROR sigprocmask returned %d", ret); }
    418418
    419419        ret = sigismember(&oldset, SIGUSR1);
    420         if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
    421         if(ret == 1) { abort("ERROR SIGUSR1 is disabled"); }
     420        if (ret <  0) { abort("ERROR sigismember returned %d", ret); }
     421        if (ret == 1) { abort("ERROR SIGUSR1 is disabled"); }
    422422
    423423        ret = sigismember(&oldset, SIGALRM);
    424         if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
    425         if(ret == 0) { abort("ERROR SIGALRM is enabled"); }
     424        if (ret <  0) { abort("ERROR sigismember returned %d", ret); }
     425        if (ret == 0) { abort("ERROR SIGALRM is enabled"); }
    426426
    427427        signal_block( SIGUSR1 );
     
    434434        int ret;
    435435        ret = __cfaabi_pthread_sigmask(0, ( const sigset_t * ) 0p, &oldset);  // workaround trac#208: cast should be unnecessary
    436         if(ret != 0) { abort("ERROR sigprocmask returned %d", ret); }
     436        if (ret != 0) { abort("ERROR sigprocmask returned %d", ret); }
    437437
    438438        ret = sigismember(&oldset, SIGUSR1);
    439         if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
    440         if(ret == 1) { abort("ERROR SIGUSR1 is disabled"); }
     439        if (ret <  0) { abort("ERROR sigismember returned %d", ret); }
     440        if (ret == 1) { abort("ERROR SIGUSR1 is disabled"); }
    441441
    442442        ret = sigismember(&oldset, SIGALRM);
    443         if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
    444         if(ret == 0) { abort("ERROR SIGALRM is enabled"); }
     443        if (ret <  0) { abort("ERROR sigismember returned %d", ret); }
     444        if (ret == 0) { abort("ERROR SIGALRM is enabled"); }
    445445}
    446446
     
    453453        // Check if preemption is safe
    454454        bool ready = true;
    455         if( __cfaabi_in( ip, __libcfa_nopreempt ) ) { ready = false; goto EXIT; };
    456         if( __cfaabi_in( ip, __libcfathrd_nopreempt ) ) { ready = false; goto EXIT; };
    457 
    458         if( !__cfaabi_tls.preemption_state.enabled) { ready = false; goto EXIT; };
    459         if( __cfaabi_tls.preemption_state.in_progress ) { ready = false; goto EXIT; };
     455        if ( __cfaabi_in( ip, __libcfa_nopreempt ) ) { ready = false; goto EXIT; };
     456        if ( __cfaabi_in( ip, __libcfathrd_nopreempt ) ) { ready = false; goto EXIT; };
     457
     458        if ( !__cfaabi_tls.preemption_state.enabled) { ready = false; goto EXIT; };
     459        if ( __cfaabi_tls.preemption_state.in_progress ) { ready = false; goto EXIT; };
    460460
    461461EXIT:
     
    484484        // Setup proper signal handlers
    485485        __cfaabi_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO ); // __cfactx_switch handler
    486         __cfaabi_sigaction( SIGALRM, sigHandler_alarm    , SA_SIGINFO ); // debug handler
     486        __cfaabi_sigaction( SIGALRM, sigHandler_alarm , SA_SIGINFO ); // debug handler
    487487
    488488        signal_block( SIGALRM );
     
    551551        // before the kernel thread has even started running. When that happens, an interrupt
    552552        // with a null 'this_processor' will be caught, just ignore it.
    553         if(! __cfaabi_tls.this_processor ) return;
     553        if ( ! __cfaabi_tls.this_processor ) return;
    554554
    555555        choose(sfp->si_value.sival_int) {
    556                 case PREEMPT_NORMAL   : ;// Normal case, nothing to do here
    557                 case PREEMPT_IO       : ;// I/O asked to stop spinning, nothing to do here
     556                case PREEMPT_NORMAL: ;                                                  // Normal case, nothing to do here
     557                case PREEMPT_IO: ;                                                              // I/O asked to stop spinning, nothing to do here
    558558                case PREEMPT_TERMINATE: verify( __atomic_load_n( &__cfaabi_tls.this_processor->do_terminate, __ATOMIC_SEQ_CST ) );
    559559                default:
     
    562562
    563563        // Check if it is safe to preempt here
    564         if( !preemption_ready( ip ) ) {
     564        if ( !preemption_ready( ip ) ) {
    565565                #if !defined(__CFA_NO_STATISTICS__)
    566566                        __cfaabi_tls.this_stats->ready.threads.preempt.rllfwd++;
     
    607607        sigfillset(&mask);
    608608        if ( __cfaabi_pthread_sigmask( SIG_BLOCK, &mask, 0p ) == -1 ) {
    609             abort( "internal error, pthread_sigmask" );
     609                abort( "internal error, pthread_sigmask" );
    610610        }
    611611
     
    622622                __cfadbg_print_buffer_local( preemption, " KERNEL: SI_QUEUE %d, SI_TIMER %d, SI_KERNEL %d\n", SI_QUEUE, SI_TIMER, SI_KERNEL );
    623623
    624                 if( sig < 0 ) {
     624                if ( sig < 0 ) {
    625625                        //Error!
    626626                        int err = errno;
Note: See TracChangeset for help on using the changeset viewer.