- File:
-
- 1 edited
-
libcfa/src/concurrency/kernel.hfa (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel.hfa
rdca5802 re3fea42 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Dec 4 07:54:51 201913 // Update Count : 1812 // Last Modified On : Tue Feb 4 12:29:26 2020 13 // Update Count : 22 14 14 // 15 15 … … 107 107 // Cluster from which to get threads 108 108 struct cluster * cltr; 109 unsigned int id;110 109 111 110 // Name of the processor … … 151 150 }; 152 151 153 void ?{}(processor & this, const char * name, struct cluster & cltr);152 void ?{}(processor & this, const char name[], struct cluster & cltr); 154 153 void ^?{}(processor & this); 155 154 156 155 static inline void ?{}(processor & this) { this{ "Anonymous Processor", *mainCluster}; } 157 156 static inline void ?{}(processor & this, struct cluster & cltr) { this{ "Anonymous Processor", cltr}; } 158 static inline void ?{}(processor & this, const char * name) { this{name, *mainCluster }; }157 static inline void ?{}(processor & this, const char name[]) { this{name, *mainCluster }; } 159 158 160 159 static inline [processor *&, processor *& ] __get( processor & this ) { 161 160 return this.node.[next, prev]; 162 161 } 163 164 165 //-----------------------------------------------------------------------------166 // Cluster Tools167 168 // Cells use by the reader writer lock169 // while not generic it only relies on a opaque pointer170 struct __processor_id;171 172 // Reader-Writer lock protecting the ready-queue173 // while this lock is mostly generic some aspects174 // have been hard-coded to for the ready-queue for175 // simplicity and performance176 struct __clusterRWLock_t {177 // total cachelines allocated178 unsigned int max;179 180 // cachelines currently in use181 volatile unsigned int alloc;182 183 // cachelines ready to itereate over184 // (!= to alloc when thread is in second half of doregister)185 volatile unsigned int ready;186 187 // writer lock188 volatile bool lock;189 190 // data pointer191 __processor_id * data;192 };193 194 void ?{}(__clusterRWLock_t & this);195 void ^?{}(__clusterRWLock_t & this);196 197 // Intrusives lanes which are used by the relaxed ready queue198 struct __attribute__((aligned(128))) __intrusive_lane_t {199 // spin lock protecting the queue200 volatile bool lock;201 202 // anchor for the head and the tail of the queue203 struct __sentinel_t {204 // Link lists fields205 // instrusive link field for threads206 // must be exactly as in thread_desc207 __thread_desc_link link;208 } before, after;209 210 #if defined(__CFA_WITH_VERIFY__)211 // id of last processor to acquire the lock212 // needed only to check for mutual exclusion violations213 unsigned int last_id;214 215 // number of items on this list216 // needed only to check for deadlocks217 unsigned int count;218 #endif219 220 // Optional statistic counters221 #if !defined(__CFA_NO_SCHED_STATS__)222 struct __attribute__((aligned(64))) {223 // difference between number of push and pops224 ssize_t diff;225 226 // total number of pushes and pops227 size_t push;228 size_t pop ;229 } stat;230 #endif231 };232 233 void ?{}(__intrusive_lane_t & this);234 void ^?{}(__intrusive_lane_t & this);235 236 typedef unsigned long long __cfa_readyQ_mask_t;237 238 // enum {239 // __cfa_ready_queue_mask_size = (64 - sizeof(size_t)) / sizeof(size_t),240 // __cfa_max_ready_queues = __cfa_ready_queue_mask_size * 8 * sizeof(size_t)241 // };242 243 #define __cfa_lane_mask_size ((64 - sizeof(size_t)) / sizeof(__cfa_readyQ_mask_t))244 #define __cfa_max_lanes (__cfa_lane_mask_size * 8 * sizeof(__cfa_readyQ_mask_t))245 246 //TODO adjust cache size to ARCHITECTURE247 // Structure holding the relaxed ready queue248 struct __attribute__((aligned(128))) __ready_queue_t {249 // Data tracking how many/which lanes are used250 // Aligned to 128 for cache locality251 struct {252 // number of non-empty lanes253 volatile size_t count;254 255 // bit mask, set bits indentify which lanes are non-empty256 volatile __cfa_readyQ_mask_t mask[ __cfa_lane_mask_size ];257 } used;258 259 // Data tracking the actual lanes260 // On a seperate cacheline from the used struct since261 // used can change on each push/pop but this data262 // only changes on shrink/grow263 struct __attribute__((aligned(64))) {264 // Arary of lanes265 __intrusive_lane_t * volatile data;266 267 // Number of lanes (empty or not)268 volatile size_t count;269 } lanes;270 271 // Statistics272 #if !defined(__CFA_NO_STATISTICS__)273 __attribute__((aligned(64))) struct {274 struct {275 // Push statistic276 struct {277 // number of attemps at pushing something278 volatile size_t attempt;279 280 // number of successes at pushing281 volatile size_t success;282 } push;283 284 // Pop statistic285 struct {286 // number of reads of the mask287 // picking an empty __cfa_readyQ_mask_t counts here288 // but not as an attempt289 volatile size_t maskrds;290 291 // number of attemps at poping something292 volatile size_t attempt;293 294 // number of successes at poping295 volatile size_t success;296 } pop;297 } pick;298 299 // stats on the "used" struct of the queue300 // tracks average number of queues that are not empty301 // when pushing / poping302 struct {303 volatile size_t value;304 volatile size_t count;305 } used;306 } global_stats;307 308 #endif309 };310 311 void ?{}(__ready_queue_t & this);312 void ^?{}(__ready_queue_t & this);313 162 314 163 //----------------------------------------------------------------------------- … … 316 165 struct cluster { 317 166 // Ready queue locks 318 __ clusterRWLock_t ready_lock;167 __spinlock_t ready_queue_lock; 319 168 320 169 // Ready queue for threads 321 __ ready_queue_tready_queue;170 __queue_t(thread_desc) ready_queue; 322 171 323 172 // Name of the cluster … … 329 178 // List of processors 330 179 __spinlock_t proc_list_lock; 180 __dllist_t(struct processor) procs; 331 181 __dllist_t(struct processor) idles; 182 unsigned int nprocessors; 332 183 333 184 // List of threads … … 344 195 extern Duration default_preemption(); 345 196 346 void ?{} (cluster & this, const char * name, Duration preemption_rate);197 void ?{} (cluster & this, const char name[], Duration preemption_rate); 347 198 void ^?{}(cluster & this); 348 199 349 200 static inline void ?{} (cluster & this) { this{"Anonymous Cluster", default_preemption()}; } 350 201 static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate}; } 351 static inline void ?{} (cluster & this, const char * name) { this{name, default_preemption()}; }202 static inline void ?{} (cluster & this, const char name[]) { this{name, default_preemption()}; } 352 203 353 204 static inline [cluster *&, cluster *& ] __get( cluster & this ) {
Note:
See TracChangeset
for help on using the changeset viewer.