ErrorStack EnginePimpl::uninitialize_once() {
  LOG(INFO) << "================================================================================";
  LOG(INFO) << "=================== FOEDUS ENGINE ("
    << describe_short() << ") EXITTING...... ================";
  LOG(INFO) << "================================================================================";
  if (is_master() && soc_manager_.is_initialized()) {
    soc_manager_.get_shared_memory_repo()->change_master_status(
      soc::MasterEngineStatus::kWaitingForChildTerminate);
  }
  ErrorStackBatch batch;
  // uninit in reverse order of initialization
  auto modules = get_modules();
  std::reverse(modules.begin(), modules.end());
  for (ModulePtr& module : modules) {
    if (!module.ptr_->is_initialized()) {
      continue;
    }
    // During uninitialization, master waits for SOCs' uninitialization before its uninit.
    if (is_master()) {
      batch.emprace_back(soc_manager_.wait_for_children_module(false, module.type_));
    }
    batch.emprace_back(module.ptr_->uninitialize());
    on_module_uninitialized(module.type_);
    // Then SOCs wait for master before moving on to next module.
    if (!is_master()) {
      batch.emprace_back(soc_manager_.wait_for_master_module(false, module.type_));
    }
  }

  // SOC manager is special. We must uninitialize it at last.
  batch.emprace_back(soc_manager_.uninitialize());
  // after that, we can't even set status. shared memory has been detached.
  return SUMMARIZE_ERROR_BATCH(batch);
}
ErrorStack EnginePimpl::initialize_once() {
  if (is_master()) {
    CHECK_ERROR(check_valid_options());
  }
  // SOC manager is special. We must initialize it first.
  CHECK_ERROR(soc_manager_.initialize());
  on_module_initialized(kSoc);
  ErrorStack module_initialize_error = initialize_modules();
  if (module_initialize_error.is_error()) {
    LOG(ERROR) << "*******************************************************************************";
    LOG(ERROR) << "*** ERROR while module initailization in " << describe_short() << ". "
      << module_initialize_error << "";
    LOG(ERROR) << "*******************************************************************************";
    soc_manager_.report_engine_fatal_error();
    CHECK_ERROR(module_initialize_error);
  }

  // The following can assume SOC manager is already initialized
  if (is_master()) {
    soc::SharedMemoryRepo* repo = soc_manager_.get_shared_memory_repo();
    repo->change_master_status(soc::MasterEngineStatus::kRunning);
    // wait for children's kRunning status
    // TASK(Hideaki) should be a function in soc manager
    uint16_t soc_count = engine_->get_options().thread_.group_count_;
    while (true) {
      std::this_thread::sleep_for(std::chrono::milliseconds(5));
      assorted::memory_fence_acq_rel();
      bool error_happened = false;
      bool remaining = false;
      for (uint16_t node = 0; node < soc_count; ++node) {
        soc::ChildEngineStatus* status = repo->get_node_memory_anchors(node)->child_status_memory_;
        if (status->status_code_ == soc::ChildEngineStatus::kFatalError) {
          error_happened = true;
          break;
        }
        if (status->status_code_ == soc::ChildEngineStatus::kRunning) {
          continue;  // ok
        }
        remaining = true;
      }

      if (error_happened) {
        LOG(ERROR) << "[FOEDUS] ERROR! error while waiting child kRunning";
        soc_manager_.report_engine_fatal_error();
        return ERROR_STACK(kErrorCodeSocChildInitFailed);
      } else if (!remaining) {
        break;
      }
    }
  }
  LOG(INFO) << "================================================================================";
  LOG(INFO) << "================== FOEDUS ENGINE ("
    << describe_short() << ") INITIALIZATION DONE ===========";
  LOG(INFO) << "================================================================================";

  // In a few places, we check if we are running under valgrind and, if so, turn off
  // optimizations valgrind can't handle (eg hugepages).
  bool running_on_valgrind = RUNNING_ON_VALGRIND;
  if (running_on_valgrind) {
    LOG(INFO) << "=============== ATTENTION: VALGRIND MODE! ==================";
    LOG(INFO) << "This Engine is running under valgrind, which disables several optimizations";
    LOG(INFO) << "If you see this message while usual execution, something is wrong.";
    LOG(INFO) << "=============== ATTENTION: VALGRIND MODE! ==================";
  }
  return kRetOk;
}
Exemple #3
0
 virtual void describe(std::ostream &out) const {
   describe_short(out);
   out << std::endl;
   if (!_description.empty())
     out << _description << std::endl;
 }