Changes in / [ac6fc48:e21f253]


Ignore:
File:
1 edited

Legend:

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

    rac6fc48 re21f253  
    187187                MAIN_LOOP:
    188188                for() {
     189                        #define OLD_MAIN 1
     190                        #if OLD_MAIN
    189191                        // Check if there is pending io
    190192                        __maybe_io_drain( this );
     
    246248                                __cfa_io_flush( this, 0 );
    247249                        }
     250
     251                        #else
     252                                #warning new kernel loop
     253                        SEARCH: {
     254                                /* paranoid */ verify( ! __preemption_enabled() );
     255
     256                                // First, lock the scheduler since we are searching for a thread
     257                                ready_schedule_lock();
     258
     259                                // Try to get the next thread
     260                                readyThread = pop_fast( this->cltr );
     261                                if(readyThread) { ready_schedule_unlock(); break SEARCH; }
     262
     263                                // If we can't find a thread, might as well flush any outstanding I/O
     264                                if(this->io.pending) { __cfa_io_flush( this, 0 ); }
     265
     266                                // Spin a little on I/O, just in case
     267                                for(5) {
     268                                        __maybe_io_drain( this );
     269                                        readyThread = pop_fast( this->cltr );
     270                                        if(readyThread) { ready_schedule_unlock(); break SEARCH; }
     271                                }
     272
     273                                // no luck, try stealing a few times
     274                                for(5) {
     275                                        if( __maybe_io_drain( this ) ) {
     276                                                readyThread = pop_fast( this->cltr );
     277                                        } else {
     278                                                readyThread = pop_slow( this->cltr );
     279                                        }
     280                                        if(readyThread) { ready_schedule_unlock(); break SEARCH; }
     281                                }
     282
     283                                // still no luck, search for a thread
     284                                readyThread = pop_search( this->cltr );
     285                                if(readyThread) { ready_schedule_unlock(); break SEARCH; }
     286
     287                                // Don't block if we are done
     288                                if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) {
     289                                        ready_schedule_unlock();
     290                                        break MAIN_LOOP;
     291                                }
     292
     293                                __STATS( __tls_stats()->ready.sleep.halts++; )
     294
     295                                // Push self to idle stack
     296                                ready_schedule_unlock();
     297                                if(!mark_idle(this->cltr->procs, * this)) goto SEARCH;
     298                                ready_schedule_lock();
     299
     300                                // Confirm the ready-queue is empty
     301                                __maybe_io_drain( this );
     302                                readyThread = pop_search( this->cltr );
     303                                ready_schedule_unlock();
     304
     305                                if( readyThread ) {
     306                                        // A thread was found, cancel the halt
     307                                        mark_awake(this->cltr->procs, * this);
     308
     309                                        __STATS( __tls_stats()->ready.sleep.cancels++; )
     310
     311                                        // continue the main loop
     312                                        break SEARCH;
     313                                }
     314
     315                                __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl()); )
     316                                __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle_fd);
     317
     318                                {
     319                                        eventfd_t val;
     320                                        ssize_t ret = read( this->idle_fd, &val, sizeof(val) );
     321                                        if(ret < 0) {
     322                                                switch((int)errno) {
     323                                                case EAGAIN:
     324                                                #if EAGAIN != EWOULDBLOCK
     325                                                        case EWOULDBLOCK:
     326                                                #endif
     327                                                case EINTR:
     328                                                        // No need to do anything special here, just assume it's a legitimate wake-up
     329                                                        break;
     330                                                default:
     331                                                        abort( "KERNEL : internal error, read failure on idle eventfd, error(%d) %s.", (int)errno, strerror( (int)errno ) );
     332                                                }
     333                                        }
     334                                }
     335
     336                                        __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl()); )
     337
     338                                // We were woken up, remove self from idle
     339                                mark_awake(this->cltr->procs, * this);
     340
     341                                // DON'T just proceed, start looking again
     342                                continue MAIN_LOOP;
     343                        }
     344
     345                RUN_THREAD:
     346                        /* paranoid */ verify( ! __preemption_enabled() );
     347                        /* paranoid */ verify( readyThread );
     348
     349                        // Reset io dirty bit
     350                        this->io.dirty = false;
     351
     352                        // We found a thread run it
     353                        __run_thread(this, readyThread);
     354
     355                        // Are we done?
     356                        if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
     357
     358                        if(this->io.pending && !this->io.dirty) {
     359                                __cfa_io_flush( this, 0 );
     360                        }
     361
     362                        ready_schedule_lock();
     363                        __maybe_io_drain( this );
     364                        ready_schedule_unlock();
     365                        #endif
    248366                }
    249367
     
    833951                unsigned tail = *ctx->cq.tail;
    834952                if(head == tail) return false;
    835                 ready_schedule_lock();
    836                 ret = __cfa_io_drain( proc );
    837                 ready_schedule_unlock();
     953                #if OLD_MAIN
     954                        ready_schedule_lock();
     955                        ret = __cfa_io_drain( proc );
     956                        ready_schedule_unlock();
     957                #else
     958                        ret = __cfa_io_drain( proc );
     959                #endif
    838960        #endif
    839961        return ret;
Note: See TracChangeset for help on using the changeset viewer.