mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 22:34:27 +02:00
8264788: Make SequentialSubTasksDone use-once
Reviewed-by: ayang, sjohanss
This commit is contained in:
parent
0793fcbbca
commit
125a8479a9
5 changed files with 23 additions and 91 deletions
|
@ -2056,18 +2056,15 @@ public:
|
||||||
MarkFromRootsTask(uint active_workers) :
|
MarkFromRootsTask(uint active_workers) :
|
||||||
AbstractGangTask("MarkFromRootsTask"),
|
AbstractGangTask("MarkFromRootsTask"),
|
||||||
_strong_roots_scope(active_workers),
|
_strong_roots_scope(active_workers),
|
||||||
_subtasks(),
|
_subtasks(ParallelRootType::sentinel),
|
||||||
_terminator(active_workers, ParCompactionManager::oop_task_queues()),
|
_terminator(active_workers, ParCompactionManager::oop_task_queues()),
|
||||||
_active_workers(active_workers) {
|
_active_workers(active_workers) {
|
||||||
_subtasks.set_n_threads(active_workers);
|
|
||||||
_subtasks.set_n_tasks(ParallelRootType::sentinel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void work(uint worker_id) {
|
virtual void work(uint worker_id) {
|
||||||
for (uint task = 0; _subtasks.try_claim_task(task); /*empty*/ ) {
|
for (uint task = 0; _subtasks.try_claim_task(task); /*empty*/ ) {
|
||||||
mark_from_roots_work(static_cast<ParallelRootType::Value>(task), worker_id);
|
mark_from_roots_work(static_cast<ParallelRootType::Value>(task), worker_id);
|
||||||
}
|
}
|
||||||
_subtasks.all_tasks_completed();
|
|
||||||
|
|
||||||
PCAddThreadRootsMarkingTaskClosure closure(worker_id);
|
PCAddThreadRootsMarkingTaskClosure closure(worker_id);
|
||||||
Threads::possibly_parallel_threads_do(true /*parallel */, &closure);
|
Threads::possibly_parallel_threads_do(true /*parallel */, &closure);
|
||||||
|
|
|
@ -304,14 +304,12 @@ public:
|
||||||
bool is_empty) :
|
bool is_empty) :
|
||||||
AbstractGangTask("ScavengeRootsTask"),
|
AbstractGangTask("ScavengeRootsTask"),
|
||||||
_strong_roots_scope(active_workers),
|
_strong_roots_scope(active_workers),
|
||||||
_subtasks(),
|
_subtasks(ParallelRootType::sentinel),
|
||||||
_old_gen(old_gen),
|
_old_gen(old_gen),
|
||||||
_gen_top(gen_top),
|
_gen_top(gen_top),
|
||||||
_active_workers(active_workers),
|
_active_workers(active_workers),
|
||||||
_is_empty(is_empty),
|
_is_empty(is_empty),
|
||||||
_terminator(active_workers, PSPromotionManager::vm_thread_promotion_manager()->stack_array_depth()) {
|
_terminator(active_workers, PSPromotionManager::vm_thread_promotion_manager()->stack_array_depth()) {
|
||||||
_subtasks.set_n_threads(active_workers);
|
|
||||||
_subtasks.set_n_tasks(ParallelRootType::sentinel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void work(uint worker_id) {
|
virtual void work(uint worker_id) {
|
||||||
|
@ -346,7 +344,6 @@ public:
|
||||||
for (uint root_type = 0; _subtasks.try_claim_task(root_type); /* empty */ ) {
|
for (uint root_type = 0; _subtasks.try_claim_task(root_type); /* empty */ ) {
|
||||||
scavenge_roots_work(static_cast<ParallelRootType::Value>(root_type), worker_id);
|
scavenge_roots_work(static_cast<ParallelRootType::Value>(root_type), worker_id);
|
||||||
}
|
}
|
||||||
_subtasks.all_tasks_completed();
|
|
||||||
|
|
||||||
PSThreadRootsTaskClosure closure(worker_id);
|
PSThreadRootsTaskClosure closure(worker_id);
|
||||||
Threads::possibly_parallel_threads_do(true /*parallel */, &closure);
|
Threads::possibly_parallel_threads_do(true /*parallel */, &closure);
|
||||||
|
|
|
@ -104,18 +104,15 @@ public:
|
||||||
while (_sub_tasks.try_claim_task(/* reference */ task_id)) {
|
while (_sub_tasks.try_claim_task(/* reference */ task_id)) {
|
||||||
_preserved_marks_set->get(task_id)->restore_and_increment(_total_size_addr);
|
_preserved_marks_set->get(task_id)->restore_and_increment(_total_size_addr);
|
||||||
}
|
}
|
||||||
_sub_tasks.all_tasks_completed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ParRestoreTask(uint worker_num,
|
ParRestoreTask(PreservedMarksSet* preserved_marks_set,
|
||||||
PreservedMarksSet* preserved_marks_set,
|
|
||||||
volatile size_t* total_size_addr)
|
volatile size_t* total_size_addr)
|
||||||
: AbstractGangTask("Parallel Preserved Mark Restoration"),
|
: AbstractGangTask("Parallel Preserved Mark Restoration"),
|
||||||
_preserved_marks_set(preserved_marks_set),
|
_preserved_marks_set(preserved_marks_set),
|
||||||
|
_sub_tasks(preserved_marks_set->num()),
|
||||||
_total_size_addr(total_size_addr) {
|
_total_size_addr(total_size_addr) {
|
||||||
_sub_tasks.set_n_threads(worker_num);
|
}
|
||||||
_sub_tasks.set_n_tasks(preserved_marks_set->num());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void PreservedMarksSet::restore(WorkGang* workers) {
|
void PreservedMarksSet::restore(WorkGang* workers) {
|
||||||
|
@ -127,7 +124,7 @@ void PreservedMarksSet::restore(WorkGang* workers) {
|
||||||
for (uint i = 0; i < _num; i += 1) {
|
for (uint i = 0; i < _num; i += 1) {
|
||||||
total_size_before += get(i)->size();
|
total_size_before += get(i)->size();
|
||||||
}
|
}
|
||||||
#endif // def ASSERT
|
#endif // ASSERT
|
||||||
|
|
||||||
if (workers == NULL) {
|
if (workers == NULL) {
|
||||||
for (uint i = 0; i < num(); i += 1) {
|
for (uint i = 0; i < num(); i += 1) {
|
||||||
|
@ -135,7 +132,7 @@ void PreservedMarksSet::restore(WorkGang* workers) {
|
||||||
get(i)->restore();
|
get(i)->restore();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ParRestoreTask task(workers->active_workers(), this, &total_size);
|
ParRestoreTask task(this, &total_size);
|
||||||
workers->run_task(&task);
|
workers->run_task(&task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -399,39 +399,10 @@ SubTasksDone::~SubTasksDone() {
|
||||||
|
|
||||||
// *** SequentialSubTasksDone
|
// *** SequentialSubTasksDone
|
||||||
|
|
||||||
void SequentialSubTasksDone::clear() {
|
|
||||||
_n_tasks = _n_claimed = 0;
|
|
||||||
_n_threads = _n_completed = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SequentialSubTasksDone::valid() {
|
|
||||||
return _n_threads > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SequentialSubTasksDone::try_claim_task(uint& t) {
|
bool SequentialSubTasksDone::try_claim_task(uint& t) {
|
||||||
t = _n_claimed;
|
t = _num_claimed;
|
||||||
while (t < _n_tasks) {
|
if (t < _num_tasks) {
|
||||||
uint res = Atomic::cmpxchg(&_n_claimed, t, t+1);
|
t = Atomic::add(&_num_claimed, 1u) - 1;
|
||||||
if (res == t) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
t = res;
|
|
||||||
}
|
}
|
||||||
return false;
|
return t < _num_tasks;
|
||||||
}
|
|
||||||
|
|
||||||
bool SequentialSubTasksDone::all_tasks_completed() {
|
|
||||||
uint complete = _n_completed;
|
|
||||||
while (true) {
|
|
||||||
uint res = Atomic::cmpxchg(&_n_completed, complete, complete+1);
|
|
||||||
if (res == complete) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
complete = res;
|
|
||||||
}
|
|
||||||
if (complete+1 == _n_threads) {
|
|
||||||
clear();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -346,57 +346,27 @@ public:
|
||||||
// sub-tasks from a set (possibly an enumeration), claim sub-tasks
|
// sub-tasks from a set (possibly an enumeration), claim sub-tasks
|
||||||
// in sequential order. This is ideal for claiming dynamically
|
// in sequential order. This is ideal for claiming dynamically
|
||||||
// partitioned tasks (like striding in the parallel remembered
|
// partitioned tasks (like striding in the parallel remembered
|
||||||
// set scanning). Note that unlike the above class this is
|
// set scanning).
|
||||||
// a stack object - is there any reason for it not to be?
|
|
||||||
|
|
||||||
class SequentialSubTasksDone : public StackObj {
|
class SequentialSubTasksDone : public CHeapObj<mtInternal> {
|
||||||
protected:
|
|
||||||
uint _n_tasks; // Total number of tasks available.
|
|
||||||
volatile uint _n_claimed; // Number of tasks claimed.
|
|
||||||
// _n_threads is used to determine when a sub task is done.
|
|
||||||
// See comments on SubTasksDone::_n_threads
|
|
||||||
uint _n_threads; // Total number of parallel threads.
|
|
||||||
volatile uint _n_completed; // Number of completed threads.
|
|
||||||
|
|
||||||
void clear();
|
uint _num_tasks; // Total number of tasks available.
|
||||||
|
volatile uint _num_claimed; // Number of tasks claimed.
|
||||||
|
|
||||||
|
NONCOPYABLE(SequentialSubTasksDone);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SequentialSubTasksDone() {
|
SequentialSubTasksDone(uint num_tasks) : _num_tasks(num_tasks), _num_claimed(0) { }
|
||||||
clear();
|
~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);
|
||||||
}
|
}
|
||||||
~SequentialSubTasksDone() {}
|
|
||||||
|
|
||||||
// True iff the object is in a valid state.
|
|
||||||
bool valid();
|
|
||||||
|
|
||||||
// number of tasks
|
|
||||||
uint n_tasks() const { return _n_tasks; }
|
|
||||||
|
|
||||||
// Get/set the number of parallel threads doing the tasks to t.
|
|
||||||
// Should be called before the task starts but it is safe
|
|
||||||
// to call this once a task is running provided that all
|
|
||||||
// threads agree on the number of threads.
|
|
||||||
uint n_threads() { return _n_threads; }
|
|
||||||
void set_n_threads(uint t) { _n_threads = t; }
|
|
||||||
|
|
||||||
// Set the number of tasks to be claimed to t. As above,
|
|
||||||
// should be called before the tasks start but it is safe
|
|
||||||
// to call this once a task is running provided all threads
|
|
||||||
// agree on the number of tasks.
|
|
||||||
void set_n_tasks(uint t) { _n_tasks = t; }
|
|
||||||
|
|
||||||
// Attempt to claim the next unclaimed task in the sequence,
|
// Attempt to claim the next unclaimed task in the sequence,
|
||||||
// returning true if successful, with t set to the index of the
|
// returning true if successful, with t set to the index of the
|
||||||
// claimed task. Returns false if there are no more unclaimed tasks
|
// claimed task. Returns false if there are no more unclaimed tasks
|
||||||
// in the sequence.
|
// in the sequence. In this case t is undefined.
|
||||||
bool try_claim_task(uint& t);
|
bool try_claim_task(uint& t);
|
||||||
|
|
||||||
// The calling thread asserts that it has attempted to claim
|
|
||||||
// all the tasks it possibly can in the sequence. Every thread
|
|
||||||
// claiming tasks must promise call this. Returns true if this
|
|
||||||
// is the last thread to complete so that the thread can perform
|
|
||||||
// cleanup if necessary.
|
|
||||||
bool all_tasks_completed();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_GC_SHARED_WORKGROUP_HPP
|
#endif // SHARE_GC_SHARED_WORKGROUP_HPP
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue