Mercurial > hg > truffle
comparison src/share/vm/utilities/taskqueue.hpp @ 11198:1e6d5dec4a4e
Merge.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Mon, 05 Aug 2013 13:20:06 +0200 |
parents | ef57c43512d6 |
children | cd25d3be91c5 |
comparison
equal
deleted
inserted
replaced
11197:3479ab380552 | 11198:1e6d5dec4a4e |
---|---|
338 template<class E, MEMFLAGS F, unsigned int N> | 338 template<class E, MEMFLAGS F, unsigned int N> |
339 bool GenericTaskQueue<E, F, N>::push_slow(E t, uint dirty_n_elems) { | 339 bool GenericTaskQueue<E, F, N>::push_slow(E t, uint dirty_n_elems) { |
340 if (dirty_n_elems == N - 1) { | 340 if (dirty_n_elems == N - 1) { |
341 // Actually means 0, so do the push. | 341 // Actually means 0, so do the push. |
342 uint localBot = _bottom; | 342 uint localBot = _bottom; |
343 // g++ complains if the volatile result of the assignment is unused. | 343 // g++ complains if the volatile result of the assignment is |
344 const_cast<E&>(_elems[localBot] = t); | 344 // unused, so we cast the volatile away. We cannot cast directly |
345 // to void, because gcc treats that as not using the result of the | |
346 // assignment. However, casting to E& means that we trigger an | |
347 // unused-value warning. So, we cast the E& to void. | |
348 (void)const_cast<E&>(_elems[localBot] = t); | |
345 OrderAccess::release_store(&_bottom, increment_index(localBot)); | 349 OrderAccess::release_store(&_bottom, increment_index(localBot)); |
346 TASKQUEUE_STATS_ONLY(stats.record_push()); | 350 TASKQUEUE_STATS_ONLY(stats.record_push()); |
347 return true; | 351 return true; |
348 } | 352 } |
349 return false; | 353 return false; |
395 uint n_elems = size(localBot, oldAge.top()); | 399 uint n_elems = size(localBot, oldAge.top()); |
396 if (n_elems == 0) { | 400 if (n_elems == 0) { |
397 return false; | 401 return false; |
398 } | 402 } |
399 | 403 |
400 const_cast<E&>(t = _elems[oldAge.top()]); | 404 // g++ complains if the volatile result of the assignment is |
405 // unused, so we cast the volatile away. We cannot cast directly | |
406 // to void, because gcc treats that as not using the result of the | |
407 // assignment. However, casting to E& means that we trigger an | |
408 // unused-value warning. So, we cast the E& to void. | |
409 (void) const_cast<E&>(t = _elems[oldAge.top()]); | |
401 Age newAge(oldAge); | 410 Age newAge(oldAge); |
402 newAge.increment(); | 411 newAge.increment(); |
403 Age resAge = _age.cmpxchg(newAge, oldAge); | 412 Age resAge = _age.cmpxchg(newAge, oldAge); |
404 | 413 |
405 // Note that using "_bottom" here might fail, since a pop_local might | 414 // Note that using "_bottom" here might fail, since a pop_local might |
638 assert((localBot >= 0) && (localBot < N), "_bottom out of range."); | 647 assert((localBot >= 0) && (localBot < N), "_bottom out of range."); |
639 idx_t top = _age.top(); | 648 idx_t top = _age.top(); |
640 uint dirty_n_elems = dirty_size(localBot, top); | 649 uint dirty_n_elems = dirty_size(localBot, top); |
641 assert(dirty_n_elems < N, "n_elems out of range."); | 650 assert(dirty_n_elems < N, "n_elems out of range."); |
642 if (dirty_n_elems < max_elems()) { | 651 if (dirty_n_elems < max_elems()) { |
643 // g++ complains if the volatile result of the assignment is unused. | 652 // g++ complains if the volatile result of the assignment is |
644 const_cast<E&>(_elems[localBot] = t); | 653 // unused, so we cast the volatile away. We cannot cast directly |
654 // to void, because gcc treats that as not using the result of the | |
655 // assignment. However, casting to E& means that we trigger an | |
656 // unused-value warning. So, we cast the E& to void. | |
657 (void) const_cast<E&>(_elems[localBot] = t); | |
645 OrderAccess::release_store(&_bottom, increment_index(localBot)); | 658 OrderAccess::release_store(&_bottom, increment_index(localBot)); |
646 TASKQUEUE_STATS_ONLY(stats.record_push()); | 659 TASKQUEUE_STATS_ONLY(stats.record_push()); |
647 return true; | 660 return true; |
648 } else { | 661 } else { |
649 return push_slow(t, dirty_n_elems); | 662 return push_slow(t, dirty_n_elems); |
663 localBot = decrement_index(localBot); | 676 localBot = decrement_index(localBot); |
664 _bottom = localBot; | 677 _bottom = localBot; |
665 // This is necessary to prevent any read below from being reordered | 678 // This is necessary to prevent any read below from being reordered |
666 // before the store just above. | 679 // before the store just above. |
667 OrderAccess::fence(); | 680 OrderAccess::fence(); |
668 const_cast<E&>(t = _elems[localBot]); | 681 // g++ complains if the volatile result of the assignment is |
682 // unused, so we cast the volatile away. We cannot cast directly | |
683 // to void, because gcc treats that as not using the result of the | |
684 // assignment. However, casting to E& means that we trigger an | |
685 // unused-value warning. So, we cast the E& to void. | |
686 (void) const_cast<E&>(t = _elems[localBot]); | |
669 // This is a second read of "age"; the "size()" above is the first. | 687 // This is a second read of "age"; the "size()" above is the first. |
670 // If there's still at least one element in the queue, based on the | 688 // If there's still at least one element in the queue, based on the |
671 // "_bottom" and "age" we've read, then there can be no interference with | 689 // "_bottom" and "age" we've read, then there can be no interference with |
672 // a "pop_global" operation, and we're done. | 690 // a "pop_global" operation, and we're done. |
673 idx_t tp = _age.top(); // XXX | 691 idx_t tp = _age.top(); // XXX |