- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/ready_queue.cfa
r39fc03e r1eb239e4 17 17 // #define __CFA_DEBUG_PRINT_READY_QUEUE__ 18 18 19 // #define USE_SNZI 20 19 21 #include "bits/defs.hfa" 20 22 #include "kernel_private.hfa" … … 192 194 void ^?{}(__ready_queue_t & this) with (this) { 193 195 verify( 1 == lanes.count ); 194 verify( !query( snzi ) ); 196 #ifdef USE_SNZI 197 verify( !query( snzi ) ); 198 #endif 195 199 free(lanes.data); 196 200 } … … 198 202 //----------------------------------------------------------------------- 199 203 __attribute__((hot)) bool query(struct cluster * cltr) { 200 return query(cltr->ready_queue.snzi); 204 #ifdef USE_SNZI 205 return query(cltr->ready_queue.snzi); 206 #endif 207 return true; 201 208 } 202 209 … … 262 269 bool lane_first = push(lanes.data[i], thrd); 263 270 264 // If this lane used to be empty we need to do more 265 if(lane_first) { 266 // Check if the entire queue used to be empty 267 first = !query(snzi); 268 269 // Update the snzi 270 arrive( snzi, i ); 271 } 271 #ifdef USE_SNZI 272 // If this lane used to be empty we need to do more 273 if(lane_first) { 274 // Check if the entire queue used to be empty 275 first = !query(snzi); 276 277 // Update the snzi 278 arrive( snzi, i ); 279 } 280 #endif 272 281 273 282 // Unlock and return … … 294 303 __attribute__((hot)) $thread * pop(struct cluster * cltr) with (cltr->ready_queue) { 295 304 /* paranoid */ verify( lanes.count > 0 ); 305 unsigned count = __atomic_load_n( &lanes.count, __ATOMIC_RELAXED ); 296 306 #if defined(BIAS) 297 307 // Don't bother trying locally too much … … 300 310 301 311 // As long as the list is not empty, try finding a lane that isn't empty and pop from it 302 while( query(snzi) ) { 312 #ifdef USE_SNZI 313 while( query(snzi) ) { 314 #else 315 for(25) { 316 #endif 303 317 // Pick two lists at random 304 318 unsigned i,j; … … 336 350 #endif 337 351 338 i %= __atomic_load_n( &lanes.count, __ATOMIC_RELAXED );339 j %= __atomic_load_n( &lanes.count, __ATOMIC_RELAXED );352 i %= count; 353 j %= count; 340 354 341 355 // try popping from the 2 picked lists … … 353 367 } 354 368 369 __attribute__((hot)) struct $thread * pop_slow(struct cluster * cltr) with (cltr->ready_queue) { 370 /* paranoid */ verify( lanes.count > 0 ); 371 unsigned count = __atomic_load_n( &lanes.count, __ATOMIC_RELAXED ); 372 unsigned offset = __tls_rand(); 373 for(i; count) { 374 unsigned idx = (offset + i) % count; 375 struct $thread * thrd = try_pop(cltr, idx); 376 if(thrd) { 377 return thrd; 378 } 379 } 380 381 // All lanes where empty return 0p 382 return 0p; 383 } 384 385 355 386 //----------------------------------------------------------------------- 356 387 // Given 2 indexes, pick the list with the oldest push an try to pop from it … … 394 425 /* paranoid */ verify(lane.lock); 395 426 396 // If this was the last element in the lane 397 if(emptied) { 398 depart( snzi, w ); 399 } 427 #ifdef USE_SNZI 428 // If this was the last element in the lane 429 if(emptied) { 430 depart( snzi, w ); 431 } 432 #endif 400 433 401 434 // Unlock and return … … 430 463 431 464 removed = true; 432 if(emptied) { 433 depart( snzi, i ); 434 } 465 #ifdef USE_SNZI 466 if(emptied) { 467 depart( snzi, i ); 468 } 469 #endif 435 470 } 436 471 __atomic_unlock(&lane.lock); … … 494 529 // grow the ready queue 495 530 with( cltr->ready_queue ) { 496 ^(snzi){}; 531 #ifdef USE_SNZI 532 ^(snzi){}; 533 #endif 497 534 498 535 // Find new count … … 516 553 lanes.count = ncount; 517 554 518 // Re-create the snzi 519 snzi{ log2( lanes.count / 8 ) }; 520 for( idx; (size_t)lanes.count ) { 521 if( !is_empty(lanes.data[idx]) ) { 522 arrive(snzi, idx); 523 } 524 } 555 #ifdef USE_SNZI 556 // Re-create the snzi 557 snzi{ log2( lanes.count / 8 ) }; 558 for( idx; (size_t)lanes.count ) { 559 if( !is_empty(lanes.data[idx]) ) { 560 arrive(snzi, idx); 561 } 562 } 563 #endif 525 564 } 526 565 … … 542 581 543 582 with( cltr->ready_queue ) { 544 ^(snzi){}; 583 #ifdef USE_SNZI 584 ^(snzi){}; 585 #endif 545 586 546 587 // Remember old count … … 596 637 } 597 638 598 // Re-create the snzi 599 snzi{ log2( lanes.count / 8 ) }; 600 for( idx; (size_t)lanes.count ) { 601 if( !is_empty(lanes.data[idx]) ) { 602 arrive(snzi, idx); 603 } 604 } 639 #ifdef USE_SNZI 640 // Re-create the snzi 641 snzi{ log2( lanes.count / 8 ) }; 642 for( idx; (size_t)lanes.count ) { 643 if( !is_empty(lanes.data[idx]) ) { 644 arrive(snzi, idx); 645 } 646 } 647 #endif 605 648 } 606 649
Note: See TracChangeset
for help on using the changeset viewer.