Ignore:
Timestamp:
Mar 18, 2022, 12:42:39 PM (2 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, enum, master, pthread-emulation, qualifiedEnum
Children:
0b4ddb71, 51239d1b
Parents:
3bc69f2
Message:

Tentative fix for spurious deadlock in some concurrency tests

File:
1 edited

Legend:

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

    r3bc69f2 r22226e4  
    136136static void mark_awake(__cluster_proc_list & idles, processor & proc);
    137137
    138 extern void __cfa_io_start( processor * );
    139138extern bool __cfa_io_drain( processor * );
    140139extern bool __cfa_io_flush( processor *, int min_comp );
    141 extern void __cfa_io_stop ( processor * );
    142140static inline bool __maybe_io_drain( processor * );
    143141
     
    164162        verify(this);
    165163
    166         io_future_t future; // used for idle sleep when io_uring is present
    167         future.self.ptr = 1p;  // mark it as already fulfilled so we know if there is a pending request or not
    168         eventfd_t idle_val;
    169         iovec idle_iovec = { &idle_val, sizeof(idle_val) };
    170 
    171         __cfa_io_start( this );
     164        /* paranoid */ verify( this->idle_wctx.ftr   != 0p );
     165        /* paranoid */ verify( this->idle_wctx.rdbuf != 0p );
     166
     167        // used for idle sleep when io_uring is present
     168        // mark it as already fulfilled so we know if there is a pending request or not
     169        this->idle_wctx.ftr->self.ptr = 1p;
     170        iovec idle_iovec = { this->idle_wctx.rdbuf, sizeof(eventfd_t) };
    172171
    173172        __cfadbg_print_safe(runtime_core, "Kernel : core %p starting\n", this);
     
    236235                                }
    237236
    238                                 idle_sleep( this, future, idle_iovec );
     237                                idle_sleep( this, *this->idle_wctx.ftr, idle_iovec );
    239238
    240239                                // We were woken up, remove self from idle
     
    264263                __cfadbg_print_safe(runtime_core, "Kernel : core %p stopping\n", this);
    265264        }
    266 
    267         for(int i = 0; !available(future); i++) {
    268                 if(i > 1000) __cfaabi_dbg_write( "ERROR: kernel has bin spinning on a flush after exit loop.\n", 60);
    269                 __cfa_io_flush( this, 1 );
    270         }
    271 
    272         __cfa_io_stop( this );
    273265
    274266        post( this->terminated );
     
    639631
    640632        int fd = 1;
    641         if( __atomic_load_n(&fdp->fd, __ATOMIC_SEQ_CST) != 1 ) {
    642                 fd = __atomic_exchange_n(&fdp->fd, 1, __ATOMIC_RELAXED);
     633        if( __atomic_load_n(&fdp->sem, __ATOMIC_SEQ_CST) != 1 ) {
     634                fd = __atomic_exchange_n(&fdp->sem, 1, __ATOMIC_RELAXED);
    643635        }
    644636
     
    682674        __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this);
    683675
    684         this->idle_wctx.fd = 1;
     676        this->idle_wctx.sem = 1;
    685677
    686678        eventfd_t val;
    687679        val = 1;
    688         eventfd_write( this->idle_fd, val );
     680        eventfd_write( this->idle_wctx.evfd, val );
    689681
    690682        /* paranoid */ verify( ! __preemption_enabled() );
     
    694686        // Tell everyone we are ready to go do sleep
    695687        for() {
    696                 int expected = this->idle_wctx.fd;
     688                int expected = this->idle_wctx.sem;
    697689
    698690                // Someone already told us to wake-up! No time for a nap.
     
    700692
    701693                // Try to mark that we are going to sleep
    702                 if(__atomic_compare_exchange_n(&this->idle_wctx.fd, &expected, this->idle_fd, false,  __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ) {
     694                if(__atomic_compare_exchange_n(&this->idle_wctx.sem, &expected, this->idle_wctx.evfd, false,  __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ) {
    703695                        // Every one agreed, taking a nap
    704696                        break;
     
    718710                {
    719711                        eventfd_t val;
    720                         ssize_t ret = read( this->idle_fd, &val, sizeof(val) );
     712                        ssize_t ret = read( this->idle_wctx.evfd, &val, sizeof(val) );
    721713                        if(ret < 0) {
    722714                                switch((int)errno) {
     
    745737                        reset(future);
    746738
    747                         __kernel_read(this, future, iov, this->idle_fd );
     739                        __kernel_read(this, future, iov, this->idle_wctx.evfd );
    748740                }
    749741
     
    755747        __STATS__(true, ready.sleep.halts++; )
    756748
    757         proc.idle_wctx.fd = 0;
     749        proc.idle_wctx.sem = 0;
    758750
    759751        /* paranoid */ verify( ! __preemption_enabled() );
Note: See TracChangeset for help on using the changeset viewer.