Ignore:
File:
1 edited

Legend:

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

    ra757ba1 r8bee858  
    138138extern bool __cfa_io_drain( processor * proc ) __attribute__((nonnull (1)));
    139139extern bool __cfa_io_flush( processor * ) __attribute__((nonnull (1)));
    140 
     140extern void __cfa_io_idle( processor * ) __attribute__((nonnull (1)));
     141
     142#if defined(CFA_WITH_IO_URING_IDLE)
     143        extern bool __kernel_read(processor * proc, io_future_t & future, iovec &, int fd);
     144#endif
    141145
    142146extern void __disable_interrupts_hard();
     
    158162        verify(this);
    159163
     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
    160171        __cfadbg_print_safe(runtime_core, "Kernel : core %p starting\n", this);
    161172        #if !defined(__CFA_NO_STATISTICS__)
     
    280291        /* paranoid */ verify( ! __preemption_enabled() );
    281292        /* paranoid */ verifyf( thrd_dst->state == Ready || thrd_dst->preempted != __NO_PREEMPTION, "state : %d, preempted %d\n", thrd_dst->state, thrd_dst->preempted);
    282         /* paranoid */ verifyf( thrd_dst->rdy_link.next == 0p, "Expected null got %p", thrd_dst->rdy_link.next );
     293        /* paranoid */ verifyf( thrd_dst->link.next == 0p, "Expected null got %p", thrd_dst->link.next );
    283294        __builtin_prefetch( thrd_dst->context.SP );
    284295
     
    310321                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ) || thrd_dst->curr_cor == proc_cor || thrd_dst->corctx_flag, "ERROR : Destination thread$ %p has been corrupted.\n StackPointer too small.\n", thrd_dst ); // add escape condition if we are setting up the processor
    311322                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit) || thrd_dst->curr_cor == proc_cor || thrd_dst->corctx_flag, "ERROR : Destination thread$ %p has been corrupted.\n StackPointer too large.\n", thrd_dst ); // add escape condition if we are setting up the processor
    312                 /* paranoid */ verify( __atomic_exchange_n( &thrd_dst->executing, this, __ATOMIC_SEQ_CST) == 0p );
    313323                /* paranoid */ verify( 0x0D15EA5E0D15EA5Ep == thrd_dst->canary );
    314324
     
    322332
    323333                /* paranoid */ verify( 0x0D15EA5E0D15EA5Ep == thrd_dst->canary );
    324                 /* paranoid */ verify( __atomic_exchange_n( &thrd_dst->executing, 0p, __ATOMIC_SEQ_CST) == this );
    325334                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit) || thrd_dst->corctx_flag, "ERROR : Destination thread$ %p has been corrupted.\n StackPointer too large.\n", thrd_dst );
    326335                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ) || thrd_dst->corctx_flag, "ERROR : Destination thread$ %p has been corrupted.\n StackPointer too small.\n", thrd_dst );
    327                 /* paranoid */ verify( thrd_dst->state != Halted );
    328336                /* paranoid */ verify( thrd_dst->context.SP );
     337                /* paranoid */ verify( thrd_dst->curr_cluster == this->cltr );
    329338                /* paranoid */ verify( kernelTLS().this_thread == thrd_dst );
    330339                /* paranoid */ verify( ! __preemption_enabled() );
     
    443452                                        "Error preempted thread marked as not currently running, state %d, preemption %d\n", thrd->state, thrd->preempted );
    444453        /* paranoid */ #endif
    445         /* paranoid */ verifyf( thrd->rdy_link.next == 0p, "Expected null got %p", thrd->rdy_link.next );
     454        /* paranoid */ verifyf( thrd->link.next == 0p, "Expected null got %p", thrd->link.next );
    446455        /* paranoid */ verify( 0x0D15EA5E0D15EA5Ep == thrd->canary );
    447456
     
    591600                /* paranoid */ verifyf( ((uintptr_t)thrd->context.SP) < ((uintptr_t)__get_stack(thrd->curr_cor)->base ), "ERROR : thread$ %p has been corrupted.\n StackPointer too small.\n", thrd );
    592601
     602                thrd->state = Halting;
    593603                if( TICKET_RUNNING != thrd->ticket ) { abort( "Thread terminated with pending unpark" ); }
    594604                if( thrd != this->owner ) { abort( "Thread internal monitor has incorrect owner" ); }
    595605                if( this->recursion != 1) { abort( "Thread internal monitor has unbalanced recursion" ); }
    596 
    597                 thrd->state = Halting;
    598                 thrd->ticket = TICKET_DEAD;
    599606
    600607                // Leave the thread
     
    617624                // If that is the case, abandon the preemption.
    618625                bool preempted = false;
    619                 if(thrd->rdy_link.next == 0p) {
     626                if(thrd->link.next == 0p) {
    620627                        preempted = true;
    621628                        thrd->preempted = reason;
     
    719726
    720727
    721         #if !defined(__CFA_NO_STATISTICS__)
    722                 if(this->print_halts) {
    723                         __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl());
    724                 }
    725         #endif
    726 
    727         __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle_fd);
    728 
    729         {
    730                 eventfd_t val;
    731                 ssize_t ret = read( this->idle_wctx.evfd, &val, sizeof(val) );
    732                 if(ret < 0) {
    733                         switch((int)errno) {
    734                         case EAGAIN:
    735                         #if EAGAIN != EWOULDBLOCK
    736                                 case EWOULDBLOCK:
    737                         #endif
    738                         case EINTR:
    739                                 // No need to do anything special here, just assume it's a legitimate wake-up
    740                                 break;
    741                         default:
    742                                 abort( "KERNEL : internal error, read failure on idle eventfd, error(%d) %s.", (int)errno, strerror( (int)errno ) );
     728        #if !defined(CFA_WITH_IO_URING_IDLE)
     729                #if !defined(__CFA_NO_STATISTICS__)
     730                        if(this->print_halts) {
     731                                __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl());
    743732                        }
    744                 }
    745         }
    746 
    747         #if !defined(__CFA_NO_STATISTICS__)
    748                 if(this->print_halts) {
    749                         __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl());
    750                 }
     733                #endif
     734
     735                __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle_fd);
     736
     737                {
     738                        eventfd_t val;
     739                        ssize_t ret = read( this->idle_wctx.evfd, &val, sizeof(val) );
     740                        if(ret < 0) {
     741                                switch((int)errno) {
     742                                case EAGAIN:
     743                                #if EAGAIN != EWOULDBLOCK
     744                                        case EWOULDBLOCK:
     745                                #endif
     746                                case EINTR:
     747                                        // No need to do anything special here, just assume it's a legitimate wake-up
     748                                        break;
     749                                default:
     750                                        abort( "KERNEL : internal error, read failure on idle eventfd, error(%d) %s.", (int)errno, strerror( (int)errno ) );
     751                                }
     752                        }
     753                }
     754
     755                #if !defined(__CFA_NO_STATISTICS__)
     756                        if(this->print_halts) {
     757                                __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl());
     758                        }
     759                #endif
     760        #else
     761                __cfa_io_idle( this );
    751762        #endif
    752763}
     
    764775                insert_first(this.idles, proc);
    765776
    766                 // update the pointer to the head wait context, which should now point to this proc.
    767777                __atomic_store_n(&this.fdw, &proc.idle_wctx, __ATOMIC_SEQ_CST);
    768778        unlock( this );
     
    781791
    782792                {
    783                         // update the pointer to the head wait context
    784793                        struct __fd_waitctx * wctx = 0;
    785794                        if(!this.idles`isEmpty) wctx = &this.idles`first.idle_wctx;
Note: See TracChangeset for help on using the changeset viewer.