Changeset 85b1deb


Ignore:
Timestamp:
Jun 7, 2018, 6:10:10 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, with_gc
Children:
7bdcac1, beefc34
Parents:
08b5a7e
Message:

Fix processor halting

Location:
src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/bits/locks.h

    r08b5a7e r85b1deb  
    126126
    127127        struct __bin_sem_t {
    128                 int_fast8_t     counter;
    129                 pthread_mutex_t lock;
    130                 pthread_cond_t  cond;
     128                bool                    signaled;
     129                pthread_mutex_t         lock;
     130                pthread_cond_t          cond;
    131131        };
    132132
    133133        static inline void ?{}(__bin_sem_t & this) with( this ) {
    134                 counter = 0;
     134                signaled = false;
    135135                pthread_mutex_init(&lock, NULL);
    136136                pthread_cond_init (&cond, NULL);
     
    145145                verify(__cfaabi_dbg_in_kernel());
    146146                pthread_mutex_lock(&lock);
    147                 if(counter != 0) {   // this must be a loop, not if!
    148                         pthread_cond_wait(&cond, &lock);
    149                 }
    150                 counter = 1;
     147                        if(!signaled) {   // this must be a loop, not if!
     148                                pthread_cond_wait(&cond, &lock);
     149                        }
     150                        signaled = false;
    151151                pthread_mutex_unlock(&lock);
    152152        }
     
    154154        static inline void post(__bin_sem_t & this) with( this ) {
    155155                verify(__cfaabi_dbg_in_kernel());
     156
    156157                pthread_mutex_lock(&lock);
    157                 bool needs_signal = counter == 0;
    158                 counter = 1;
     158                        bool needs_signal = !signaled;
     159                        signaled = true;
    159160                pthread_mutex_unlock(&lock);
    160                 if (!needs_signal)
     161
     162                if (needs_signal)
    161163                        pthread_cond_signal(&cond);
    162                 }
     164        }
    163165#endif
  • src/libcfa/concurrency/kernel

    r08b5a7e r85b1deb  
    113113        pthread_t kernel_thread;
    114114
     115        // RunThread data
     116        // Action to do after a thread is ran
     117        struct FinishAction finish;
     118
     119        // Preemption data
     120        // Node which is added in the discrete event simulaiton
     121        struct alarm_node_t * preemption_alarm;
     122
     123        // If true, a preemption was triggered in an unsafe region, the processor must preempt as soon as possible
     124        bool pending_preemption;
     125
     126        // Idle lock
     127        __bin_sem_t idleLock;
     128
    115129        // Termination
    116130        // Set to true to notify the processor should terminate
     
    119133        // Termination synchronisation
    120134        semaphore terminated;
    121 
    122         // RunThread data
    123         // Action to do after a thread is ran
    124         struct FinishAction finish;
    125 
    126         // Preemption data
    127         // Node which is added in the discrete event simulaiton
    128         struct alarm_node_t * preemption_alarm;
    129 
    130         // If true, a preemption was triggered in an unsafe region, the processor must preempt as soon as possible
    131         bool pending_preemption;
    132 
    133         // Idle lock
    134         sem_t idleLock;
    135         // __bin_sem_t idleLock;
    136135
    137136        // Link lists fields
  • src/libcfa/concurrency/kernel.c

    r08b5a7e r85b1deb  
    147147        runner.proc = &this;
    148148
    149         sem_init(&idleLock, 0, 0);
     149        idleLock{};
    150150
    151151        start( &this );
     
    155155        if( ! __atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE) ) {
    156156                __cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this);
    157                 terminate(&this);
    158                 verify( __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) );
    159                 verify( kernelTLS.this_processor != &this);
     157
     158                __atomic_store_n(&do_terminate, true, __ATOMIC_RELAXED);
     159                wake( &this );
     160
    160161                P( terminated );
    161162                verify( kernelTLS.this_processor != &this);
    162                 pthread_join( kernel_thread, NULL );
    163         }
    164 
    165         sem_destroy(&idleLock);
     163        }
     164
     165        pthread_join( kernel_thread, NULL );
    166166}
    167167
     
    295295}
    296296
    297 // Handles spinning logic
    298 // TODO : find some strategy to put cores to sleep after some time
    299 void spin(processor * this, unsigned int * spin_count) {
    300         // (*spin_count)++;
    301         halt(this);
    302 }
    303 
    304297// KERNEL_ONLY
    305298// Context invoker for processors
     
    408401                unlock( ready_queue_lock );
    409402
    410                 if( was_empty ) {
     403                if(was_empty) {
    411404                        lock      (proc_list_lock __cfaabi_dbg_ctx2);
    412405                        if(idles) {
    413                                 wake(idles.head);
     406                                wake_fast(idles.head);
    414407                        }
    415408                        unlock    (proc_list_lock);
    416409                }
     410                else if( struct processor * idle = idles.head ) {
     411                        wake_fast(idle);
     412                }
     413
    417414        }
    418415
     
    660657
    661658void halt(processor * this) with( *this ) {
    662         verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) );
     659        // verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) );
    663660
    664661        with( *cltr ) {
     
    671668        __cfaabi_dbg_print_safe("Kernel : Processor %p ready to sleep\n", this);
    672669
    673         // #ifdef __CFA_WITH_VERIFY__
    674         //      int sval = 0;
    675         //      sem_getvalue(&this->idleLock, &sval);
    676         //      verifyf(sval < 200, "Binary semaphore reached value %d : \n", sval);
    677         // #endif
    678 
    679         verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) );
    680         int __attribute__((unused)) ret = sem_wait(&idleLock);
    681         // verifyf(ret >= 0 || errno == EINTR, "Sem_wait returned %d (errno %d : %s\n", ret, errno, strerror(errno));
    682 
    683         // wait( idleLock );
     670        wait( idleLock );
    684671
    685672        __cfaabi_dbg_print_safe("Kernel : Processor %p woke up and ready to run\n", this);
     
    691678                unlock    (proc_list_lock);
    692679        }
    693 }
    694 
    695 void wake(processor * this) {
    696         __cfaabi_dbg_print_safe("Kernel : Waking up processor %p\n", this);
    697         int __attribute__((unused)) ret = sem_post(&this->idleLock);
    698         // verifyf(ret >= 0 || errno == EINTR, "Sem_post returned %d (errno %d : %s\n", ret, errno, strerror(errno));
    699 
    700         // #ifdef __CFA_WITH_VERIFY__
    701         //      int sval = 0;
    702         //      sem_getvalue(&this->idleLock, &sval);
    703         //      verifyf(sval < 200, "Binary semaphore reached value %d\n", sval);
    704         // #endif
    705 
    706         // post( this->idleLock );
    707680}
    708681
  • src/libcfa/concurrency/kernel_private.h

    r08b5a7e r85b1deb  
    5858void finishRunning(processor * this);
    5959void halt(processor * this);
    60 void wake(processor * this);
    61 void terminate(processor * this);
    62 void spin(processor * this, unsigned int * spin_count);
     60
     61static inline void wake_fast(processor * this) {
     62        __cfaabi_dbg_print_safe("Kernel : Waking up processor %p\n", this);
     63        post( this->idleLock );
     64}
     65
     66static inline void wake(processor * this) {
     67        disable_interrupts();
     68        wake_fast(this);
     69        enable_interrupts( __cfaabi_dbg_ctx );
     70}
    6371
    6472struct event_kernel_t {
     
    6876
    6977extern event_kernel_t * event_kernel;
    70 
    71 //extern thread_local coroutine_desc * volatile this_coroutine;
    72 //extern thread_local thread_desc *    volatile this_thread;
    73 //extern thread_local processor *      volatile this_processor;
    74 
    75 // extern volatile thread_local bool preemption_in_progress;
    76 // extern volatile thread_local bool preemption_enabled;
    77 // extern volatile thread_local unsigned short disable_preempt_count;
    7878
    7979struct __cfa_kernel_preemption_state_t {
  • src/libcfa/concurrency/preemption.c

    r08b5a7e r85b1deb  
    260260static void preempt( processor * this ) {
    261261        sigval_t value = { PREEMPT_NORMAL };
    262         pthread_sigqueue( this->kernel_thread, SIGUSR1, value );
    263 }
    264 
    265 // kill wrapper : signal a processor
    266 void terminate(processor * this) {
    267         disable_interrupts();
    268         __atomic_store_n(&this->do_terminate, true, __ATOMIC_SEQ_CST);
    269         wake( this );
    270         sigval_t value = { PREEMPT_TERMINATE };
    271         enable_interrupts( __cfaabi_dbg_ctx );
    272262        pthread_sigqueue( this->kernel_thread, SIGUSR1, value );
    273263}
  • src/tests/preempt_longrun/enter.c

    r08b5a7e r85b1deb  
    1515
    1616monitor mon_t {};
     17void foo( mon_t & mutex this ) {}
    1718
    1819mon_t mon;
    19 
    20 void foo( mon_t & mutex this ) {}
    21 
    2220thread worker_t {};
    23 
    2421void main( worker_t & this ) {
    2522        for( unsigned long i = 0; i < N; i++ ) {
     
    2825}
    2926
    30 extern "C" {
    31 static worker_t * workers;
    32 }
    33 
    3427int main(int argc, char * argv[] ) {
    3528        processor p;
    3629        {
    3730                worker_t w[7];
    38                 workers = w;
    3931        }
    4032}
  • src/tests/preempt_longrun/processor.c

    r08b5a7e r85b1deb  
    1313}
    1414
    15 static const unsigned long N = 5_000ul;
     15static const unsigned long N = 50_000ul;
    1616
    1717int main(int argc, char* argv[]) {
    1818        processor * p[15];
    19         write(STDERR_FILENO, "Preparing\n", sizeof("Preparing\n"));
     19        write(STDOUT_FILENO, "Preparing\n", sizeof("Preparing\n"));
    2020        for ( int pi = 0; pi < 15; pi++ ) {
    2121                p[pi] = new();
    2222        }
    23         write(STDERR_FILENO, "Starting\n", sizeof("Starting\n"));
     23        write(STDOUT_FILENO, "Starting\n", sizeof("Starting\n"));
    2424        for ( int i = 0; i < N; i++) {
    2525                int pi = i % 15;
     
    2727                p[pi] = new();
    2828        }
    29         write(STDERR_FILENO, "Stopping\n", sizeof("Stopping\n"));
     29        write(STDOUT_FILENO, "Stopping\n", sizeof("Stopping\n"));
    3030        for ( int pi = 0; pi < 15; pi++ ) {
    3131                delete( p[pi] );
    3232        }
    33         write(STDERR_FILENO, "Done\n", sizeof("Done\n"));
     33        write(STDOUT_FILENO, "Done\n", sizeof("Done\n"));
    3434}
Note: See TracChangeset for help on using the changeset viewer.