380 // assignment. However, casting to E& means that we trigger an |
380 // assignment. However, casting to E& means that we trigger an |
381 // unused-value warning. So, we cast the E& to void. |
381 // unused-value warning. So, we cast the E& to void. |
382 (void)const_cast<E&>(_elems[localBot] = t); |
382 (void)const_cast<E&>(_elems[localBot] = t); |
383 OrderAccess::release_store(&_bottom, increment_index(localBot)); |
383 OrderAccess::release_store(&_bottom, increment_index(localBot)); |
384 TASKQUEUE_STATS_ONLY(stats.record_push()); |
384 TASKQUEUE_STATS_ONLY(stats.record_push()); |
|
385 #ifdef MIPS64 |
|
386 if (Use3A2000) OrderAccess::fence(); |
|
387 #endif |
385 return true; |
388 return true; |
386 } |
389 } |
387 return false; |
390 return false; |
388 } |
391 } |
389 |
392 |
504 bool OverflowTaskQueue<E, F, N>::push(E t) |
507 bool OverflowTaskQueue<E, F, N>::push(E t) |
505 { |
508 { |
506 if (!taskqueue_t::push(t)) { |
509 if (!taskqueue_t::push(t)) { |
507 overflow_stack()->push(t); |
510 overflow_stack()->push(t); |
508 TASKQUEUE_STATS_ONLY(stats.record_overflow(overflow_stack()->size())); |
511 TASKQUEUE_STATS_ONLY(stats.record_overflow(overflow_stack()->size())); |
|
512 #ifdef MIPS64 |
|
513 if (Use3A2000) OrderAccess::fence(); |
|
514 #endif |
509 } |
515 } |
510 return true; |
516 return true; |
511 } |
517 } |
512 |
518 |
513 template <class E, MEMFLAGS F, unsigned int N> |
519 template <class E, MEMFLAGS F, unsigned int N> |
576 template<class T, MEMFLAGS F> bool |
582 template<class T, MEMFLAGS F> bool |
577 GenericTaskQueueSet<T, F>::steal(uint queue_num, int* seed, E& t) { |
583 GenericTaskQueueSet<T, F>::steal(uint queue_num, int* seed, E& t) { |
578 for (uint i = 0; i < 2 * _n; i++) { |
584 for (uint i = 0; i < 2 * _n; i++) { |
579 if (steal_best_of_2(queue_num, seed, t)) { |
585 if (steal_best_of_2(queue_num, seed, t)) { |
580 TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal(true)); |
586 TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal(true)); |
|
587 #ifdef MIPS64 |
|
588 if (Use3A2000) OrderAccess::fence(); |
|
589 #endif |
581 return true; |
590 return true; |
582 } |
591 } |
583 } |
592 } |
584 TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal(false)); |
593 TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal(false)); |
|
594 #ifdef MIPS64 |
|
595 if (Use3A2000) OrderAccess::fence(); |
|
596 #endif |
585 return false; |
597 return false; |
586 } |
598 } |
587 |
599 |
588 template<class T, MEMFLAGS F> bool |
600 template<class T, MEMFLAGS F> bool |
589 GenericTaskQueueSet<T, F>::steal_best_of_2(uint queue_num, int* seed, E& t) { |
601 GenericTaskQueueSet<T, F>::steal_best_of_2(uint queue_num, int* seed, E& t) { |
695 // assignment. However, casting to E& means that we trigger an |
707 // assignment. However, casting to E& means that we trigger an |
696 // unused-value warning. So, we cast the E& to void. |
708 // unused-value warning. So, we cast the E& to void. |
697 (void) const_cast<E&>(_elems[localBot] = t); |
709 (void) const_cast<E&>(_elems[localBot] = t); |
698 OrderAccess::release_store(&_bottom, increment_index(localBot)); |
710 OrderAccess::release_store(&_bottom, increment_index(localBot)); |
699 TASKQUEUE_STATS_ONLY(stats.record_push()); |
711 TASKQUEUE_STATS_ONLY(stats.record_push()); |
|
712 #ifdef MIPS64 |
|
713 if (Use3A2000) OrderAccess::fence(); |
|
714 #endif |
700 return true; |
715 return true; |
701 } else { |
716 } else { |
702 return push_slow(t, dirty_n_elems); |
717 return push_slow(t, dirty_n_elems); |
703 } |
718 } |
704 } |
719 } |