// 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();
}
Beispiel #4
0
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();
}
Beispiel #5
0
/**
 * 创建并初始化所有的工作线程
 */
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;
}
Beispiel #6
0
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);
    }
  }
}