Ignore:
Timestamp:
Mar 28, 2022, 4:00:32 PM (2 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, enum, master, pthread-emulation, qualifiedEnum
Children:
37a3aa23
Parents:
2377ca2
Message:

Refactored io to allow holding the lock duirng idle sleep

File:
1 edited

Legend:

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

    r2377ca2 r18f7858  
    132132static void __wake_one(cluster * cltr);
    133133
    134 static void idle_sleep(processor * proc, io_future_t & future, iovec & iov);
     134static void idle_sleep(processor * proc);
    135135static bool mark_idle (__cluster_proc_list & idles, processor & proc);
    136136static void mark_awake(__cluster_proc_list & idles, processor & proc);
    137137
    138138extern bool __cfa_io_drain( processor * proc ) __attribute__((nonnull (1)));
    139 extern bool __cfa_io_flush( processor *, int min_comp );
    140 static inline bool __maybe_io_drain( processor * );
     139extern bool __cfa_io_flush( processor * ) __attribute__((nonnull (1)));
     140extern void __cfa_io_idle( processor * ) __attribute__((nonnull (1)));
    141141
    142142#if defined(CFA_WITH_IO_URING_IDLE)
     
    168168        // mark it as already fulfilled so we know if there is a pending request or not
    169169        this->idle_wctx.ftr->self.ptr = 1p;
    170         iovec idle_iovec = { this->idle_wctx.rdbuf, sizeof(eventfd_t) };
    171170
    172171        __cfadbg_print_safe(runtime_core, "Kernel : core %p starting\n", this);
     
    193192                for() {
    194193                        // Check if there is pending io
    195                         __maybe_io_drain( this );
     194                        __cfa_io_drain( this );
    196195
    197196                        // Try to get the next thread
     
    199198
    200199                        if( !readyThread ) {
     200                                // there is no point in holding submissions if we are idle
    201201                                __IO_STATS__(true, io.flush.idle++; )
    202                                 __cfa_io_flush( this, 0 );
     202                                __cfa_io_flush( this );
     203
     204                                // drain again in case something showed up
     205                                __cfa_io_drain( this );
    203206
    204207                                readyThread = __next_thread( this->cltr );
     
    206209
    207210                        if( !readyThread ) for(5) {
     211                                readyThread = __next_thread_slow( this->cltr );
     212
     213                                if( readyThread ) break;
     214
     215                                // It's unlikely we still I/O to submit, but the arbiter could
    208216                                __IO_STATS__(true, io.flush.idle++; )
    209 
    210                                 readyThread = __next_thread_slow( this->cltr );
    211 
    212                                 if( readyThread ) break;
    213 
    214                                 __cfa_io_flush( this, 0 );
     217                                __cfa_io_flush( this );
     218
     219                                // drain again in case something showed up
     220                                __cfa_io_drain( this );
    215221                        }
    216222
     
    235241                                }
    236242
    237                                 idle_sleep( this, *this->idle_wctx.ftr, idle_iovec );
     243                                idle_sleep( this );
    238244
    239245                                // We were woken up, remove self from idle
     
    257263                        if(__atomic_load_n(&this->io.pending, __ATOMIC_RELAXED) && !__atomic_load_n(&this->io.dirty, __ATOMIC_RELAXED)) {
    258264                                __IO_STATS__(true, io.flush.dirty++; )
    259                                 __cfa_io_flush( this, 0 );
     265                                __cfa_io_flush( this );
    260266                        }
    261267                }
     
    683689}
    684690
    685 static void idle_sleep(processor * this, io_future_t & future, iovec & iov) {
     691static void idle_sleep(processor * this) {
    686692        /* paranoid */ verify( this->idle_wctx.evfd != 1 );
    687693        /* paranoid */ verify( this->idle_wctx.evfd != 2 );
     
    735741                #endif
    736742        #else
    737                 // Do we already have a pending read
    738                 if(available(future)) {
    739                         // There is no pending read, we need to add one
    740                         reset(future);
    741 
    742                         __kernel_read(this, future, iov, this->idle_wctx.evfd );
    743                 }
    744 
    745                 __cfa_io_flush( this, 1 );
     743                __cfa_io_idle( this );
    746744        #endif
    747745}
     
    831829#endif
    832830
    833 static inline bool __maybe_io_drain( processor * proc ) {
    834         /* paranoid */ verify( proc );
    835         bool ret = false;
    836         #if defined(CFA_HAVE_LINUX_IO_URING_H)
    837                 __cfadbg_print_safe(runtime_core, "Kernel : core %p checking io for ring %d\n", proc, proc->io.ctx->fd);
    838 
    839                 // Check if we should drain the queue
    840                 $io_context * ctx = proc->io.ctx;
    841                 unsigned head = *ctx->cq.head;
    842                 unsigned tail = *ctx->cq.tail;
    843                 if(head == tail) return false;
    844                 ready_schedule_lock();
    845                 ret = __cfa_io_drain( proc );
    846                 ready_schedule_unlock();
    847         #endif
    848         return ret;
    849 }
     831
    850832
    851833//-----------------------------------------------------------------------------
Note: See TracChangeset for help on using the changeset viewer.