- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel.hfa
rdd4e2d7 r504a7dc 60 60 // Cluster from which to get threads 61 61 struct cluster * cltr; 62 unsigned int id; 62 63 63 64 // Name of the processor … … 92 93 93 94 // Link lists fields 94 struct __dbg_node_ proc{95 structprocessor * next;96 structprocessor * prev;95 struct __dbg_node_cltr { 96 processor * next; 97 processor * prev; 97 98 } node; 98 99 … … 116 117 struct __io_data; 117 118 118 #define CFA_CLUSTER_IO_POLLER_USER_THREAD 1 << 0 // 0x1 119 #define CFA_CLUSTER_IO_POLLER_THREAD_SUBMITS 1 << 1 // 0x2 120 // #define CFA_CLUSTER_IO_POLLER_KERNEL_SIDE 1 << 2 // 0x4 121 #define CFA_CLUSTER_IO_BUFFLEN_OFFSET 16 119 #define CFA_CLUSTER_IO_POLLER_USER_THREAD 1 << 0 120 // #define CFA_CLUSTER_IO_POLLER_KERNEL_SIDE 1 << 1 121 122 123 //----------------------------------------------------------------------------- 124 // Cluster Tools 125 126 // Cells use by the reader writer lock 127 // while not generic it only relies on a opaque pointer 128 struct __processor_id; 129 130 // Reader-Writer lock protecting the ready-queue 131 // while this lock is mostly generic some aspects 132 // have been hard-coded to for the ready-queue for 133 // simplicity and performance 134 struct __clusterRWLock_t { 135 // total cachelines allocated 136 unsigned int max; 137 138 // cachelines currently in use 139 volatile unsigned int alloc; 140 141 // cachelines ready to itereate over 142 // (!= to alloc when thread is in second half of doregister) 143 volatile unsigned int ready; 144 145 // writer lock 146 volatile bool lock; 147 148 // data pointer 149 __processor_id * data; 150 }; 151 152 void ?{}(__clusterRWLock_t & this); 153 void ^?{}(__clusterRWLock_t & this); 154 155 // Intrusives lanes which are used by the relaxed ready queue 156 struct __attribute__((aligned(128))) __intrusive_lane_t { 157 // spin lock protecting the queue 158 volatile bool lock; 159 160 // anchor for the head and the tail of the queue 161 struct __sentinel_t { 162 // Link lists fields 163 // instrusive link field for threads 164 // must be exactly as in $thread 165 __thread_desc_link link; 166 } before, after; 167 168 #if defined(__CFA_WITH_VERIFY__) 169 // id of last processor to acquire the lock 170 // needed only to check for mutual exclusion violations 171 unsigned int last_id; 172 173 // number of items on this list 174 // needed only to check for deadlocks 175 unsigned int count; 176 #endif 177 178 // Optional statistic counters 179 #if !defined(__CFA_NO_SCHED_STATS__) 180 struct __attribute__((aligned(64))) { 181 // difference between number of push and pops 182 ssize_t diff; 183 184 // total number of pushes and pops 185 size_t push; 186 size_t pop ; 187 } stat; 188 #endif 189 }; 190 191 void ?{}(__intrusive_lane_t & this); 192 void ^?{}(__intrusive_lane_t & this); 193 194 typedef unsigned long long __cfa_readyQ_mask_t; 195 196 // enum { 197 // __cfa_ready_queue_mask_size = (64 - sizeof(size_t)) / sizeof(size_t), 198 // __cfa_max_ready_queues = __cfa_ready_queue_mask_size * 8 * sizeof(size_t) 199 // }; 200 201 #define __cfa_lane_mask_size ((64 - sizeof(size_t)) / sizeof(__cfa_readyQ_mask_t)) 202 #define __cfa_max_lanes (__cfa_lane_mask_size * 8 * sizeof(__cfa_readyQ_mask_t)) 203 204 //TODO adjust cache size to ARCHITECTURE 205 // Structure holding the relaxed ready queue 206 struct __attribute__((aligned(128))) __ready_queue_t { 207 // Data tracking how many/which lanes are used 208 // Aligned to 128 for cache locality 209 struct { 210 // number of non-empty lanes 211 volatile size_t count; 212 213 // bit mask, set bits indentify which lanes are non-empty 214 volatile __cfa_readyQ_mask_t mask[ __cfa_lane_mask_size ]; 215 } used; 216 217 // Data tracking the actual lanes 218 // On a seperate cacheline from the used struct since 219 // used can change on each push/pop but this data 220 // only changes on shrink/grow 221 struct __attribute__((aligned(64))) { 222 // Arary of lanes 223 __intrusive_lane_t * volatile data; 224 225 // Number of lanes (empty or not) 226 volatile size_t count; 227 } lanes; 228 229 // Statistics 230 #if !defined(__CFA_NO_STATISTICS__) 231 __attribute__((aligned(64))) struct { 232 struct { 233 // Push statistic 234 struct { 235 // number of attemps at pushing something 236 volatile size_t attempt; 237 238 // number of successes at pushing 239 volatile size_t success; 240 } push; 241 242 // Pop statistic 243 struct { 244 // number of reads of the mask 245 // picking an empty __cfa_readyQ_mask_t counts here 246 // but not as an attempt 247 volatile size_t maskrds; 248 249 // number of attemps at poping something 250 volatile size_t attempt; 251 252 // number of successes at poping 253 volatile size_t success; 254 } pop; 255 } pick; 256 257 // stats on the "used" struct of the queue 258 // tracks average number of queues that are not empty 259 // when pushing / poping 260 struct { 261 volatile size_t value; 262 volatile size_t count; 263 } used; 264 } global_stats; 265 266 #endif 267 }; 268 269 void ?{}(__ready_queue_t & this); 270 void ^?{}(__ready_queue_t & this); 122 271 123 272 //----------------------------------------------------------------------------- … … 125 274 struct cluster { 126 275 // Ready queue locks 127 __ spinlock_t ready_queue_lock;276 __clusterRWLock_t ready_lock; 128 277 129 278 // Ready queue for threads 130 __ queue_t($thread)ready_queue;279 __ready_queue_t ready_queue; 131 280 132 281 // Name of the cluster … … 161 310 extern Duration default_preemption(); 162 311 163 void ?{} (cluster & this, const char name[], Duration preemption_rate, unsignedflags);312 void ?{} (cluster & this, const char name[], Duration preemption_rate, int flags); 164 313 void ^?{}(cluster & this); 165 314 166 static inline void ?{} (cluster & this) 167 static inline void ?{} (cluster & this, Duration preemption_rate) 168 static inline void ?{} (cluster & this, const char name[]) 169 static inline void ?{} (cluster & this, unsignedflags) { this{"Anonymous Cluster", default_preemption(), flags}; }170 static inline void ?{} (cluster & this, Duration preemption_rate, unsignedflags) { this{"Anonymous Cluster", preemption_rate, flags}; }171 static inline void ?{} (cluster & this, const char name[], unsignedflags) { this{name, default_preemption(), flags}; }315 static inline void ?{} (cluster & this) { this{"Anonymous Cluster", default_preemption(), 0}; } 316 static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate, 0}; } 317 static inline void ?{} (cluster & this, const char name[]) { this{name, default_preemption(), 0}; } 318 static inline void ?{} (cluster & this, int flags) { this{"Anonymous Cluster", default_preemption(), flags}; } 319 static inline void ?{} (cluster & this, Duration preemption_rate, int flags) { this{"Anonymous Cluster", preemption_rate, flags}; } 320 static inline void ?{} (cluster & this, const char name[], int flags) { this{name, default_preemption(), flags}; } 172 321 173 322 static inline [cluster *&, cluster *& ] __get( cluster & this ) __attribute__((const)) { return this.node.[next, prev]; }
Note:
See TracChangeset
for help on using the changeset viewer.