Changeset 4479890


Ignore:
Timestamp:
Mar 22, 2022, 4:59:53 PM (3 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.

Location:
libcfa/src/concurrency
Files:
5 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;
  • libcfa/src/concurrency/io/types.hfa

    r0521a1a r4479890  
    135135        };
    136136
     137        static inline unsigned long long ts($io_context *& this) {
     138                return this->cq.ts;
     139        }
     140
    137141        struct __pending_alloc {
    138142                inline __outstanding_io;
  • libcfa/src/concurrency/kernel.cfa

    r0521a1a r4479890  
    136136static void mark_awake(__cluster_proc_list & idles, processor & proc);
    137137
    138 extern bool __cfa_io_drain( $io_context *, cluster * cltr );
     138extern bool __cfa_io_drain( processor * proc ) __attribute__((nonnull (1)));
    139139extern bool __cfa_io_flush( processor *, int min_comp );
    140140static inline bool __maybe_io_drain( processor * );
     
    829829
    830830static inline bool __maybe_io_drain( processor * proc ) {
     831        /* paranoid */ verify( proc );
    831832        bool ret = false;
    832833        #if defined(CFA_HAVE_LINUX_IO_URING_H)
     
    839840                if(head == tail) return false;
    840841                ready_schedule_lock();
    841                 ret = __cfa_io_drain( ctx, proc->cltr );
     842                ret = __cfa_io_drain( proc );
    842843                ready_schedule_unlock();
    843844        #endif
  • libcfa/src/concurrency/kernel/cluster.hfa

    r0521a1a r4479890  
    4949static inline unsigned long long calc_cutoff(
    5050        const unsigned long long ctsc,
    51         const processor * proc,
     51        unsigned procid,
    5252        size_t count,
    5353        Data_t * data,
     
    5555        const unsigned shard_factor
    5656) {
    57         unsigned start = proc->rdq.id;
     57        unsigned start = procid;
    5858        unsigned long long max = 0;
    5959        for(i; shard_factor) {
  • libcfa/src/concurrency/ready_queue.cfa

    r0521a1a r4479890  
    139139                /* paranoid */ verify( readyQ.tscs[target].tv != MAX );
    140140                if(target < lanes_count) {
    141                         const unsigned long long cutoff = calc_cutoff(ctsc, proc, lanes_count, cltr->sched.readyQ.data, cltr->sched.readyQ.tscs, __shard_factor.readyq);
     141                        const unsigned long long cutoff = calc_cutoff(ctsc, proc->rdq.id, lanes_count, cltr->sched.readyQ.data, cltr->sched.readyQ.tscs, __shard_factor.readyq);
    142142                        const unsigned long long age = moving_average(ctsc, readyQ.tscs[target].tv, readyQ.tscs[target].ma);
    143143                        __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");
Note: See TracChangeset for help on using the changeset viewer.