Ignore:
File:
1 edited

Legend:

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

    r6d1790c rac2b598  
    1616#pragma once
    1717
     18#include <stdbool.h>
     19
    1820#include "invoke.h"
    1921#include "time_t.hfa"
    2022#include "coroutine.hfa"
    2123
    22 #include "containers/list.hfa"
    23 
    2424extern "C" {
    25         #include <bits/pthreadtypes.h>
    26         #include <linux/types.h>
     25#include <pthread.h>
     26#include <semaphore.h>
    2727}
    2828
     
    3737void  ?{}(semaphore & this, int count = 1);
    3838void ^?{}(semaphore & this);
    39 bool   P (semaphore & this);
    40 bool   V (semaphore & this);
    41 bool   V (semaphore & this, unsigned count);
     39void   P (semaphore & this);
     40void   V (semaphore & this);
    4241
    4342
     
    4645extern struct cluster * mainCluster;
    4746
    48 // Processor id, required for scheduling threads
    49 struct __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 
     47// Processor
    5848coroutine processorCtx_t {
    5949        struct processor * proc;
     
    6151
    6252// Wrapper around kernel threads
    63 struct __attribute__((aligned(128))) processor {
     53struct processor {
    6454        // Main state
    65         inline __processor_id_t;
     55        // Coroutine ctx who does keeps the state of the processor
     56        struct processorCtx_t runner;
    6657
    6758        // Cluster from which to get threads
    6859        struct cluster * cltr;
    69 
    70         // Set to true to notify the processor should terminate
    71         volatile bool do_terminate;
    72 
    73         // Coroutine ctx who does keeps the state of the processor
    74         struct processorCtx_t runner;
    7560
    7661        // Name of the processor
     
    7964        // Handle to pthreads
    8065        pthread_t kernel_thread;
     66
     67        // RunThread data
     68        // Action to do after a thread is ran
     69        $thread * destroyer;
    8170
    8271        // Preemption data
     
    8776        bool pending_preemption;
    8877
    89         // Idle lock (kernel semaphore)
    90         __bin_sem_t idle;
     78        // Idle lock
     79        __bin_sem_t idleLock;
    9180
    92         // Termination synchronisation (user semaphore)
     81        // Termination
     82        // Set to true to notify the processor should terminate
     83        volatile bool do_terminate;
     84
     85        // Termination synchronisation
    9386        semaphore terminated;
    9487
     
    9790
    9891        // Link lists fields
    99         DLISTED_MGD_IMPL_IN(processor)
    100 
    101         #if !defined(__CFA_NO_STATISTICS__)
    102                 int print_stats;
    103                 bool print_halts;
    104         #endif
     92        struct __dbg_node_proc {
     93                struct processor * next;
     94                struct processor * prev;
     95        } node;
    10596
    10697#ifdef __CFA_DEBUG__
     
    117108static inline void  ?{}(processor & this, const char name[]) { this{name, *mainCluster }; }
    118109
    119 DLISTED_MGD_IMPL_OUT(processor)
    120 
    121 //-----------------------------------------------------------------------------
    122 // I/O
    123 struct __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
    128 struct $io_ctx_thread {
    129         struct __io_data * ring;
    130         single_sem sem;
    131         volatile bool done;
    132         $thread self;
    133 };
    134 
    135 
    136 struct io_context {
    137         $io_ctx_thread thrd;
    138 };
    139 
    140 struct 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 
    150 void  ?{}(io_context_params & this);
    151 
    152 void  ?{}(io_context & this, struct cluster & cl);
    153 void  ?{}(io_context & this, struct cluster & cl, const io_context_params & params);
    154 void ^?{}(io_context & this);
    155 
    156 struct io_cancellation {
    157         __u64 target;
    158 };
    159 
    160 static inline void  ?{}(io_cancellation & this) { this.target = -1u; }
    161 static inline void ^?{}(io_cancellation &) {}
    162 bool cancel(io_cancellation & this);
    163 
    164 //-----------------------------------------------------------------------------
    165 // Cluster Tools
    166 
    167 // Intrusives lanes which are used by the relaxed ready queue
    168 struct __attribute__((aligned(128))) __intrusive_lane_t;
    169 void  ?{}(__intrusive_lane_t & this);
    170 void ^?{}(__intrusive_lane_t & this);
    171 
    172 // Counter used for wether or not the lanes are all empty
    173 struct __attribute__((aligned(128))) __snzi_node_t;
    174 struct __snzi_t {
    175         unsigned mask;
    176         int root;
    177         __snzi_node_t * nodes;
    178 };
    179 
    180 void  ?{}( __snzi_t & this, unsigned depth );
    181 void ^?{}( __snzi_t & this );
    182 
    183 //TODO adjust cache size to ARCHITECTURE
    184 // Structure holding the relaxed ready queue
    185 struct __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 
    203 void  ?{}(__ready_queue_t & this);
    204 void ^?{}(__ready_queue_t & this);
    205 
    206 // Idle Sleep
    207 struct __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 };
     110static inline [processor *&, processor *& ] __get( processor & this ) __attribute__((const)) { return this.node.[next, prev]; }
    220111
    221112//-----------------------------------------------------------------------------
    222113// Cluster
    223 struct __attribute__((aligned(128))) cluster {
     114struct cluster {
     115        // Ready queue locks
     116        __spinlock_t ready_queue_lock;
     117
    224118        // Ready queue for threads
    225         __ready_queue_t ready_queue;
     119        __queue_t($thread) ready_queue;
    226120
    227121        // Name of the cluster
     
    231125        Duration preemption_rate;
    232126
    233         // List of idle processors
    234         __cluster_idles idles;
     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;
    235132
    236133        // List of threads
     
    244141                cluster * prev;
    245142        } 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
    256143};
    257144extern Duration default_preemption();
    258145
    259 void ?{} (cluster & this, const char name[], Duration preemption_rate, unsigned num_io, const io_context_params & io_params);
     146void ?{} (cluster & this, const char name[], Duration preemption_rate);
    260147void ^?{}(cluster & this);
    261148
    262 static inline void ?{} (cluster & this)                                            { io_context_params default_params;    this{"Anonymous Cluster", default_preemption(), 1, default_params}; }
    263 static inline void ?{} (cluster & this, Duration preemption_rate)                  { io_context_params default_params;    this{"Anonymous Cluster", preemption_rate, 1, default_params}; }
    264 static inline void ?{} (cluster & this, const char name[])                         { io_context_params default_params;    this{name, default_preemption(), 1, default_params}; }
    265 static inline void ?{} (cluster & this, unsigned num_io)                           { io_context_params default_params;    this{"Anonymous Cluster", default_preemption(), num_io, default_params}; }
    266 static inline void ?{} (cluster & this, Duration preemption_rate, unsigned num_io) { io_context_params default_params;    this{"Anonymous Cluster", preemption_rate, num_io, default_params}; }
    267 static inline void ?{} (cluster & this, const char name[], unsigned num_io)        { io_context_params default_params;    this{name, default_preemption(), num_io, default_params}; }
    268 static inline void ?{} (cluster & this, const io_context_params & io_params)                                            { this{"Anonymous Cluster", default_preemption(), 1, io_params}; }
    269 static inline void ?{} (cluster & this, Duration preemption_rate, const io_context_params & io_params)                  { this{"Anonymous Cluster", preemption_rate, 1, io_params}; }
    270 static inline void ?{} (cluster & this, const char name[], const io_context_params & io_params)                         { this{name, default_preemption(), 1, io_params}; }
    271 static inline void ?{} (cluster & this, unsigned num_io, const io_context_params & io_params)                           { this{"Anonymous Cluster", default_preemption(), num_io, io_params}; }
    272 static 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}; }
    273 static inline void ?{} (cluster & this, const char name[], unsigned num_io, const io_context_params & io_params)        { this{name, default_preemption(), num_io, io_params}; }
     149static inline void ?{} (cluster & this)                           { this{"Anonymous Cluster", default_preemption()}; }
     150static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate}; }
     151static inline void ?{} (cluster & this, const char name[])        { this{name, default_preemption()}; }
    274152
    275153static inline [cluster *&, cluster *& ] __get( cluster & this ) __attribute__((const)) { return this.node.[next, prev]; }
    276154
    277 static inline struct processor * active_processor() { return publicTLS_get( this_processor ); } // UNSAFE
    278 static 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
     155static inline struct processor * active_processor() { return TL_GET( this_processor ); } // UNSAFE
     156static inline struct cluster   * active_cluster  () { return TL_GET( this_processor )->cltr; }
    293157
    294158// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.