/* * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
// A class that acts as a synchronisation barrier. Workers enter // the barrier and must wait until all other workers have entered // before any of them may leave.
class WorkerThreadsBarrierSync : public StackObj { protected:
Monitor _monitor;
uint _n_workers;
uint _n_completed; bool _should_reset; bool _aborted;
// Set the number of workers that will use the barrier. // Must be called before any of the workers start running. void set_n_workers(uint n_workers);
// Enter the barrier. A worker that enters the barrier will // not be allowed to leave until all other threads have // also entered the barrier or the barrier is aborted. // Returns false if the barrier was aborted. bool enter();
// Aborts the barrier and wakes up any threads waiting for // the barrier to complete. The barrier will remain in the // aborted state until the next call to set_n_workers(). void abort();
};
// A class to manage claiming of subtasks within a group of tasks. The // subtasks will be identified by integer indices, usually elements of an // enumeration type.
class SubTasksDone: public CHeapObj<mtInternal> { volatilebool* _tasks;
uint _n_tasks;
// make sure verification logic is run exactly once to avoid duplicate assertion failures
DEBUG_ONLY(volatilebool _verification_done = false;) void all_tasks_claimed_impl(uint skipped[], size_t skipped_size) NOT_DEBUG_RETURN;
NONCOPYABLE(SubTasksDone);
public: // Initializes "this" to a state in which there are "n" tasks to be // processed, none of the which are originally claimed.
SubTasksDone(uint n);
// Attempt to claim the task "t", returning true if successful, // false if it has already been claimed. The task "t" is required // to be within the range of "this". bool try_claim_task(uint t);
// The calling thread asserts that it has attempted to claim all the tasks // that it will try to claim. Tasks that are meant to be skipped must be // explicitly passed as extra arguments. Every thread in the parallel task // must execute this. template<typename T0, typename... Ts,
ENABLE_IF(Conjunction<std::is_same<T0, Ts>...>::value)> void all_tasks_claimed(T0 first_skipped, Ts... more_skipped) {
static_assert(std::is_convertible<T0, uint>::value, "not convertible");
uint skipped[] = { static_cast<uint>(first_skipped), static_cast<uint>(more_skipped)... };
all_tasks_claimed_impl(skipped, ARRAY_SIZE(skipped));
} // if there are no skipped tasks. void all_tasks_claimed() {
all_tasks_claimed_impl(nullptr, 0);
}
// Destructor.
~SubTasksDone();
};
// As above, but for sequential tasks, i.e. instead of claiming // sub-tasks from a set (possibly an enumeration), claim sub-tasks // in sequential order. This is ideal for claiming dynamically // partitioned tasks (like striding in the parallel remembered // set scanning).
class SequentialSubTasksDone : public CHeapObj<mtInternal> {
uint _num_tasks; // Total number of tasks available. volatile uint _num_claimed; // Number of tasks claimed.
NONCOPYABLE(SequentialSubTasksDone);
public:
SequentialSubTasksDone(uint num_tasks) : _num_tasks(num_tasks), _num_claimed(0) { }
~SequentialSubTasksDone() { // Claiming may try to claim more tasks than there are.
assert(_num_claimed >= _num_tasks, "Claimed %u tasks of %u", _num_claimed, _num_tasks);
}
// Attempt to claim the next unclaimed task in the sequence, // returning true if successful, with t set to the index of the // claimed task. Returns false if there are no more unclaimed tasks // in the sequence. In this case t is undefined. bool try_claim_task(uint& t);
};
#endif// SHARE_GC_SHARED_WORKERUTILS_HPP
Messung V0.5
¤ Dauer der Verarbeitung: 0.28 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.