< prev index next >
src/share/vm/gc/shared/workgroup.cpp
Print this page
*** 29,100 ****
#include "runtime/atomic.inline.hpp"
#include "runtime/os.hpp"
// Definitions of WorkGang methods.
- AbstractWorkGang::AbstractWorkGang(const char* name,
- bool are_GC_task_threads,
- bool are_ConcurrentGC_threads) :
- _name(name),
- _are_GC_task_threads(are_GC_task_threads),
- _are_ConcurrentGC_threads(are_ConcurrentGC_threads) {
-
- assert(!(are_GC_task_threads && are_ConcurrentGC_threads),
- "They cannot both be STW GC and Concurrent threads" );
-
- // Other initialization.
- _monitor = new Monitor(/* priority */ Mutex::leaf,
- /* name */ "WorkGroup monitor",
- /* allow_vm_block */ are_GC_task_threads,
- Monitor::_safepoint_check_sometimes);
- assert(monitor() != NULL, "Failed to allocate monitor");
- _task = NULL;
- _sequence_number = 0;
- _started_workers = 0;
- _finished_workers = 0;
- }
-
- WorkGang::WorkGang(const char* name,
- uint workers,
- bool are_GC_task_threads,
- bool are_ConcurrentGC_threads) :
- AbstractWorkGang(name, are_GC_task_threads, are_ConcurrentGC_threads) {
- _total_workers = workers;
- }
-
- GangWorker* WorkGang::allocate_worker(uint which) {
- GangWorker* new_worker = new GangWorker(this, which);
- return new_worker;
- }
-
// The current implementation will exit if the allocation
// of any worker fails. Still, return a boolean so that
// a future implementation can possibly do a partial
// initialization of the workers and report such to the
// caller.
! bool WorkGang::initialize_workers() {
if (TraceWorkGang) {
tty->print_cr("Constructing work gang %s with %d threads",
name(),
total_workers());
}
! _gang_workers = NEW_C_HEAP_ARRAY(GangWorker*, total_workers(), mtInternal);
! if (gang_workers() == NULL) {
vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create GangWorker array.");
return false;
}
os::ThreadType worker_type;
if (are_ConcurrentGC_threads()) {
worker_type = os::cgc_thread;
} else {
worker_type = os::pgc_thread;
}
for (uint worker = 0; worker < total_workers(); worker += 1) {
! GangWorker* new_worker = allocate_worker(worker);
assert(new_worker != NULL, "Failed to allocate GangWorker");
! _gang_workers[worker] = new_worker;
if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) {
vm_exit_out_of_memory(0, OOM_MALLOC_ERROR,
"Cannot create worker GC thread. Out of system resources.");
return false;
}
--- 29,65 ----
#include "runtime/atomic.inline.hpp"
#include "runtime/os.hpp"
// Definitions of WorkGang methods.
// The current implementation will exit if the allocation
// of any worker fails. Still, return a boolean so that
// a future implementation can possibly do a partial
// initialization of the workers and report such to the
// caller.
! bool AbstractWorkGang::initialize_workers() {
if (TraceWorkGang) {
tty->print_cr("Constructing work gang %s with %d threads",
name(),
total_workers());
}
! _workers = NEW_C_HEAP_ARRAY(AbstractGangWorker*, total_workers(), mtInternal);
! if (_workers == NULL) {
vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create GangWorker array.");
return false;
}
os::ThreadType worker_type;
if (are_ConcurrentGC_threads()) {
worker_type = os::cgc_thread;
} else {
worker_type = os::pgc_thread;
}
for (uint worker = 0; worker < total_workers(); worker += 1) {
! AbstractGangWorker* new_worker = allocate_worker(worker);
assert(new_worker != NULL, "Failed to allocate GangWorker");
! _workers[worker] = new_worker;
if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) {
vm_exit_out_of_memory(0, OOM_MALLOC_ERROR,
"Cannot create worker GC thread. Out of system resources.");
return false;
}
*** 103,124 ****
}
}
return true;
}
! GangWorker* AbstractWorkGang::gang_worker(uint i) const {
// Array index bounds checking.
! GangWorker* result = NULL;
! assert(gang_workers() != NULL, "No workers for indexing");
assert(i < total_workers(), "Worker index out of bounds");
! result = _gang_workers[i];
assert(result != NULL, "Indexing to null worker");
return result;
}
void WorkGang::run_task(AbstractGangTask* task) {
! run_task(task, total_workers());
}
void WorkGang::run_task(AbstractGangTask* task, uint no_of_parallel_workers) {
// This thread is executed by the VM thread which does not block
// on ordinary MutexLocker's.
--- 68,128 ----
}
}
return true;
}
! AbstractGangWorker* AbstractWorkGang::worker(uint i) const {
// Array index bounds checking.
! AbstractGangWorker* result = NULL;
! assert(_workers != NULL, "No workers for indexing");
assert(i < total_workers(), "Worker index out of bounds");
! result = _workers[i];
assert(result != NULL, "Indexing to null worker");
return result;
}
+ void AbstractWorkGang::print_worker_threads_on(outputStream* st) const {
+ uint workers = total_workers();
+ for (uint i = 0; i < workers; i++) {
+ worker(i)->print_on(st);
+ st->cr();
+ }
+ }
+
+ void AbstractWorkGang::threads_do(ThreadClosure* tc) const {
+ assert(tc != NULL, "Null ThreadClosure");
+ uint workers = total_workers();
+ for (uint i = 0; i < workers; i++) {
+ tc->do_thread(worker(i));
+ }
+ }
+
+ WorkGang::WorkGang(const char* name,
+ uint workers,
+ bool are_GC_task_threads,
+ bool are_ConcurrentGC_threads) :
+ AbstractWorkGang(name, workers, are_GC_task_threads, are_ConcurrentGC_threads),
+ _started_workers(0),
+ _finished_workers(0),
+ _sequence_number(0),
+ _task(NULL) {
+
+ // Other initialization.
+ _monitor = new Monitor(/* priority */ Mutex::leaf,
+ /* name */ "WorkGroup monitor",
+ /* allow_vm_block */ are_GC_task_threads,
+ Monitor::_safepoint_check_sometimes);
+
+ assert(monitor() != NULL, "Failed to allocate monitor");
+ }
+
+ AbstractGangWorker* WorkGang::allocate_worker(uint worker_id) {
+ return new GangWorker(this, worker_id);
+ }
+
void WorkGang::run_task(AbstractGangTask* task) {
! run_task(task, (uint)active_workers());
}
void WorkGang::run_task(AbstractGangTask* task, uint no_of_parallel_workers) {
// This thread is executed by the VM thread which does not block
// on ordinary MutexLocker's.
*** 152,216 ****
Thread* me = Thread::current();
tty->print_cr(" T: " PTR_FORMAT " VM_thread: %d", p2i(me), me->is_VM_thread());
}
}
! void FlexibleWorkGang::run_task(AbstractGangTask* task) {
! // If active_workers() is passed, _finished_workers
! // must only be incremented for workers that find non_null
! // work (as opposed to all those that just check that the
! // task is not null).
! WorkGang::run_task(task, (uint) active_workers());
! }
!
! void AbstractWorkGang::internal_worker_poll(WorkData* data) const {
assert(monitor()->owned_by_self(), "worker_poll is an internal method");
assert(data != NULL, "worker data is null");
data->set_task(task());
data->set_sequence_number(sequence_number());
}
! void AbstractWorkGang::internal_note_start() {
assert(monitor()->owned_by_self(), "note_finish is an internal method");
_started_workers += 1;
}
! void AbstractWorkGang::internal_note_finish() {
assert(monitor()->owned_by_self(), "note_finish is an internal method");
_finished_workers += 1;
}
- void AbstractWorkGang::print_worker_threads_on(outputStream* st) const {
- uint num_thr = total_workers();
- for (uint i = 0; i < num_thr; i++) {
- gang_worker(i)->print_on(st);
- st->cr();
- }
- }
-
- void AbstractWorkGang::threads_do(ThreadClosure* tc) const {
- assert(tc != NULL, "Null ThreadClosure");
- uint num_thr = total_workers();
- for (uint i = 0; i < num_thr; i++) {
- tc->do_thread(gang_worker(i));
- }
- }
-
// GangWorker methods.
! GangWorker::GangWorker(AbstractWorkGang* gang, uint id) {
_gang = gang;
set_id(id);
set_name("%s#%d", gang->name(), id);
}
! void GangWorker::run() {
initialize();
loop();
}
! void GangWorker::initialize() {
this->initialize_thread_local_storage();
this->record_stack_base_and_size();
this->initialize_named_thread();
assert(_gang != NULL, "No gang to run in");
os::set_priority(this, NearMaxPriority);
--- 156,196 ----
Thread* me = Thread::current();
tty->print_cr(" T: " PTR_FORMAT " VM_thread: %d", p2i(me), me->is_VM_thread());
}
}
! void WorkGang::internal_worker_poll(WorkData* data) const {
assert(monitor()->owned_by_self(), "worker_poll is an internal method");
assert(data != NULL, "worker data is null");
data->set_task(task());
data->set_sequence_number(sequence_number());
}
! void WorkGang::internal_note_start() {
assert(monitor()->owned_by_self(), "note_finish is an internal method");
_started_workers += 1;
}
! void WorkGang::internal_note_finish() {
assert(monitor()->owned_by_self(), "note_finish is an internal method");
_finished_workers += 1;
}
// GangWorker methods.
! AbstractGangWorker::AbstractGangWorker(AbstractWorkGang* gang, uint id) {
_gang = gang;
set_id(id);
set_name("%s#%d", gang->name(), id);
}
! void AbstractGangWorker::run() {
initialize();
loop();
}
! void AbstractGangWorker::initialize() {
this->initialize_thread_local_storage();
this->record_stack_base_and_size();
this->initialize_named_thread();
assert(_gang != NULL, "No gang to run in");
os::set_priority(this, NearMaxPriority);
*** 222,231 ****
--- 202,225 ----
// as (opposed to MutexLockerEx's).
assert(!Thread::current()->is_VM_thread(), "VM thread should not be part"
" of a work gang");
}
+ bool AbstractGangWorker::is_GC_task_thread() const {
+ return gang()->are_GC_task_threads();
+ }
+
+ bool AbstractGangWorker::is_ConcurrentGC_thread() const {
+ return gang()->are_ConcurrentGC_threads();
+ }
+
+ void AbstractGangWorker::print_on(outputStream* st) const {
+ st->print("\"%s\" ", name());
+ Thread::print_on(st);
+ st->cr();
+ }
+
void GangWorker::loop() {
int previous_sequence_number = 0;
Monitor* gang_monitor = gang()->monitor();
for ( ; ; ) {
WorkData data;
*** 298,338 ****
}
previous_sequence_number = data.sequence_number();
}
}
- bool GangWorker::is_GC_task_thread() const {
- return gang()->are_GC_task_threads();
- }
-
- bool GangWorker::is_ConcurrentGC_thread() const {
- return gang()->are_ConcurrentGC_threads();
- }
-
- void GangWorker::print_on(outputStream* st) const {
- st->print("\"%s\" ", name());
- Thread::print_on(st);
- st->cr();
- }
-
- // Printing methods
-
- const char* AbstractWorkGang::name() const {
- return _name;
- }
-
- #ifndef PRODUCT
-
- const char* AbstractGangTask::name() const {
- return _name;
- }
-
- #endif /* PRODUCT */
-
- // FlexibleWorkGang
-
-
// *** WorkGangBarrierSync
WorkGangBarrierSync::WorkGangBarrierSync()
: _monitor(Mutex::safepoint, "work gang barrier sync", true,
Monitor::_safepoint_check_never),
--- 292,301 ----
< prev index next >