Changeset 22f94a4 for libcfa/src/concurrency/kernel.hfa
- Timestamp:
- Aug 11, 2020, 4:40:15 PM (5 years ago)
- 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. - File:
-
- 1 edited
-
libcfa/src/concurrency/kernel.hfa (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel.hfa
r07d867b r22f94a4 16 16 #pragma once 17 17 18 #include <stdbool.h>19 #include <stdint.h>20 21 18 #include "invoke.h" 22 19 #include "time_t.hfa" 23 20 #include "coroutine.hfa" 24 21 22 #include "containers/list.hfa" 23 25 24 extern "C" { 26 #include <pthread.h> 27 #include <semaphore.h> 25 #include <bits/pthreadtypes.h> 28 26 } 29 27 … … 47 45 extern struct cluster * mainCluster; 48 46 49 // Processor 47 // Processor id, required for scheduling threads 48 struct __processor_id_t { 49 unsigned id; 50 51 #if !defined(__CFA_NO_STATISTICS__) 52 struct __stats_t * stats; 53 #endif 54 }; 55 50 56 coroutine processorCtx_t { 51 57 struct processor * proc; … … 53 59 54 60 // Wrapper around kernel threads 55 struct processor {61 struct __attribute__((aligned(128))) processor { 56 62 // 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 57 71 // Coroutine ctx who does keeps the state of the processor 58 72 struct processorCtx_t runner; 59 60 // Cluster from which to get threads61 struct cluster * cltr;62 73 63 74 // Name of the processor … … 81 92 __bin_sem_t idle; 82 93 83 // Termination84 // Set to true to notify the processor should terminate85 volatile bool do_terminate;86 87 94 // Termination synchronisation (user semaphore) 88 95 semaphore terminated; … … 92 99 93 100 // 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 98 107 99 108 #ifdef __CFA_DEBUG__ … … 110 119 static inline void ?{}(processor & this, const char name[]) { this{name, *mainCluster }; } 111 120 112 static inline [processor *&, processor *& ] __get( processor & this ) __attribute__((const)) { return this.node.[next, prev]; } 121 DLISTED_MGD_IMPL_OUT(processor) 113 122 114 123 //----------------------------------------------------------------------------- … … 116 125 struct __io_data; 117 126 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 130 struct $io_ctx_thread { 131 struct __io_data * ring; 132 single_sem sem; 133 volatile bool done; 134 $thread self; 135 }; 136 137 138 struct io_context { 139 $io_ctx_thread thrd; 140 }; 141 142 struct 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 152 void ?{}(io_context_params & this); 153 154 void ?{}(io_context & this, struct cluster & cl); 155 void ?{}(io_context & this, struct cluster & cl, const io_context_params & params); 156 void ^?{}(io_context & this); 157 158 struct io_cancellation { 159 uint32_t target; 160 }; 161 162 static inline void ?{}(io_cancellation & this) { this.target = -1u; } 163 static inline void ^?{}(io_cancellation & this) {} 164 bool cancel(io_cancellation & this); 165 166 //----------------------------------------------------------------------------- 167 // Cluster Tools 168 169 // Intrusives lanes which are used by the relaxed ready queue 170 struct __attribute__((aligned(128))) __intrusive_lane_t; 171 void ?{}(__intrusive_lane_t & this); 172 void ^?{}(__intrusive_lane_t & this); 173 174 // Counter used for wether or not the lanes are all empty 175 struct __attribute__((aligned(128))) __snzi_node_t; 176 struct __snzi_t { 177 unsigned mask; 178 int root; 179 __snzi_node_t * nodes; 180 }; 181 182 void ?{}( __snzi_t & this, unsigned depth ); 183 void ^?{}( __snzi_t & this ); 184 185 //TODO adjust cache size to ARCHITECTURE 186 // Structure holding the relaxed ready queue 187 struct __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 205 void ?{}(__ready_queue_t & this); 206 void ^?{}(__ready_queue_t & this); 207 208 // Idle Sleep 209 struct __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 }; 120 222 121 223 //----------------------------------------------------------------------------- 122 224 // Cluster 123 struct cluster { 124 // Ready queue locks 125 __spinlock_t ready_queue_lock; 126 225 struct __attribute__((aligned(128))) cluster { 127 226 // Ready queue for threads 128 __ queue_t($thread)ready_queue;227 __ready_queue_t ready_queue; 129 228 130 229 // Name of the cluster … … 134 233 Duration preemption_rate; 135 234 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; 141 237 142 238 // List of threads … … 151 247 } node; 152 248 153 struct __io_data * io; 249 struct { 250 io_context * ctxs; 251 unsigned cnt; 252 } io; 154 253 155 254 #if !defined(__CFA_NO_STATISTICS__) 156 bool print_stats; 255 struct __stats_t * stats; 256 int print_stats; 157 257 #endif 158 258 }; 159 259 extern Duration default_preemption(); 160 260 161 void ?{} (cluster & this, const char name[], Duration preemption_rate, int flags);261 void ?{} (cluster & this, const char name[], Duration preemption_rate, unsigned num_io, const io_context_params & io_params); 162 262 void ^?{}(cluster & this); 163 263 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}; } 264 static inline void ?{} (cluster & this) { io_context_params default_params; this{"Anonymous Cluster", default_preemption(), 1, default_params}; } 265 static inline void ?{} (cluster & this, Duration preemption_rate) { io_context_params default_params; this{"Anonymous Cluster", preemption_rate, 1, default_params}; } 266 static inline void ?{} (cluster & this, const char name[]) { io_context_params default_params; this{name, default_preemption(), 1, default_params}; } 267 static inline void ?{} (cluster & this, unsigned num_io) { io_context_params default_params; this{"Anonymous Cluster", default_preemption(), num_io, default_params}; } 268 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}; } 269 static inline void ?{} (cluster & this, const char name[], unsigned num_io) { io_context_params default_params; this{name, default_preemption(), num_io, default_params}; } 270 static inline void ?{} (cluster & this, const io_context_params & io_params) { this{"Anonymous Cluster", default_preemption(), 1, io_params}; } 271 static inline void ?{} (cluster & this, Duration preemption_rate, const io_context_params & io_params) { this{"Anonymous Cluster", preemption_rate, 1, io_params}; } 272 static inline void ?{} (cluster & this, const char name[], const io_context_params & io_params) { this{name, default_preemption(), 1, io_params}; } 273 static inline void ?{} (cluster & this, unsigned num_io, const io_context_params & io_params) { this{"Anonymous Cluster", default_preemption(), num_io, io_params}; } 274 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}; } 275 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}; } 170 276 171 277 static inline [cluster *&, cluster *& ] __get( cluster & this ) __attribute__((const)) { return this.node.[next, prev]; } … … 175 281 176 282 #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; 179 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 ); 180 292 #endif 181 293
Note:
See TracChangeset
for help on using the changeset viewer.