Ignore:
Timestamp:
Aug 11, 2020, 4:40:15 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
0d070ca
Parents:
07d867b (diff), 129674b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into new-ast

File:
1 edited

Legend:

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

    r07d867b r22f94a4  
    1616#pragma once
    1717
    18 #include <stdbool.h>
    19 #include <stdint.h>
    20 
    2118#include "invoke.h"
    2219#include "time_t.hfa"
    2320#include "coroutine.hfa"
    2421
     22#include "containers/list.hfa"
     23
    2524extern "C" {
    26 #include <pthread.h>
    27 #include <semaphore.h>
     25#include <bits/pthreadtypes.h>
    2826}
    2927
     
    4745extern struct cluster * mainCluster;
    4846
    49 // Processor
     47// Processor id, required for scheduling threads
     48struct __processor_id_t {
     49        unsigned id;
     50
     51        #if !defined(__CFA_NO_STATISTICS__)
     52                struct __stats_t * stats;
     53        #endif
     54};
     55
    5056coroutine processorCtx_t {
    5157        struct processor * proc;
     
    5359
    5460// Wrapper around kernel threads
    55 struct processor {
     61struct __attribute__((aligned(128))) processor {
    5662        // Main state
     63        inline __processor_id_t;
     64
     65        // Cluster from which to get threads
     66        struct cluster * cltr;
     67
     68        // Set to true to notify the processor should terminate
     69        volatile bool do_terminate;
     70
    5771        // Coroutine ctx who does keeps the state of the processor
    5872        struct processorCtx_t runner;
    59 
    60         // Cluster from which to get threads
    61         struct cluster * cltr;
    6273
    6374        // Name of the processor
     
    8192        __bin_sem_t idle;
    8293
    83         // Termination
    84         // Set to true to notify the processor should terminate
    85         volatile bool do_terminate;
    86 
    8794        // Termination synchronisation (user semaphore)
    8895        semaphore terminated;
     
    9299
    93100        // Link lists fields
    94         struct __dbg_node_proc {
    95                 struct processor * next;
    96                 struct processor * prev;
    97         } node;
     101        DLISTED_MGD_IMPL_IN(processor)
     102
     103        #if !defined(__CFA_NO_STATISTICS__)
     104                int print_stats;
     105                bool print_halts;
     106        #endif
    98107
    99108#ifdef __CFA_DEBUG__
     
    110119static inline void  ?{}(processor & this, const char name[]) { this{name, *mainCluster }; }
    111120
    112 static inline [processor *&, processor *& ] __get( processor & this ) __attribute__((const)) { return this.node.[next, prev]; }
     121DLISTED_MGD_IMPL_OUT(processor)
    113122
    114123//-----------------------------------------------------------------------------
     
    116125struct __io_data;
    117126
    118 #define CFA_CLUSTER_IO_POLLER_USER_THREAD 1 << 0
    119 // #define CFA_CLUSTER_IO_POLLER_KERNEL_SIDE 1 << 1
     127// IO poller user-thread
     128// Not using the "thread" keyword because we want to control
     129// more carefully when to start/stop it
     130struct $io_ctx_thread {
     131        struct __io_data * ring;
     132        single_sem sem;
     133        volatile bool done;
     134        $thread self;
     135};
     136
     137
     138struct io_context {
     139        $io_ctx_thread thrd;
     140};
     141
     142struct io_context_params {
     143        int num_entries;
     144        int num_ready;
     145        int submit_aff;
     146        bool eager_submits:1;
     147        bool poller_submits:1;
     148        bool poll_submit:1;
     149        bool poll_complete:1;
     150};
     151
     152void  ?{}(io_context_params & this);
     153
     154void  ?{}(io_context & this, struct cluster & cl);
     155void  ?{}(io_context & this, struct cluster & cl, const io_context_params & params);
     156void ^?{}(io_context & this);
     157
     158struct io_cancellation {
     159        uint32_t target;
     160};
     161
     162static inline void  ?{}(io_cancellation & this) { this.target = -1u; }
     163static inline void ^?{}(io_cancellation & this) {}
     164bool cancel(io_cancellation & this);
     165
     166//-----------------------------------------------------------------------------
     167// Cluster Tools
     168
     169// Intrusives lanes which are used by the relaxed ready queue
     170struct __attribute__((aligned(128))) __intrusive_lane_t;
     171void  ?{}(__intrusive_lane_t & this);
     172void ^?{}(__intrusive_lane_t & this);
     173
     174// Counter used for wether or not the lanes are all empty
     175struct __attribute__((aligned(128))) __snzi_node_t;
     176struct __snzi_t {
     177        unsigned mask;
     178        int root;
     179        __snzi_node_t * nodes;
     180};
     181
     182void  ?{}( __snzi_t & this, unsigned depth );
     183void ^?{}( __snzi_t & this );
     184
     185//TODO adjust cache size to ARCHITECTURE
     186// Structure holding the relaxed ready queue
     187struct __ready_queue_t {
     188        // Data tracking how many/which lanes are used
     189        // Aligned to 128 for cache locality
     190        __snzi_t snzi;
     191
     192        // Data tracking the actual lanes
     193        // On a seperate cacheline from the used struct since
     194        // used can change on each push/pop but this data
     195        // only changes on shrink/grow
     196        struct {
     197                // Arary of lanes
     198                __intrusive_lane_t * volatile data;
     199
     200                // Number of lanes (empty or not)
     201                volatile size_t count;
     202        } lanes;
     203};
     204
     205void  ?{}(__ready_queue_t & this);
     206void ^?{}(__ready_queue_t & this);
     207
     208// Idle Sleep
     209struct __cluster_idles {
     210        // Spin lock protecting the queue
     211        volatile uint64_t lock;
     212
     213        // Total number of processors
     214        unsigned total;
     215
     216        // Total number of idle processors
     217        unsigned idle;
     218
     219        // List of idle processors
     220        dlist(processor, processor) list;
     221};
    120222
    121223//-----------------------------------------------------------------------------
    122224// Cluster
    123 struct cluster {
    124         // Ready queue locks
    125         __spinlock_t ready_queue_lock;
    126 
     225struct __attribute__((aligned(128))) cluster {
    127226        // Ready queue for threads
    128         __queue_t($thread) ready_queue;
     227        __ready_queue_t ready_queue;
    129228
    130229        // Name of the cluster
     
    134233        Duration preemption_rate;
    135234
    136         // List of processors
    137         __spinlock_t idle_lock;
    138         __dllist_t(struct processor) procs;
    139         __dllist_t(struct processor) idles;
    140         unsigned int nprocessors;
     235        // List of idle processors
     236        __cluster_idles idles;
    141237
    142238        // List of threads
     
    151247        } node;
    152248
    153         struct __io_data * io;
     249        struct {
     250                io_context * ctxs;
     251                unsigned cnt;
     252        } io;
    154253
    155254        #if !defined(__CFA_NO_STATISTICS__)
    156                 bool print_stats;
     255                struct __stats_t * stats;
     256                int print_stats;
    157257        #endif
    158258};
    159259extern Duration default_preemption();
    160260
    161 void ?{} (cluster & this, const char name[], Duration preemption_rate, int flags);
     261void ?{} (cluster & this, const char name[], Duration preemption_rate, unsigned num_io, const io_context_params & io_params);
    162262void ^?{}(cluster & this);
    163263
    164 static inline void ?{} (cluster & this)                                      { this{"Anonymous Cluster", default_preemption(), 0}; }
    165 static inline void ?{} (cluster & this, Duration preemption_rate)            { this{"Anonymous Cluster", preemption_rate, 0}; }
    166 static inline void ?{} (cluster & this, const char name[])                   { this{name, default_preemption(), 0}; }
    167 static inline void ?{} (cluster & this, int flags)                           { this{"Anonymous Cluster", default_preemption(), flags}; }
    168 static inline void ?{} (cluster & this, Duration preemption_rate, int flags) { this{"Anonymous Cluster", preemption_rate, flags}; }
    169 static inline void ?{} (cluster & this, const char name[], int flags)        { this{name, default_preemption(), flags}; }
     264static inline void ?{} (cluster & this)                                            { io_context_params default_params;    this{"Anonymous Cluster", default_preemption(), 1, default_params}; }
     265static inline void ?{} (cluster & this, Duration preemption_rate)                  { io_context_params default_params;    this{"Anonymous Cluster", preemption_rate, 1, default_params}; }
     266static inline void ?{} (cluster & this, const char name[])                         { io_context_params default_params;    this{name, default_preemption(), 1, default_params}; }
     267static inline void ?{} (cluster & this, unsigned num_io)                           { io_context_params default_params;    this{"Anonymous Cluster", default_preemption(), num_io, default_params}; }
     268static inline void ?{} (cluster & this, Duration preemption_rate, unsigned num_io) { io_context_params default_params;    this{"Anonymous Cluster", preemption_rate, num_io, default_params}; }
     269static inline void ?{} (cluster & this, const char name[], unsigned num_io)        { io_context_params default_params;    this{name, default_preemption(), num_io, default_params}; }
     270static inline void ?{} (cluster & this, const io_context_params & io_params)                                            { this{"Anonymous Cluster", default_preemption(), 1, io_params}; }
     271static inline void ?{} (cluster & this, Duration preemption_rate, const io_context_params & io_params)                  { this{"Anonymous Cluster", preemption_rate, 1, io_params}; }
     272static inline void ?{} (cluster & this, const char name[], const io_context_params & io_params)                         { this{name, default_preemption(), 1, io_params}; }
     273static inline void ?{} (cluster & this, unsigned num_io, const io_context_params & io_params)                           { this{"Anonymous Cluster", default_preemption(), num_io, io_params}; }
     274static inline void ?{} (cluster & this, Duration preemption_rate, unsigned num_io, const io_context_params & io_params) { this{"Anonymous Cluster", preemption_rate, num_io, io_params}; }
     275static inline void ?{} (cluster & this, const char name[], unsigned num_io, const io_context_params & io_params)        { this{name, default_preemption(), num_io, io_params}; }
    170276
    171277static inline [cluster *&, cluster *& ] __get( cluster & this ) __attribute__((const)) { return this.node.[next, prev]; }
     
    175281
    176282#if !defined(__CFA_NO_STATISTICS__)
    177         static inline void print_stats_at_exit( cluster & this ) {
    178                 this.print_stats = true;
     283        static inline void print_stats_at_exit( cluster & this, int flags ) {
     284                this.print_stats |= flags;
    179285        }
     286
     287        static inline void print_stats_at_exit( processor & this, int flags ) {
     288                this.print_stats |= flags;
     289        }
     290
     291        void print_halts( processor & this );
    180292#endif
    181293
Note: See TracChangeset for help on using the changeset viewer.