Ignore:
File:
1 edited

Legend:

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

    r2026bb6 rac2b598  
    1010// Created On       : Mon Jun 5 14:20:42 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jun  5 17:35:49 2018
    13 // Update Count     : 37
     12// Last Modified On : Thu Dec  5 16:34:05 2019
     13// Update Count     : 43
    1414//
    1515
     
    2424#include <string.h>
    2525#include <unistd.h>
     26#include <limits.h>                                                                             // PTHREAD_STACK_MIN
    2627}
    2728
     
    3839// FwdDeclarations : timeout handlers
    3940static void preempt( processor   * this );
    40 static void timeout( thread_desc * this );
     41static void timeout( $thread * this );
    4142
    4243// FwdDeclarations : Signal handlers
     
    6465event_kernel_t * event_kernel;                        // kernel public handle to even kernel
    6566static pthread_t alarm_thread;                        // pthread handle to alarm thread
     67static void * alarm_stack;                                                        // pthread stack for alarm thread
    6668
    6769static void ?{}(event_kernel_t & this) with( this ) {
     
    8183// Get next expired node
    8284static inline alarm_node_t * get_expired( alarm_list_t * alarms, Time currtime ) {
    83         if( !alarms->head ) return NULL;                          // If no alarms return null
    84         if( alarms->head->alarm >= currtime ) return NULL;        // If alarms head not expired return null
    85         return pop(alarms);                                       // Otherwise just pop head
     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
     87        return pop(alarms);                                                                     // Otherwise just pop head
    8688}
    8789
    8890// Tick one frame of the Discrete Event Simulation for alarms
    8991static void tick_preemption() {
    90         alarm_node_t * node = NULL;                     // Used in the while loop but cannot be declared in the while condition
    91         alarm_list_t * alarms = &event_kernel->alarms;  // Local copy for ease of reading
    92         Time currtime = __kernel_get_time();                    // Check current time once so we everything "happens at once"
     92        alarm_node_t * node = 0p;                                                       // Used in the while loop but cannot be declared in the while condition
     93        alarm_list_t * alarms = &event_kernel->alarms;          // Local copy for ease of reading
     94        Time currtime = __kernel_get_time();                            // Check current time once so everything "happens at once"
    9395
    9496        //Loop throught every thing expired
     
    182184
    183185        // Enable interrupts by decrementing the counter
    184         // If counter reaches 0, execute any pending CtxSwitch
     186        // If counter reaches 0, execute any pending __cfactx_switch
    185187        void enable_interrupts( __cfaabi_dbg_ctx_param ) {
    186188                processor   * proc = kernelTLS.this_processor; // Cache the processor now since interrupts can start happening after the atomic store
    187                 thread_desc * thrd = kernelTLS.this_thread;       // Cache the thread now since interrupts can start happening after the atomic store
    188189
    189190                with( kernelTLS.preemption_state ){
     
    207208                                if( proc->pending_preemption ) {
    208209                                        proc->pending_preemption = false;
    209                                         BlockInternal( thrd );
     210                                        force_yield( __POLL_PREEMPTION );
    210211                                }
    211212                        }
     
    217218
    218219        // Disable interrupts by incrementint the counter
    219         // Don't execute any pending CtxSwitch even if counter reaches 0
     220        // Don't execute any pending __cfactx_switch even if counter reaches 0
    220221        void enable_interrupts_noPoll() {
    221222                unsigned short prev = kernelTLS.preemption_state.disable_count;
     
    243244        sigaddset( &mask, sig );
    244245
    245         if ( pthread_sigmask( SIG_UNBLOCK, &mask, NULL ) == -1 ) {
     246        if ( pthread_sigmask( SIG_UNBLOCK, &mask, 0p ) == -1 ) {
    246247            abort( "internal error, pthread_sigmask" );
    247248        }
     
    254255        sigaddset( &mask, sig );
    255256
    256         if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) {
     257        if ( pthread_sigmask( SIG_BLOCK, &mask, 0p ) == -1 ) {
    257258            abort( "internal error, pthread_sigmask" );
    258259        }
     
    266267
    267268// reserved for future use
    268 static void timeout( thread_desc * this ) {
     269static void timeout( $thread * this ) {
    269270        //TODO : implement waking threads
    270271}
    271272
    272273// KERNEL ONLY
    273 // Check if a CtxSwitch signal handler shoud defer
     274// Check if a __cfactx_switch signal handler shoud defer
    274275// If true  : preemption is safe
    275276// If false : preemption is unsafe and marked as pending
     
    301302
    302303        // Setup proper signal handlers
    303         __cfaabi_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO | SA_RESTART );         // CtxSwitch handler
     304        __cfaabi_sigaction( SIGUSR1, sigHandler_ctxSwitch, SA_SIGINFO | SA_RESTART ); // __cfactx_switch handler
    304305
    305306        signal_block( SIGALRM );
    306307
    307         pthread_create( &alarm_thread, NULL, alarm_loop, NULL );
     308        alarm_stack = __create_pthread( &alarm_thread, alarm_loop, 0p );
    308309}
    309310
     
    316317        sigset_t mask;
    317318        sigfillset( &mask );
    318         sigprocmask( SIG_BLOCK, &mask, NULL );
     319        sigprocmask( SIG_BLOCK, &mask, 0p );
    319320
    320321        // Notify the alarm thread of the shutdown
     
    323324
    324325        // Wait for the preemption thread to finish
    325         pthread_join( alarm_thread, NULL );
     326
     327        pthread_join( alarm_thread, 0p );
     328        free( alarm_stack );
    326329
    327330        // Preemption is now fully stopped
     
    380383        static_assert( sizeof( sigset_t ) == sizeof( cxt->uc_sigmask ), "Expected cxt->uc_sigmask to be of sigset_t" );
    381384        #endif
    382         if ( pthread_sigmask( SIG_SETMASK, (sigset_t *)&(cxt->uc_sigmask), NULL ) == -1 ) {
     385        if ( pthread_sigmask( SIG_SETMASK, (sigset_t *)&(cxt->uc_sigmask), 0p ) == -1 ) {
    383386                abort( "internal error, sigprocmask" );
    384387        }
     
    390393        // Preemption can occur here
    391394
    392         BlockInternal( kernelTLS.this_thread ); // Do the actual CtxSwitch
     395        force_yield( __ALARM_PREEMPTION ); // Do the actual __cfactx_switch
    393396}
    394397
     
    399402        sigset_t mask;
    400403        sigfillset(&mask);
    401         if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) {
     404        if ( pthread_sigmask( SIG_BLOCK, &mask, 0p ) == -1 ) {
    402405            abort( "internal error, pthread_sigmask" );
    403406        }
     
    420423                                        {__cfaabi_dbg_print_buffer_decl( " KERNEL: Spurious wakeup %d.\n", err );}
    421424                                        continue;
    422                         case EINVAL :
     425                                case EINVAL :
    423426                                        abort( "Timeout was invalid." );
    424427                                default:
     
    453456EXIT:
    454457        __cfaabi_dbg_print_safe( "Kernel : Preemption thread stopping\n" );
    455         return NULL;
     458        return 0p;
    456459}
    457460
     
    466469        sigset_t oldset;
    467470        int ret;
    468         ret = pthread_sigmask(0, NULL, &oldset);
     471        ret = pthread_sigmask(0, 0p, &oldset);
    469472        if(ret != 0) { abort("ERROR sigprocmask returned %d", ret); }
    470473
Note: See TracChangeset for help on using the changeset viewer.