--- old/src/hotspot/share/gc/shared/taskqueue.hpp 2020-01-17 17:08:35.860135673 +0100 +++ new/src/hotspot/share/gc/shared/taskqueue.hpp 2020-01-17 17:08:35.757135678 +0100 @@ -357,7 +357,8 @@ static int randomParkAndMiller(int* seed0); public: // Returns "true" if some TaskQueue in the set contains a task. - virtual bool peek() = 0; + virtual bool peek() = 0; + virtual size_t tasks() = 0; }; template class TaskQueueSetSuperImpl: public CHeapObj, public TaskQueueSetSuper { @@ -389,6 +390,7 @@ bool steal(uint queue_num, int* seed, E& t); bool peek(); + size_t tasks(); uint size() const { return _n; } }; @@ -414,6 +416,16 @@ return false; } +template +size_t GenericTaskQueueSet::tasks() { + size_t n = 0; + for (uint j = 0; j < _n; j++) { + n += _queues[j]->size(); + } + return n; +} + + // When to terminate from the termination protocol. class TerminatorTerminator: public CHeapObj { public: @@ -426,7 +438,7 @@ #undef TRACESPINNING class ParallelTaskTerminator: public StackObj { -private: +protected: uint _n_threads; TaskQueueSetSuper* _queue_set; @@ -462,7 +474,7 @@ // As above, but it also terminates if the should_exit_termination() // method of the terminator parameter returns true. If terminator is // NULL, then it is ignored. - bool offer_termination(TerminatorTerminator* terminator); + virtual bool offer_termination(TerminatorTerminator* terminator); // Reset the terminator, so that it may be reused again. // The caller is responsible for ensuring that this is done