mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-21 21:33:07 +00:00
8244307: Improve assertions against taskqueue underflow
Added assert_not_underflow. Reviewed-by: tschatzl, sjohanss
This commit is contained in:
parent
7ae3bea212
commit
98d41015ca
@ -202,12 +202,24 @@ protected:
|
||||
// threads attempting to perform the pop_global will all perform the same
|
||||
// CAS, and only one can succeed.) Any stealing thread that reads after
|
||||
// either the increment or decrement will see an empty queue, and will not
|
||||
// join the competitors. The "sz == -1 || sz == N-1" state will not be
|
||||
// modified by concurrent queues, so the owner thread can reset the state to
|
||||
// _bottom == top so subsequent pushes will be performed normally.
|
||||
// join the competitors. The "sz == -1" / "sz == N-1" state will not be
|
||||
// modified by concurrent threads, so the owner thread can reset the state
|
||||
// to _bottom == top so subsequent pushes will be performed normally.
|
||||
return (sz == N - 1) ? 0 : sz;
|
||||
}
|
||||
|
||||
// Assert that we're not in the underflow state where bottom has
|
||||
// been decremented past top, so that _bottom+1 mod N == top. See
|
||||
// the discussion in clean_size.
|
||||
|
||||
void assert_not_underflow(uint bot, uint top) const {
|
||||
assert_not_underflow(dirty_size(bot, top));
|
||||
}
|
||||
|
||||
void assert_not_underflow(uint dirty_size) const {
|
||||
assert(dirty_size != N - 1, "invariant");
|
||||
}
|
||||
|
||||
private:
|
||||
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
|
||||
|
||||
@ -313,6 +325,7 @@ protected:
|
||||
using TaskQueueSuper<N, F>::decrement_index;
|
||||
using TaskQueueSuper<N, F>::dirty_size;
|
||||
using TaskQueueSuper<N, F>::clean_size;
|
||||
using TaskQueueSuper<N, F>::assert_not_underflow;
|
||||
|
||||
public:
|
||||
using TaskQueueSuper<N, F>::max_elems;
|
||||
|
||||
@ -123,7 +123,7 @@ bool GenericTaskQueue<E, F, N>::pop_local_slow(uint localBot, Age oldAge) {
|
||||
Age tempAge = cmpxchg_age(oldAge, newAge);
|
||||
if (tempAge == oldAge) {
|
||||
// We win.
|
||||
assert(dirty_size(localBot, age_top_relaxed()) != N - 1, "sanity");
|
||||
assert_not_underflow(localBot, age_top_relaxed());
|
||||
TASKQUEUE_STATS_ONLY(stats.record_pop_slow());
|
||||
return true;
|
||||
}
|
||||
@ -132,7 +132,7 @@ bool GenericTaskQueue<E, F, N>::pop_local_slow(uint localBot, Age oldAge) {
|
||||
// and top is greater than bottom. Fix this representation of the empty queue
|
||||
// to become the canonical one.
|
||||
set_age_relaxed(newAge);
|
||||
assert(dirty_size(localBot, age_top_relaxed()) != N - 1, "sanity");
|
||||
assert_not_underflow(localBot, age_top_relaxed());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ GenericTaskQueue<E, F, N>::pop_local(E& t, uint threshold) {
|
||||
// resets the size to 0 before the next call (which is sequential,
|
||||
// since this is pop_local.)
|
||||
uint dirty_n_elems = dirty_size(localBot, age_top_relaxed());
|
||||
assert(dirty_n_elems != N - 1, "Shouldn't be possible...");
|
||||
assert_not_underflow(dirty_n_elems);
|
||||
if (dirty_n_elems <= threshold) return false;
|
||||
localBot = decrement_index(localBot);
|
||||
set_bottom_relaxed(localBot);
|
||||
@ -158,7 +158,7 @@ GenericTaskQueue<E, F, N>::pop_local(E& t, uint threshold) {
|
||||
// a "pop_global" operation, and we're done.
|
||||
idx_t tp = age_top_relaxed();
|
||||
if (clean_size(localBot, tp) > 0) {
|
||||
assert(dirty_size(localBot, tp) != N - 1, "sanity");
|
||||
assert_not_underflow(localBot, tp);
|
||||
TASKQUEUE_STATS_ONLY(stats.record_pop());
|
||||
return true;
|
||||
} else {
|
||||
@ -241,7 +241,7 @@ bool GenericTaskQueue<E, F, N>::pop_global(E& t) {
|
||||
|
||||
// Note that using "bottom" here might fail, since a pop_local might
|
||||
// have decremented it.
|
||||
assert(dirty_size(localBot, newAge.top()) != N - 1, "sanity");
|
||||
assert_not_underflow(localBot, newAge.top());
|
||||
return resAge == oldAge;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user