// 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; } if (!DisableStartThread) { os::start_thread(new_worker); } } 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 >= 0) && (i < total_workers())), "Worker index out of bounds"); result = _gang_workers[i]; assert(result != NULL, "Indexing to null worker"); return result; }
AbstractWorkGang::~AbstractWorkGang() { if (TraceWorkGang) { tty->print_cr("Destructing work gang %s", name()); } stop(); // stop all the workers for (uint worker = 0; worker < total_workers(); worker += 1) { delete gang_worker(worker); } delete gang_workers(); delete monitor(); }
WorkGang::~WorkGang() { if (TraceWorkGang) { tty->print_cr("Destructing work gang %s", name()); } stop_task(); for (int worker = 0; worker < total_workers(); worker += 1) { delete gang_worker(worker); } delete gang_workers(); delete monitor(); }
/** * 创建并初始化所有的工作线程 */ 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()); if (gang_workers() == NULL) { vm_exit_out_of_memory(0, "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; } printf("%s[%d] [tid: %lu]: 开始创建 %u 个 %s Gc线程.\n", __FILE__, __LINE__, pthread_self(), total_workers(), worker_type == os::cgc_thread? "Concurrent" : "Parallel"); 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, "Cannot create worker GC thread. Out of system resources."); return false; } if (!DisableStartThread) { os::start_thread(new_worker); } } return true; }
WorkGang::WorkGang(const char* name, int workers, bool are_GC_threads) { // Save arguments. _name = name; _total_workers = workers; _are_GC_threads = are_GC_threads; if (TraceWorkGang) { tty->print_cr("Constructing work gang %s with %d threads", name, workers); } // Other initialization. if (are_GC_threads) { _monitor = new Monitor(/* priority */ Mutex::safepoint, /* name */ "WorkGroup monitor", /* allow_vm_block */ true); } else { _monitor = new Monitor(/* priority */ Mutex::leaf, /* name */ "WorkGroup monitor", /* allow_vm_block */ false); } assert(monitor() != NULL, "Failed to allocate monitor"); _terminate = false; _task = NULL; _sequence_number = 0; _started_workers = 0; _finished_workers = 0; _gang_workers = NEW_C_HEAP_ARRAY(GangWorker*, workers); assert(gang_workers() != NULL, "Failed to allocate gang workers"); for (int worker = 0; worker < total_workers(); worker += 1) { GangWorker* new_worker = new GangWorker(this, worker); assert(new_worker != NULL, "Failed to allocate GangWorker"); _gang_workers[worker] = new_worker; bool os_thread_create = os::create_thread(new_worker, os::gc_thread); assert(os_thread_create, "os thread create failed"); if (!DisableStartThread) { os::start_thread(new_worker); } } }