Ignore:
Timestamp:
Mar 22, 2022, 4:59:53 PM (2 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, enum, master, pthread-emulation, qualifiedEnum
Children:
1a567d0
Parents:
0521a1a
Message:

Implemented helping for io drain based on timestamps.

File:
1 edited

Legend:

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

    r0521a1a r4479890  
    9494        extern void __kernel_unpark( thread$ * thrd, unpark_hint );
    9595
    96         bool __cfa_io_drain( $io_context * ctx, cluster * cltr ) {
     96        static bool __cfa_do_drain( $io_context * ctx, cluster * cltr ) {
    9797                /* paranoid */ verify( ! __preemption_enabled() );
    9898                /* paranoid */ verify( ready_schedule_islocked() );
     
    142142
    143143                return true;
     144        }
     145
     146        bool __cfa_io_drain( processor * proc ) {
     147                bool local = false;
     148                bool remote = false;
     149
     150                cluster * const cltr = proc->cltr;
     151                $io_context * const ctx = proc->io.ctx;
     152                /* paranoid */ verify( cltr );
     153                /* paranoid */ verify( ctx );
     154
     155                with(cltr->sched) {
     156                        const size_t ctxs_count = io.count;
     157
     158                        /* paranoid */ verify( ready_schedule_islocked() );
     159                        /* paranoid */ verify( ! __preemption_enabled() );
     160                        /* paranoid */ verify( active_processor() == proc );
     161                        /* paranoid */ verify( __shard_factor.io > 0 );
     162                        /* paranoid */ verify( ctxs_count > 0 );
     163                        /* paranoid */ verify( ctx->cq.id < ctxs_count );
     164
     165                        const unsigned this_cache = cache_id(cltr, ctx->cq.id / __shard_factor.io);
     166                        const unsigned long long ctsc = rdtscl();
     167
     168                        if(proc->io.target == MAX) {
     169                                uint64_t chaos = __tls_rand();
     170                                unsigned ext = chaos & 0xff;
     171                                unsigned other  = (chaos >> 8) % (ctxs_count);
     172
     173                                if(ext < 3 || __atomic_load_n(&caches[other / __shard_factor.io].id, __ATOMIC_RELAXED) == this_cache) {
     174                                        proc->io.target = other;
     175                                }
     176                        }
     177                        else {
     178                                const unsigned target = proc->io.target;
     179                                /* paranoid */ verify( io.tscs[target].tv != MAX );
     180                                if(target < ctxs_count) {
     181                                        const unsigned long long cutoff = calc_cutoff(ctsc, ctx->cq.id, ctxs_count, io.data, io.tscs, __shard_factor.io);
     182                                        const unsigned long long age = moving_average(ctsc, io.tscs[target].tv, io.tscs[target].ma);
     183                                        // __cfadbg_print_safe(ready_queue, "Kernel : Help attempt on %u from %u, age %'llu vs cutoff %'llu, %s\n", target, this, age, cutoff, age > cutoff ? "yes" : "no");
     184                                        if(age > cutoff) {
     185                                                remote = __cfa_do_drain( io.data[target], cltr );
     186                                        }
     187                                }
     188                                proc->io.target = MAX;
     189                        }
     190                }
     191
     192
     193                // Drain the local queue
     194                local = __cfa_do_drain( proc->io.ctx, cltr );
     195
     196                /* paranoid */ verify( ready_schedule_islocked() );
     197                /* paranoid */ verify( ! __preemption_enabled() );
     198                /* paranoid */ verify( active_processor() == proc );
     199                return local || remote;
    144200        }
    145201
     
    189245
    190246                ready_schedule_lock();
    191                 bool ret = __cfa_io_drain( &ctx, cltr );
     247                bool ret = __cfa_io_drain( proc );
    192248                ready_schedule_unlock();
    193249                return ret;
Note: See TracChangeset for help on using the changeset viewer.