Changes in / [a0e7d3c:92b9958]
- Location:
- libcfa/src/concurrency
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel.hfa
ra0e7d3c r92b9958 145 145 void ^?{}(__intrusive_lane_t & this); 146 146 147 // Counter used for wether or not the lanes are all empty 148 struct __attribute__((aligned(128))) __snzi_node_t; 149 struct __snzi_t { 150 unsigned mask; 151 int root; 152 __snzi_node_t * nodes; 153 }; 154 155 void ?{}( __snzi_t & this, unsigned depth ); 156 void ^?{}( __snzi_t & this ); 157 147 158 //TODO adjust cache size to ARCHITECTURE 148 159 // Structure holding the relaxed ready queue 149 160 struct __ready_queue_t { 161 // Data tracking how many/which lanes are used 162 // Aligned to 128 for cache locality 163 __snzi_t snzi; 164 150 165 // Data tracking the actual lanes 151 166 // On a seperate cacheline from the used struct since -
libcfa/src/concurrency/kernel_private.hfa
ra0e7d3c r92b9958 284 284 // Ready-Queue API 285 285 //----------------------------------------------------------------------- 286 // pop thread from the ready queue of a cluster 287 // returns 0p if empty 288 __attribute__((hot)) bool query(struct cluster * cltr); 289 290 //----------------------------------------------------------------------- 286 291 // push thread onto a ready queue for a cluster 287 292 // returns true if the list was previously empty, false otherwise -
libcfa/src/concurrency/ready_queue.cfa
ra0e7d3c r92b9958 17 17 // #define __CFA_DEBUG_PRINT_READY_QUEUE__ 18 18 19 // #define USE_SNZI 19 20 // #define USE_MPSC 20 21 … … 28 29 #include <unistd.h> 29 30 31 #include "snzi.hfa" 30 32 #include "ready_subqueue.hfa" 31 33 … … 200 202 void ^?{}(__ready_queue_t & this) with (this) { 201 203 verify( 1 == lanes.count ); 204 #ifdef USE_SNZI 205 verify( !query( snzi ) ); 206 #endif 202 207 free(lanes.data); 203 208 } 204 209 205 210 //----------------------------------------------------------------------- 211 __attribute__((hot)) bool query(struct cluster * cltr) { 212 #ifdef USE_SNZI 213 return query(cltr->ready_queue.snzi); 214 #endif 215 return true; 216 } 217 206 218 static inline [unsigned, bool] idx_from_r(unsigned r, unsigned preferred) { 207 219 unsigned i; … … 281 293 282 294 // Actually push it 295 #ifdef USE_SNZI 296 bool lane_first = 297 #endif 298 283 299 push(lanes.data[i], thrd); 300 301 #ifdef USE_SNZI 302 // If this lane used to be empty we need to do more 303 if(lane_first) { 304 // Check if the entire queue used to be empty 305 first = !query(snzi); 306 307 // Update the snzi 308 arrive( snzi, i ); 309 } 310 #endif 284 311 285 312 #if !defined(USE_MPSC) … … 324 351 325 352 // As long as the list is not empty, try finding a lane that isn't empty and pop from it 326 for(25) { 353 #ifdef USE_SNZI 354 while( query(snzi) ) { 355 #else 356 for(25) { 357 #endif 327 358 // Pick two lists at random 328 359 // unsigned ri = __tls_rand(); … … 416 447 /* paranoid */ verify(lane.lock); 417 448 449 #ifdef USE_SNZI 450 // If this was the last element in the lane 451 if(emptied) { 452 depart( snzi, w ); 453 } 454 #endif 455 418 456 // Unlock and return 419 457 __atomic_unlock(&lane.lock); … … 446 484 447 485 removed = true; 486 #ifdef USE_SNZI 487 if(emptied) { 488 depart( snzi, i ); 489 } 490 #endif 448 491 } 449 492 __atomic_unlock(&lane.lock); … … 528 571 // grow the ready queue 529 572 with( cltr->ready_queue ) { 573 #ifdef USE_SNZI 574 ^(snzi){}; 575 #endif 576 530 577 // Find new count 531 578 // Make sure we always have atleast 1 list … … 551 598 // Update original 552 599 lanes.count = ncount; 600 601 #ifdef USE_SNZI 602 // Re-create the snzi 603 snzi{ log2( lanes.count / 8 ) }; 604 for( idx; (size_t)lanes.count ) { 605 if( !is_empty(lanes.data[idx]) ) { 606 arrive(snzi, idx); 607 } 608 } 609 #endif 553 610 } 554 611 … … 574 631 575 632 with( cltr->ready_queue ) { 633 #ifdef USE_SNZI 634 ^(snzi){}; 635 #endif 636 576 637 // Remember old count 577 638 size_t ocount = lanes.count; … … 624 685 fix(lanes.data[idx]); 625 686 } 687 688 #ifdef USE_SNZI 689 // Re-create the snzi 690 snzi{ log2( lanes.count / 8 ) }; 691 for( idx; (size_t)lanes.count ) { 692 if( !is_empty(lanes.data[idx]) ) { 693 arrive(snzi, idx); 694 } 695 } 696 #endif 626 697 } 627 698
Note: See TracChangeset
for help on using the changeset viewer.