Ignore:
Timestamp:
May 11, 2020, 1:53:29 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
504a7dc
Parents:
b7d6a36 (diff), a7b486b (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 branch 'master' into relaxed_ready

File:
1 edited

Legend:

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

    rb7d6a36 r6a490b2  
    3939// FwdDeclarations : timeout handlers
    4040static void preempt( processor   * this );
    41 static void timeout( thread_desc * this );
     41static void timeout( $thread * this );
    4242
    4343// FwdDeclarations : Signal handlers
    4444static void sigHandler_ctxSwitch( __CFA_SIGPARMS__ );
     45static void sigHandler_alarm    ( __CFA_SIGPARMS__ );
    4546static void sigHandler_segv     ( __CFA_SIGPARMS__ );
    4647static void sigHandler_ill      ( __CFA_SIGPARMS__ );
     
    8384// Get next expired node
    8485static inline alarm_node_t * get_expired( alarm_list_t * alarms, Time currtime ) {
    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
     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
    8788        return pop(alarms);                                                                     // Otherwise just pop head
    8889}
     
    9798        while( node = get_expired( alarms, currtime ) ) {
    9899                // __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                }
    99104
    100105                // Check if this is a kernel
     
    107112
    108113                // Check if this is a periodic alarm
    109                 Duration period = node->period;
    110114                if( period > 0 ) {
    111115                        // __cfaabi_dbg_print_buffer_local( " KERNEL: alarm period is %lu.\n", period.tv );
     
    113117                        insert( alarms, node );             // Reinsert the node for the next time it triggers
    114118                }
    115                 else {
    116                         node->set = false;                  // Node is one-shot, just mark it as not pending
    117                 }
    118119        }
    119120
    120121        // If there are still alarms pending, reset the timer
    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);
     122        if( & (*alarms)`first ) {
     123                __cfadbg_print_buffer_decl(preemption, " 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);
    125126                // itimerval tim  = { caped };
    126127                // __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);
    127128
    128                 __kernel_set_timer( caped );
     129                __kernel_set_timer( capped );
    129130        }
    130131}
     
    184185
    185186        // Enable interrupts by decrementing the counter
    186         // If counter reaches 0, execute any pending CtxSwitch
     187        // If counter reaches 0, execute any pending __cfactx_switch
    187188        void enable_interrupts( __cfaabi_dbg_ctx_param ) {
    188189                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                                         BlockInternal( thrd );
     211                                        force_yield( __POLL_PREEMPTION );
    212212                                }
    213213                        }
     
    219219
    220220        // Disable interrupts by incrementint the counter
    221         // Don't execute any pending CtxSwitch even if counter reaches 0
     221        // Don't execute any pending __cfactx_switch 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_desc * this ) {
    271         //TODO : implement waking threads
     270static void timeout( $thread * this ) {
     271        __unpark( this __cfaabi_dbg_ctx2 );
    272272}
    273273
    274274// KERNEL ONLY
    275 // Check if a CtxSwitch signal handler shoud defer
     275// Check if a __cfactx_switch 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 ); // CtxSwitch handler
     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
    306307
    307308        signal_block( SIGALRM );
    308309
    309         alarm_stack = create_pthread( &alarm_thread, alarm_loop, 0p );
     310        alarm_stack = __create_pthread( &alarm_thread, alarm_loop, 0p );
    310311}
    311312
     
    394395        // Preemption can occur here
    395396
    396         BlockInternal( kernelTLS.this_thread ); // Do the actual CtxSwitch
     397        force_yield( __ALARM_PREEMPTION ); // Do the actual __cfactx_switch
     398}
     399
     400static void sigHandler_alarm( __CFA_SIGPARMS__ ) {
     401        abort("SIGALRM should never reach the signal handler");
    397402}
    398403
Note: See TracChangeset for help on using the changeset viewer.