Changes in / [5bd0aad:59e86eb]


Ignore:
Location:
src
Files:
6 edited

Legend:

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

    r5bd0aad r59e86eb  
    153153
    154154void register_self( alarm_node_t * this ) {
    155         alarm_list_t * alarms = &event_kernel->alarms;
     155        disable_interrupts();
     156        verify( !systemProcessor->pending_alarm );
     157        lock( &systemProcessor->alarm_lock DEBUG_CTX2 );
     158        {
     159                verify( validate( &systemProcessor->alarms ) );
     160                bool first = !systemProcessor->alarms.head;
    156161
    157         disable_interrupts();
    158         lock( &event_kernel->lock DEBUG_CTX2 );
    159         {
    160                 verify( validate( alarms ) );
    161                 bool first = !alarms->head;
    162 
    163                 insert( alarms, this );
     162                insert( &systemProcessor->alarms, this );
     163                if( systemProcessor->pending_alarm ) {
     164                        tick_preemption();
     165                }
    164166                if( first ) {
    165                         __kernel_set_timer( alarms->head->alarm - __kernel_get_time() );
     167                        __kernel_set_timer( systemProcessor->alarms.head->alarm - __kernel_get_time() );
    166168                }
    167169        }
    168         unlock( &event_kernel->lock );
     170        unlock( &systemProcessor->alarm_lock );
    169171        this->set = true;
    170172        enable_interrupts( DEBUG_CTX );
     
    172174
    173175void unregister_self( alarm_node_t * this ) {
     176        // LIB_DEBUG_PRINT_BUFFER_DECL( STDERR_FILENO, "Kernel : unregister %p start\n", this );
    174177        disable_interrupts();
    175         lock( &event_kernel->lock DEBUG_CTX2 );
     178        lock( &systemProcessor->alarm_lock DEBUG_CTX2 );
    176179        {
    177                 verify( validate( &event_kernel->alarms ) );
    178                 remove( &event_kernel->alarms, this );
     180                verify( validate( &systemProcessor->alarms ) );
     181                remove( &systemProcessor->alarms, this );
    179182        }
    180         unlock( &event_kernel->lock );
     183        unlock( &systemProcessor->alarm_lock );
    181184        enable_interrupts( DEBUG_CTX );
    182185        this->set = false;
     186        // LIB_DEBUG_PRINT_BUFFER_LOCAL( STDERR_FILENO, "Kernel : unregister %p end\n", this );
    183187}
  • src/libcfa/concurrency/kernel

    r5bd0aad r59e86eb  
    2828//-----------------------------------------------------------------------------
    2929// Locks
    30 void lock      ( spinlock * DEBUG_CTX_PARAM2 );       // Lock the spinlock, spin if already acquired
    31 void lock_yield( spinlock * DEBUG_CTX_PARAM2 );       // Lock the spinlock, yield repeatedly if already acquired
    32 bool try_lock  ( spinlock * DEBUG_CTX_PARAM2 );       // Lock the spinlock, return false if already acquired
    33 void unlock    ( spinlock * );                        // Unlock the spinlock
     30bool try_lock  ( spinlock * DEBUG_CTX_PARAM2 );
     31void lock      ( spinlock * DEBUG_CTX_PARAM2 );
     32void lock_yield( spinlock * DEBUG_CTX_PARAM2 );
     33void unlock    ( spinlock * );
    3434
    3535struct semaphore {
     
    4848// Cluster
    4949struct cluster {
    50         spinlock ready_queue_lock;                      // Ready queue locks
    51         __thread_queue_t ready_queue;                   // Ready queue for threads
    52         unsigned long long int preemption;              // Preemption rate on this cluster
     50        __thread_queue_t ready_queue;
     51        spinlock lock;
    5352};
    5453
     
    7776static inline void ^?{}(FinishAction * this) {}
    7877
    79 // Processor
    80 // Wrapper around kernel threads
    8178struct processor {
    82         // Main state
    83         struct processorCtx_t * runner;                 // Coroutine ctx who does keeps the state of the processor
    84         cluster * cltr;                                 // Cluster from which to get threads
    85         pthread_t kernel_thread;                        // Handle to pthreads
     79        struct processorCtx_t * runner;
     80        cluster * cltr;
     81        pthread_t kernel_thread;
    8682
    87         // Termination
    88         volatile bool do_terminate;                     // Set to true to notify the processor should terminate
    89         semaphore terminated;                           // Termination synchronisation
     83        semaphore terminated;
     84        volatile bool is_terminated;
    9085
    91         // RunThread data
    92         struct FinishAction finish;                     // Action to do after a thread is ran
     86        struct FinishAction finish;
    9387
    94         // Preemption data
    95         struct alarm_node_t * preemption_alarm;         // Node which is added in the discrete event simulaiton
    96         bool pending_preemption;                        // If true, a preemption was triggered in an unsafe region, the processor must preempt as soon as possible
     88        struct alarm_node_t * preemption_alarm;
     89        unsigned int preemption;
    9790
    98 #ifdef __CFA_DEBUG__
    99         char * last_enable;                             // Last function to enable preemption on this processor
    100 #endif
     91        bool pending_preemption;
     92
     93        char * last_enable;
    10194};
    10295
  • src/libcfa/concurrency/kernel.c

    r5bd0aad r59e86eb  
    4747KERNEL_STORAGE(cluster, systemCluster);
    4848KERNEL_STORAGE(system_proc_t, systemProcessor);
    49 KERNEL_STORAGE(event_kernel_t, event_kernel);
    5049KERNEL_STORAGE(thread_desc, mainThread);
    5150KERNEL_STORAGE(machine_context_t, mainThreadCtx);
     
    5352cluster * systemCluster;
    5453system_proc_t * systemProcessor;
    55 event_kernel_t * event_kernel;
    5654thread_desc * mainThread;
    5755
     
    133131        this->cltr = cltr;
    134132        (&this->terminated){ 0 };
    135         this->do_terminate = false;
     133        this->is_terminated = false;
    136134        this->preemption_alarm = NULL;
     135        this->preemption = default_preemption();
    137136        this->pending_preemption = false;
    138137
     
    143142        this->cltr = cltr;
    144143        (&this->terminated){ 0 };
    145         this->do_terminate = false;
     144        this->is_terminated = false;
    146145        this->preemption_alarm = NULL;
     146        this->preemption = default_preemption();
    147147        this->pending_preemption = false;
    148148        this->kernel_thread = pthread_self();
     
    156156
    157157void ?{}(system_proc_t * this, cluster * cltr, processorCtx_t * runner) {
     158        (&this->alarms){};
     159        (&this->alarm_lock){};
     160        this->pending_alarm = false;
     161
    158162        (&this->proc){ cltr, runner };
    159 }
    160 
    161 void ?{}(event_kernel_t * this) {
    162         (&this->alarms){};
    163         (&this->lock){};
    164163
    165164        verify( validate( &this->alarms ) );
     
    167166
    168167void ^?{}(processor * this) {
    169         if( ! this->do_terminate ) {
     168        if( ! this->is_terminated ) {
    170169                LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", this);
    171                 this->do_terminate = true;
     170                this->is_terminated = true;
    172171                P( &this->terminated );
    173172                pthread_join( this->kernel_thread, NULL );
     
    177176void ?{}(cluster * this) {
    178177        ( &this->ready_queue ){};
    179         ( &this->ready_queue_lock ){};
    180 
    181         this->preemption = default_preemption();
     178        ( &this->lock ){};
    182179}
    183180
     
    202199
    203200                thread_desc * readyThread = NULL;
    204                 for( unsigned int spin_count = 0; ! this->do_terminate; spin_count++ )
     201                for( unsigned int spin_count = 0; ! this->is_terminated; spin_count++ )
    205202                {
    206203                        readyThread = nextThread( this->cltr );
     
    346343        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    347344
    348         lock( &systemProcessor->proc.cltr->ready_queue_lock DEBUG_CTX2 );
     345        lock( &systemProcessor->proc.cltr->lock DEBUG_CTX2 );
    349346        append( &systemProcessor->proc.cltr->ready_queue, thrd );
    350         unlock( &systemProcessor->proc.cltr->ready_queue_lock );
     347        unlock( &systemProcessor->proc.cltr->lock );
    351348
    352349        verify( disable_preempt_count > 0 );
     
    355352thread_desc * nextThread(cluster * this) {
    356353        verify( disable_preempt_count > 0 );
    357         lock( &this->ready_queue_lock DEBUG_CTX2 );
     354        lock( &this->lock DEBUG_CTX2 );
    358355        thread_desc * head = pop_head( &this->ready_queue );
    359         unlock( &this->ready_queue_lock );
     356        unlock( &this->lock );
    360357        verify( disable_preempt_count > 0 );
    361358        return head;
     
    473470        systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtxStorage };
    474471
    475         // Initialize the event kernel
    476         event_kernel = (event_kernel_t *)&event_kernelStorage;
    477         event_kernel{};
    478 
    479472        // Add the main thread to the ready queue
    480473        // once resume is called on systemProcessor->runner the mainThread needs to be scheduled like any normal thread
     
    511504        // When its coroutine terminates, it return control to the mainThread
    512505        // which is currently here
    513         systemProcessor->proc.do_terminate = true;
     506        systemProcessor->proc.is_terminated = true;
    514507        suspend();
    515508
  • src/libcfa/concurrency/kernel_private.h

    r5bd0aad r59e86eb  
    4545thread_desc * nextThread(cluster * this);
    4646
    47 //Block current thread and release/wake-up the following resources
    4847void BlockInternal(void);
    4948void BlockInternal(spinlock * lock);
     
    6867struct system_proc_t {
    6968        processor proc;
    70 };
    7169
    72 struct event_kernel_t {
    7370        alarm_list_t alarms;
    74         spinlock lock;
     71        spinlock alarm_lock;
     72
     73        bool pending_alarm;
    7574};
    7675
    7776extern cluster * systemCluster;
    7877extern system_proc_t * systemProcessor;
    79 extern event_kernel_t * event_kernel;
    80 
    8178extern volatile thread_local processor * this_processor;
    8279extern volatile thread_local coroutine_desc * this_coroutine;
  • src/libcfa/concurrency/preemption.c

    r5bd0aad r59e86eb  
    6666
    6767void tick_preemption() {
    68         alarm_list_t * alarms = &event_kernel->alarms;
     68        alarm_list_t * alarms = &systemProcessor->alarms;
    6969        __cfa_time_t currtime = __kernel_get_time();
    7070
     
    189189}
    190190
     191static inline void defer_alarm() {
     192        systemProcessor->pending_alarm = true;
     193}
     194
    191195static void preempt( processor * this ) {
    192196        pthread_kill( this->kernel_thread, SIGUSR1 );
     
    232236        this->proc = proc;
    233237        this->proc->preemption_alarm = &this->alarm;
    234         update_preemption( this->proc, this->proc->cltr->preemption );
     238        update_preemption( this->proc, this->proc->preemption );
    235239}
    236240
     
    279283                case SI_KERNEL:
    280284                        LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");
    281                         lock( &event_kernel->lock DEBUG_CTX2 );
     285                        lock( &systemProcessor->alarm_lock DEBUG_CTX2 );
    282286                        tick_preemption();
    283                         unlock( &event_kernel->lock );
     287                        unlock( &systemProcessor->alarm_lock );
    284288                        break;
    285289                case SI_QUEUE:
  • src/tests/test.py

    r5bd0aad r59e86eb  
    221221                if   retcode == TestResult.SUCCESS:     result_txt = "Done"
    222222                elif retcode == TestResult.TIMEOUT:     result_txt = "TIMEOUT"
    223                 else :                                          result_txt = "ERROR code %d" % retcode
     223                else :                                          result_txt = "ERROR"
    224224        else :
    225225                if   retcode == TestResult.SUCCESS:     result_txt = "PASSED"
    226226                elif retcode == TestResult.TIMEOUT:     result_txt = "TIMEOUT"
    227                 else :                                          result_txt = "FAILED with code %d" % retcode
     227                else :                                          result_txt = "FAILED"
    228228
    229229        #print result with error if needed
Note: See TracChangeset for help on using the changeset viewer.