Ignore:
Timestamp:
Jan 7, 2021, 3:27:00 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
2b4daf2, 64aeca0
Parents:
3c64c668 (diff), eef8dfb (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 park_unpark

File:
1 edited

Legend:

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

    r3c64c668 r58fe85a  
    1616#pragma once
    1717
    18 #include <stdbool.h>
    19 
    2018#include "invoke.h"
    2119#include "time_t.hfa"
    2220#include "coroutine.hfa"
    2321
     22#include "containers/list.hfa"
     23
    2424extern "C" {
    25 #include <pthread.h>
    26 #include <semaphore.h>
     25        #include <bits/pthreadtypes.h>
     26        #include <linux/types.h>
    2727}
    2828
     
    3737void  ?{}(semaphore & this, int count = 1);
    3838void ^?{}(semaphore & this);
    39 void   P (semaphore & this);
    40 void   V (semaphore & this);
     39bool   P (semaphore & this);
     40bool   V (semaphore & this);
     41bool   V (semaphore & this, unsigned count);
    4142
    4243
     
    4546extern struct cluster * mainCluster;
    4647
    47 // Processor
     48// Processor id, required for scheduling threads
     49struct __processor_id_t {
     50        unsigned id:24;
     51        bool full_proc:1;
     52
     53        #if !defined(__CFA_NO_STATISTICS__)
     54                struct __stats_t * stats;
     55        #endif
     56};
     57
    4858coroutine processorCtx_t {
    4959        struct processor * proc;
     
    5161
    5262// Wrapper around kernel threads
    53 struct processor {
     63struct __attribute__((aligned(128))) processor {
    5464        // Main state
     65        inline __processor_id_t;
     66
     67        // Cluster from which to get threads
     68        struct cluster * cltr;
     69
     70        // Set to true to notify the processor should terminate
     71        volatile bool do_terminate;
     72
    5573        // Coroutine ctx who does keeps the state of the processor
    5674        struct processorCtx_t runner;
    5775
    58         // Cluster from which to get threads
    59         struct cluster * cltr;
    60 
    6176        // Name of the processor
    6277        const char * name;
     
    6479        // Handle to pthreads
    6580        pthread_t kernel_thread;
    66 
    67         // RunThread data
    68         // Action to do after a thread is ran
    69         $thread * destroyer;
    7081
    7182        // Preemption data
     
    7687        bool pending_preemption;
    7788
    78         // Idle lock
    79         __bin_sem_t idleLock;
    80 
    81         // Termination
    82         // Set to true to notify the processor should terminate
    83         volatile bool do_terminate;
    84 
    85         // Termination synchronisation
     89        // Idle lock (kernel semaphore)
     90        __bin_sem_t idle;
     91
     92        // Termination synchronisation (user semaphore)
    8693        semaphore terminated;
    8794
     
    9097
    9198        // Link lists fields
    92         struct __dbg_node_proc {
    93                 struct processor * next;
    94                 struct processor * prev;
    95         } node;
     99        DLISTED_MGD_IMPL_IN(processor)
     100
     101        #if !defined(__CFA_NO_STATISTICS__)
     102                int print_stats;
     103                bool print_halts;
     104        #endif
    96105
    97106#ifdef __CFA_DEBUG__
     
    108117static inline void  ?{}(processor & this, const char name[]) { this{name, *mainCluster }; }
    109118
    110 static inline [processor *&, processor *& ] __get( processor & this ) __attribute__((const)) { return this.node.[next, prev]; }
     119DLISTED_MGD_IMPL_OUT(processor)
     120
     121//-----------------------------------------------------------------------------
     122// I/O
     123struct __io_data;
     124
     125// IO poller user-thread
     126// Not using the "thread" keyword because we want to control
     127// more carefully when to start/stop it
     128struct $io_ctx_thread {
     129        struct __io_data * ring;
     130        single_sem sem;
     131        volatile bool done;
     132        $thread self;
     133};
     134
     135
     136struct io_context {
     137        $io_ctx_thread thrd;
     138};
     139
     140struct io_context_params {
     141        int num_entries;
     142        int num_ready;
     143        int submit_aff;
     144        bool eager_submits:1;
     145        bool poller_submits:1;
     146        bool poll_submit:1;
     147        bool poll_complete:1;
     148};
     149
     150void  ?{}(io_context_params & this);
     151
     152void  ?{}(io_context & this, struct cluster & cl);
     153void  ?{}(io_context & this, struct cluster & cl, const io_context_params & params);
     154void ^?{}(io_context & this);
     155
     156struct io_cancellation {
     157        __u64 target;
     158};
     159
     160static inline void  ?{}(io_cancellation & this) { this.target = -1u; }
     161static inline void ^?{}(io_cancellation &) {}
     162bool cancel(io_cancellation & this);
     163
     164//-----------------------------------------------------------------------------
     165// Cluster Tools
     166
     167// Intrusives lanes which are used by the relaxed ready queue
     168struct __attribute__((aligned(128))) __intrusive_lane_t;
     169void  ?{}(__intrusive_lane_t & this);
     170void ^?{}(__intrusive_lane_t & this);
     171
     172// Counter used for wether or not the lanes are all empty
     173struct __attribute__((aligned(128))) __snzi_node_t;
     174struct __snzi_t {
     175        unsigned mask;
     176        int root;
     177        __snzi_node_t * nodes;
     178};
     179
     180void  ?{}( __snzi_t & this, unsigned depth );
     181void ^?{}( __snzi_t & this );
     182
     183//TODO adjust cache size to ARCHITECTURE
     184// Structure holding the relaxed ready queue
     185struct __ready_queue_t {
     186        // Data tracking how many/which lanes are used
     187        // Aligned to 128 for cache locality
     188        __snzi_t snzi;
     189
     190        // Data tracking the actual lanes
     191        // On a seperate cacheline from the used struct since
     192        // used can change on each push/pop but this data
     193        // only changes on shrink/grow
     194        struct {
     195                // Arary of lanes
     196                __intrusive_lane_t * volatile data;
     197
     198                // Number of lanes (empty or not)
     199                volatile size_t count;
     200        } lanes;
     201};
     202
     203void  ?{}(__ready_queue_t & this);
     204void ^?{}(__ready_queue_t & this);
     205
     206// Idle Sleep
     207struct __cluster_idles {
     208        // Spin lock protecting the queue
     209        volatile uint64_t lock;
     210
     211        // Total number of processors
     212        unsigned total;
     213
     214        // Total number of idle processors
     215        unsigned idle;
     216
     217        // List of idle processors
     218        dlist(processor, processor) list;
     219};
    111220
    112221//-----------------------------------------------------------------------------
    113222// Cluster
    114 struct cluster {
    115         // Ready queue locks
    116         __spinlock_t ready_queue_lock;
    117 
     223struct __attribute__((aligned(128))) cluster {
    118224        // Ready queue for threads
    119         __queue_t($thread) ready_queue;
     225        __ready_queue_t ready_queue;
    120226
    121227        // Name of the cluster
     
    125231        Duration preemption_rate;
    126232
    127         // List of processors
    128         __spinlock_t proc_list_lock;
    129         __dllist_t(struct processor) procs;
    130         __dllist_t(struct processor) idles;
    131         unsigned int nprocessors;
     233        // List of idle processors
     234        __cluster_idles idles;
    132235
    133236        // List of threads
     
    141244                cluster * prev;
    142245        } node;
     246
     247        struct {
     248                io_context * ctxs;
     249                unsigned cnt;
     250        } io;
     251
     252        #if !defined(__CFA_NO_STATISTICS__)
     253                struct __stats_t * stats;
     254                int print_stats;
     255        #endif
    143256};
    144257extern Duration default_preemption();
    145258
    146 void ?{} (cluster & this, const char name[], Duration preemption_rate);
     259void ?{} (cluster & this, const char name[], Duration preemption_rate, unsigned num_io, const io_context_params & io_params);
    147260void ^?{}(cluster & this);
    148261
    149 static inline void ?{} (cluster & this)                           { this{"Anonymous Cluster", default_preemption()}; }
    150 static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate}; }
    151 static inline void ?{} (cluster & this, const char name[])        { this{name, default_preemption()}; }
     262static inline void ?{} (cluster & this)                                            { io_context_params default_params;    this{"Anonymous Cluster", default_preemption(), 1, default_params}; }
     263static inline void ?{} (cluster & this, Duration preemption_rate)                  { io_context_params default_params;    this{"Anonymous Cluster", preemption_rate, 1, default_params}; }
     264static inline void ?{} (cluster & this, const char name[])                         { io_context_params default_params;    this{name, default_preemption(), 1, default_params}; }
     265static inline void ?{} (cluster & this, unsigned num_io)                           { io_context_params default_params;    this{"Anonymous Cluster", default_preemption(), num_io, default_params}; }
     266static inline void ?{} (cluster & this, Duration preemption_rate, unsigned num_io) { io_context_params default_params;    this{"Anonymous Cluster", preemption_rate, num_io, default_params}; }
     267static inline void ?{} (cluster & this, const char name[], unsigned num_io)        { io_context_params default_params;    this{name, default_preemption(), num_io, default_params}; }
     268static inline void ?{} (cluster & this, const io_context_params & io_params)                                            { this{"Anonymous Cluster", default_preemption(), 1, io_params}; }
     269static inline void ?{} (cluster & this, Duration preemption_rate, const io_context_params & io_params)                  { this{"Anonymous Cluster", preemption_rate, 1, io_params}; }
     270static inline void ?{} (cluster & this, const char name[], const io_context_params & io_params)                         { this{name, default_preemption(), 1, io_params}; }
     271static inline void ?{} (cluster & this, unsigned num_io, const io_context_params & io_params)                           { this{"Anonymous Cluster", default_preemption(), num_io, io_params}; }
     272static 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}; }
     273static inline void ?{} (cluster & this, const char name[], unsigned num_io, const io_context_params & io_params)        { this{name, default_preemption(), num_io, io_params}; }
    152274
    153275static inline [cluster *&, cluster *& ] __get( cluster & this ) __attribute__((const)) { return this.node.[next, prev]; }
    154276
    155 static inline struct processor * active_processor() { return TL_GET( this_processor ); } // UNSAFE
    156 static inline struct cluster   * active_cluster  () { return TL_GET( this_processor )->cltr; }
     277static inline struct processor * active_processor() { return publicTLS_get( this_processor ); } // UNSAFE
     278static inline struct cluster   * active_cluster  () { return publicTLS_get( this_processor )->cltr; }
     279
     280#if !defined(__CFA_NO_STATISTICS__)
     281        void print_stats_now( cluster & this, int flags );
     282
     283        static inline void print_stats_at_exit( cluster & this, int flags ) {
     284                this.print_stats |= flags;
     285        }
     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 );
     292#endif
    157293
    158294// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.