- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/ready_queue.cfa
r1f45c7d re84ab3d 67 67 #endif 68 68 69 static inline struct $thread* try_pop(struct cluster * cltr, unsigned w __STATS(, __stats_readyQ_pop_t & stats));70 static inline struct $thread* try_pop(struct cluster * cltr, unsigned i, unsigned j __STATS(, __stats_readyQ_pop_t & stats));71 static inline struct $thread* search(struct cluster * cltr);69 static inline struct thread$ * try_pop(struct cluster * cltr, unsigned w __STATS(, __stats_readyQ_pop_t & stats)); 70 static inline struct thread$ * try_pop(struct cluster * cltr, unsigned i, unsigned j __STATS(, __stats_readyQ_pop_t & stats)); 71 static inline struct thread$ * search(struct cluster * cltr); 72 72 static inline [unsigned, bool] idx_from_r(unsigned r, unsigned preferred); 73 73 … … 274 274 //----------------------------------------------------------------------- 275 275 #if defined(USE_CPU_WORK_STEALING) 276 __attribute__((hot)) void push(struct cluster * cltr, struct $thread* thrd, bool push_local) with (cltr->ready_queue) {276 __attribute__((hot)) void push(struct cluster * cltr, struct thread$ * thrd, bool push_local) with (cltr->ready_queue) { 277 277 __cfadbg_print_safe(ready_queue, "Kernel : Pushing %p on cluster %p\n", thrd, cltr); 278 278 … … 316 316 317 317 // Pop from the ready queue from a given cluster 318 __attribute__((hot)) $thread* pop_fast(struct cluster * cltr) with (cltr->ready_queue) {318 __attribute__((hot)) thread$ * pop_fast(struct cluster * cltr) with (cltr->ready_queue) { 319 319 /* paranoid */ verify( lanes.count > 0 ); 320 320 /* paranoid */ verify( kernelTLS().this_processor ); … … 345 345 /* paranoid */ verify(lanes.count < 65536); // The following code assumes max 65536 cores. 346 346 /* paranoid */ verify(map.count < 65536); // The following code assumes max 65536 cores. 347 348 if(0 == (__tls_rand() % 10_000)) { 349 proc->rdq.target = __tls_rand() % lanes.count; 347 uint64_t chaos = __tls_rand(); 348 uint64_t high_chaos = (chaos >> 32); 349 uint64_t mid_chaos = (chaos >> 16) & 0xffff; 350 uint64_t low_chaos = chaos & 0xffff; 351 352 unsigned me = map.self; 353 unsigned cpu_chaos = map.start + (mid_chaos % map.count); 354 bool global = cpu_chaos == me; 355 356 if(global) { 357 proc->rdq.target = high_chaos % lanes.count; 350 358 } else { 351 unsigned cpu_chaos = map.start + (__tls_rand() % map.count); 352 proc->rdq.target = (cpu_chaos * READYQ_SHARD_FACTOR) + (__tls_rand() % READYQ_SHARD_FACTOR); 359 proc->rdq.target = (cpu_chaos * READYQ_SHARD_FACTOR) + (low_chaos % READYQ_SHARD_FACTOR); 353 360 /* paranoid */ verify(proc->rdq.target >= (map.start * READYQ_SHARD_FACTOR)); 354 361 /* paranoid */ verify(proc->rdq.target < ((map.start + map.count) * READYQ_SHARD_FACTOR)); … … 364 371 proc->rdq.target = -1u; 365 372 if(lanes.tscs[target].tv < cutoff && ts(lanes.data[target]) < cutoff) { 366 $thread* t = try_pop(cltr, target __STATS(, __tls_stats()->ready.pop.help));373 thread$ * t = try_pop(cltr, target __STATS(, __tls_stats()->ready.pop.help)); 367 374 proc->rdq.last = target; 368 375 if(t) return t; … … 372 379 unsigned last = proc->rdq.last; 373 380 if(last != -1u && lanes.tscs[last].tv < cutoff && ts(lanes.data[last]) < cutoff) { 374 $thread* t = try_pop(cltr, last __STATS(, __tls_stats()->ready.pop.help));381 thread$ * t = try_pop(cltr, last __STATS(, __tls_stats()->ready.pop.help)); 375 382 if(t) return t; 376 383 } … … 382 389 for(READYQ_SHARD_FACTOR) { 383 390 unsigned i = start + (proc->rdq.itr++ % READYQ_SHARD_FACTOR); 384 if( $thread* t = try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.local))) return t;391 if(thread$ * t = try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.local))) return t; 385 392 } 386 393 … … 389 396 } 390 397 391 __attribute__((hot)) struct $thread* pop_slow(struct cluster * cltr) with (cltr->ready_queue) {398 __attribute__((hot)) struct thread$ * pop_slow(struct cluster * cltr) with (cltr->ready_queue) { 392 399 processor * const proc = kernelTLS().this_processor; 393 400 unsigned last = proc->rdq.last; 394 401 if(last != -1u) { 395 struct $thread* t = try_pop(cltr, last __STATS(, __tls_stats()->ready.pop.steal));402 struct thread$ * t = try_pop(cltr, last __STATS(, __tls_stats()->ready.pop.steal)); 396 403 if(t) return t; 397 404 proc->rdq.last = -1u; … … 401 408 return try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.steal)); 402 409 } 403 __attribute__((hot)) struct $thread* pop_search(struct cluster * cltr) {410 __attribute__((hot)) struct thread$ * pop_search(struct cluster * cltr) { 404 411 return search(cltr); 405 412 } … … 428 435 } 429 436 430 __attribute__((hot)) void push(struct cluster * cltr, struct $thread* thrd, bool push_local) with (cltr->ready_queue) {437 __attribute__((hot)) void push(struct cluster * cltr, struct thread$ * thrd, bool push_local) with (cltr->ready_queue) { 431 438 __cfadbg_print_safe(ready_queue, "Kernel : Pushing %p on cluster %p\n", thrd, cltr); 432 439 … … 475 482 476 483 // Pop from the ready queue from a given cluster 477 __attribute__((hot)) $thread* pop_fast(struct cluster * cltr) with (cltr->ready_queue) {484 __attribute__((hot)) thread$ * pop_fast(struct cluster * cltr) with (cltr->ready_queue) { 478 485 /* paranoid */ verify( lanes.count > 0 ); 479 486 /* paranoid */ verify( kernelTLS().this_processor ); … … 499 506 500 507 // try popping from the 2 picked lists 501 struct $thread* thrd = try_pop(cltr, i, j __STATS(, *(locali || localj ? &__tls_stats()->ready.pop.local : &__tls_stats()->ready.pop.help)));508 struct thread$ * thrd = try_pop(cltr, i, j __STATS(, *(locali || localj ? &__tls_stats()->ready.pop.local : &__tls_stats()->ready.pop.help))); 502 509 if(thrd) { 503 510 return thrd; … … 509 516 } 510 517 511 __attribute__((hot)) struct $thread* pop_slow(struct cluster * cltr) { return pop_fast(cltr); }512 __attribute__((hot)) struct $thread* pop_search(struct cluster * cltr) {518 __attribute__((hot)) struct thread$ * pop_slow(struct cluster * cltr) { return pop_fast(cltr); } 519 __attribute__((hot)) struct thread$ * pop_search(struct cluster * cltr) { 513 520 return search(cltr); 514 521 } 515 522 #endif 516 523 #if defined(USE_WORK_STEALING) 517 __attribute__((hot)) void push(struct cluster * cltr, struct $thread* thrd, bool push_local) with (cltr->ready_queue) {524 __attribute__((hot)) void push(struct cluster * cltr, struct thread$ * thrd, bool push_local) with (cltr->ready_queue) { 518 525 __cfadbg_print_safe(ready_queue, "Kernel : Pushing %p on cluster %p\n", thrd, cltr); 519 526 … … 569 576 570 577 // Pop from the ready queue from a given cluster 571 __attribute__((hot)) $thread* pop_fast(struct cluster * cltr) with (cltr->ready_queue) {578 __attribute__((hot)) thread$ * pop_fast(struct cluster * cltr) with (cltr->ready_queue) { 572 579 /* paranoid */ verify( lanes.count > 0 ); 573 580 /* paranoid */ verify( kernelTLS().this_processor ); … … 591 598 const unsigned long long cutoff = proc->rdq.cutoff > bias ? proc->rdq.cutoff - bias : proc->rdq.cutoff; 592 599 if(lanes.tscs[target].tv < cutoff && ts(lanes.data[target]) < cutoff) { 593 $thread* t = try_pop(cltr, target __STATS(, __tls_stats()->ready.pop.help));600 thread$ * t = try_pop(cltr, target __STATS(, __tls_stats()->ready.pop.help)); 594 601 if(t) return t; 595 602 } … … 598 605 for(READYQ_SHARD_FACTOR) { 599 606 unsigned i = proc->rdq.id + (proc->rdq.itr++ % READYQ_SHARD_FACTOR); 600 if( $thread* t = try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.local))) return t;607 if(thread$ * t = try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.local))) return t; 601 608 } 602 609 return 0p; 603 610 } 604 611 605 __attribute__((hot)) struct $thread* pop_slow(struct cluster * cltr) with (cltr->ready_queue) {612 __attribute__((hot)) struct thread$ * pop_slow(struct cluster * cltr) with (cltr->ready_queue) { 606 613 unsigned i = __tls_rand() % lanes.count; 607 614 return try_pop(cltr, i __STATS(, __tls_stats()->ready.pop.steal)); 608 615 } 609 616 610 __attribute__((hot)) struct $thread* pop_search(struct cluster * cltr) with (cltr->ready_queue) {617 __attribute__((hot)) struct thread$ * pop_search(struct cluster * cltr) with (cltr->ready_queue) { 611 618 return search(cltr); 612 619 } … … 621 628 //----------------------------------------------------------------------- 622 629 // try to pop from a lane given by index w 623 static inline struct $thread* try_pop(struct cluster * cltr, unsigned w __STATS(, __stats_readyQ_pop_t & stats)) with (cltr->ready_queue) {630 static inline struct thread$ * try_pop(struct cluster * cltr, unsigned w __STATS(, __stats_readyQ_pop_t & stats)) with (cltr->ready_queue) { 624 631 __STATS( stats.attempt++; ) 625 632 … … 644 651 645 652 // Actually pop the list 646 struct $thread* thrd;653 struct thread$ * thrd; 647 654 unsigned long long tsv; 648 655 [thrd, tsv] = pop(lane); … … 671 678 // try to pop from any lanes making sure you don't miss any threads push 672 679 // before the start of the function 673 static inline struct $thread* search(struct cluster * cltr) with (cltr->ready_queue) {680 static inline struct thread$ * search(struct cluster * cltr) with (cltr->ready_queue) { 674 681 /* paranoid */ verify( lanes.count > 0 ); 675 682 unsigned count = __atomic_load_n( &lanes.count, __ATOMIC_RELAXED ); … … 677 684 for(i; count) { 678 685 unsigned idx = (offset + i) % count; 679 struct $thread* thrd = try_pop(cltr, idx __STATS(, __tls_stats()->ready.pop.search));686 struct thread$ * thrd = try_pop(cltr, idx __STATS(, __tls_stats()->ready.pop.search)); 680 687 if(thrd) { 681 688 return thrd; … … 712 719 //----------------------------------------------------------------------- 713 720 // Given 2 indexes, pick the list with the oldest push an try to pop from it 714 static inline struct $thread* try_pop(struct cluster * cltr, unsigned i, unsigned j __STATS(, __stats_readyQ_pop_t & stats)) with (cltr->ready_queue) {721 static inline struct thread$ * try_pop(struct cluster * cltr, unsigned i, unsigned j __STATS(, __stats_readyQ_pop_t & stats)) with (cltr->ready_queue) { 715 722 // Pick the bet list 716 723 int w = i; … … 847 854 // As long as we can pop from this lane to push the threads somewhere else in the queue 848 855 while(!is_empty(lanes.data[idx])) { 849 struct $thread* thrd;856 struct thread$ * thrd; 850 857 unsigned long long _; 851 858 [thrd, _] = pop(lanes.data[idx]);
Note: See TracChangeset
for help on using the changeset viewer.