libfoedus-core
FOEDUS Core Library
foedus::soc::SocManagerPimpl Class Referencefinal

Pimpl object of SocManager. More...

Detailed Description

Pimpl object of SocManager.

A private pimpl object for SocManager. Do not include this header from a client program unless you know what you are doing.

Definition at line 43 of file soc_manager_pimpl.hpp.

#include <soc_manager_pimpl.hpp>

Inheritance diagram for foedus::soc::SocManagerPimpl:
Collaboration diagram for foedus::soc::SocManagerPimpl:

Public Member Functions

 SocManagerPimpl ()=delete
 
 SocManagerPimpl (Engine *engine)
 
ErrorStack initialize_once () override
 
ErrorStack uninitialize_once () override
 
void report_engine_fatal_error ()
 
ErrorStack initialize_master ()
 Called as part of initialize_once() if this is a master engine. More...
 
ErrorStack initialize_child ()
 Called as part of initialize_once() if this is a child SOC engine. More...
 
ErrorStack launch_emulated_children ()
 Launch emulated children as threads. More...
 
ErrorStack launch_forked_children ()
 Launch children via fork. More...
 
ErrorStack launch_spawned_children ()
 Launch children via spawn. More...
 
ErrorStack wait_for_child_attach ()
 Wait for child SOCs to start up and at least finish attaching shared memory. More...
 
ErrorStack wait_for_child_terminate ()
 Wait for child SOCs to terminate. More...
 
ErrorStack wait_for_master_status (MasterEngineStatus::StatusCode target_status)
 Wait for master engine to finish upto the specified status. More...
 
ErrorStack wait_for_master_module (bool init, ModuleType module)
 
ErrorStack wait_for_children_module (bool init, ModuleType module)
 
void emulated_child_main (SocId node)
 Main routine of emulated SOCs. More...
 
int forked_child_main (SocId node)
 Main routine of forked SOCs. More...
 
- Public Member Functions inherited from foedus::DefaultInitializable
 DefaultInitializable ()
 
virtual ~DefaultInitializable ()
 
 DefaultInitializable (const DefaultInitializable &)=delete
 
DefaultInitializableoperator= (const DefaultInitializable &)=delete
 
ErrorStack initialize () override final
 Typical implementation of Initializable::initialize() that provides initialize-once semantics. More...
 
ErrorStack uninitialize () override final
 Typical implementation of Initializable::uninitialize() that provides uninitialize-once semantics. More...
 
bool is_initialized () const override final
 Returns whether the object has been already initialized or not. More...
 
- Public Member Functions inherited from foedus::Initializable
virtual ~Initializable ()
 

Static Public Member Functions

static void spawned_child_main (const std::vector< proc::ProcAndName > &procedures)
 Main routine of spawned SOCs. More...
 
static ErrorStack child_main_common (EngineType engine_type, Upid master_upid, Eid master_eid, SocId node, const std::vector< proc::ProcAndName > &procedures)
 

Public Attributes

Engine *const engine_
 
SharedMemoryRepo memory_repo_
 
std::vector< std::thread > child_emulated_threads_
 Threads that emulate child SOCs. More...
 
std::vector< Engine * > child_emulated_engines_
 And their engines. More...
 
Upid child_upids_ [kMaxSocs]
 Process IDs of child SOCs. More...
 

Constructor & Destructor Documentation

foedus::soc::SocManagerPimpl::SocManagerPimpl ( )
delete
foedus::soc::SocManagerPimpl::SocManagerPimpl ( Engine engine)
inlineexplicit

Definition at line 46 of file soc_manager_pimpl.hpp.

46 : engine_(engine) {}

Member Function Documentation

ErrorStack foedus::soc::SocManagerPimpl::child_main_common ( EngineType  engine_type,
Upid  master_upid,
Eid  master_eid,
SocId  node,
const std::vector< proc::ProcAndName > &  procedures 
)
static

Definition at line 594 of file soc_manager_pimpl.cpp.

References foedus::soc::SharedMemoryRepo::change_child_status(), CHECK_ERROR, COERCE_ERROR, foedus::proc::ProcManager::describe_registered_procs(), foedus::Engine::get_proc_manager(), foedus::Engine::get_soc_manager(), foedus::Engine::initialize(), foedus::ErrorStack::is_error(), foedus::kChildEmulated, foedus::kRetOk, foedus::soc::MasterEngineStatus::kRunning, foedus::soc::ChildEngineStatus::kRunning, foedus::soc::ChildEngineStatus::kTerminated, foedus::soc::MasterEngineStatus::kWaitingForChildTerminate, foedus::soc::ChildEngineStatus::kWaitingForMasterInitialization, foedus::proc::ProcManager::local_register(), memory_repo_, foedus::Engine::uninitialize(), and wait_for_master_status().

Referenced by emulated_child_main(), forked_child_main(), and spawned_child_main().

599  {
600  thread::NumaThreadScope scope(node);
601 
602  // In order to make sure child processes die as soon as the parent dies,
603  // we use prctl.
604  if (engine_type != kChildEmulated) {
605  ::prctl(PR_SET_PDEATHSIG, SIGHUP);
606  }
607 
608  Engine soc_engine(engine_type, master_upid, master_eid, node);
609  ErrorStack init_error = soc_engine.initialize();
610  if (init_error.is_error()) {
611  std::cerr << "[FOEDUS-Child] Failed to initialize child SOC-" << node
612  << ". error=" << init_error
613  << " This is an unrecoverable error. This process quits shortly" << std::endl;
614  CHECK_ERROR(soc_engine.uninitialize());
615  return init_error;
616  }
617 
618  SocManagerPimpl* soc_this = soc_engine.get_soc_manager()->pimpl_;
619  SharedMemoryRepo& soc_memory = soc_this->memory_repo_;
620 
621  // after initialize(), we can safely use glog.
622  LOG(INFO) << "The SOC engine-" << node << " was initialized.";
623 
624  // Add the given procedures.
625  proc::ProcManager* procm = soc_engine.get_proc_manager();
626  for (const proc::ProcAndName& proc_and_name : procedures) {
627  COERCE_ERROR(procm->local_register(proc_and_name));
628  }
629 
630  LOG(INFO) << "Added user procedures: " << procm->describe_registered_procs()
631  << ". Waiting for master engine's initialization...";
632  soc_memory.change_child_status(node, ChildEngineStatus::kWaitingForMasterInitialization);
633  COERCE_ERROR(soc_this->wait_for_master_status(MasterEngineStatus::kRunning));
634  LOG(INFO) << "The SOC engine-" << node << " detected that master engine has started"
635  << " running.";
636  soc_memory.change_child_status(node, ChildEngineStatus::kRunning);
637  COERCE_ERROR(soc_this->wait_for_master_status(MasterEngineStatus::kWaitingForChildTerminate));
638 
639  LOG(INFO) << "Stopping the SOC engine-" << node;
640  soc_memory.change_child_status(node, ChildEngineStatus::kTerminated);
641  ErrorStack uninit_error = soc_engine.uninitialize();
642  if (uninit_error.is_error()) {
643  LOG(ERROR) << "Error while uninitializing SOC engine-" << node << ": " << uninit_error;
644  return uninit_error;
645  }
646 
647  return kRetOk;
648 }
The master is waiting for child engines to terminate.
#define COERCE_ERROR(x)
This macro calls x and aborts if encounters an error.
The child engine has normally terminated.
Done all initialization and running transactions.
std::pair< ProcName, Proc > ProcAndName
Just a std::pair.
Definition: proc_id.hpp:119
Child engine has successfully initialized all modules and is now waiting for master's kRunning status...
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
const ErrorStack kRetOk
Normal return value for no-error case.
Done all initialization and running transactions.
A child SOC instance launched just as a thread in the same process as master.
Definition: engine_type.hpp:51

Here is the call graph for this function:

Here is the caller graph for this function:

void foedus::soc::SocManagerPimpl::emulated_child_main ( SocId  node)

Main routine of emulated SOCs.

Definition at line 462 of file soc_manager_pimpl.cpp.

References child_main_common(), engine_, foedus::Engine::get_master_eid(), foedus::Engine::get_master_upid(), foedus::proc::ProcManager::get_pre_registered_procedures(), foedus::Engine::get_proc_manager(), foedus::ErrorStack::is_error(), and foedus::kChildEmulated.

Referenced by launch_emulated_children().

462  {
463  Upid master_upid = engine_->get_master_upid();
464  Eid master_eid = engine_->get_master_eid();
465  // We can reuse procedures pre-registered in master. Good for being a thread.
466  const auto& procedures = engine_->get_proc_manager()->get_pre_registered_procedures();
467  ErrorStack ret = child_main_common(kChildEmulated, master_upid, master_eid, node, procedures);
468  if (ret.is_error()) {
469  std::cerr << "[FOEDUS-Child] Emulated SOC-" << node
470  << " exits with an error: " << ret << std::endl;
471  }
472 }
static ErrorStack child_main_common(EngineType engine_type, Upid master_upid, Eid master_eid, SocId node, const std::vector< proc::ProcAndName > &procedures)
Eid get_master_eid() const
Returns Engine ID of the master engine.
Definition: engine.cpp:76
soc::Upid get_master_upid() const
Returns Universal (or Unique) ID of the master process.
Definition: engine.cpp:75
const std::vector< ProcAndName > & get_pre_registered_procedures() const
Returns procedures given to pre_register()
uint64_t Upid
Universal (or Unique) ID of a process.
Definition: soc_id.hpp:48
proc::ProcManager * get_proc_manager() const
See System and User Procedures.
Definition: engine.cpp:51
uint64_t Eid
An Engine ID to differentiate two Engine objects instantiated in the same process.
Definition: engine_type.hpp:29
A child SOC instance launched just as a thread in the same process as master.
Definition: engine_type.hpp:51

Here is the call graph for this function:

Here is the caller graph for this function:

int foedus::soc::SocManagerPimpl::forked_child_main ( SocId  node)

Main routine of forked SOCs.

Returns
exit code as a process

Definition at line 503 of file soc_manager_pimpl.cpp.

References child_main_common(), engine_, foedus::Engine::get_master_eid(), foedus::Engine::get_master_upid(), foedus::proc::ProcManager::get_pre_registered_procedures(), foedus::Engine::get_proc_manager(), foedus::ErrorStack::is_error(), and foedus::kChildForked.

Referenced by launch_forked_children().

503  {
504  Upid master_upid = engine_->get_master_upid();
505  Eid master_eid = engine_->get_master_eid();
506  // These are pre-registered before fork(), so still we can reuse.
507  const auto& procedures = engine_->get_proc_manager()->get_pre_registered_procedures();
508  ErrorStack ret = child_main_common(kChildForked, master_upid, master_eid, node, procedures);
509  if (ret.is_error()) {
510  std::cerr << "[FOEDUS-Child] Forked SOC-" << node
511  << " exits with an error: " << ret << std::endl;
512  return EXIT_FAILURE;
513  } else {
514  return EXIT_SUCCESS;
515  }
516 }
static ErrorStack child_main_common(EngineType engine_type, Upid master_upid, Eid master_eid, SocId node, const std::vector< proc::ProcAndName > &procedures)
Eid get_master_eid() const
Returns Engine ID of the master engine.
Definition: engine.cpp:76
soc::Upid get_master_upid() const
Returns Universal (or Unique) ID of the master process.
Definition: engine.cpp:75
const std::vector< ProcAndName > & get_pre_registered_procedures() const
Returns procedures given to pre_register()
uint64_t Upid
Universal (or Unique) ID of a process.
Definition: soc_id.hpp:48
A child SOC instance launched via fork().
Definition: engine_type.hpp:65
proc::ProcManager * get_proc_manager() const
See System and User Procedures.
Definition: engine.cpp:51
uint64_t Eid
An Engine ID to differentiate two Engine objects instantiated in the same process.
Definition: engine_type.hpp:29

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorStack foedus::soc::SocManagerPimpl::initialize_child ( )

Called as part of initialize_once() if this is a child SOC engine.

Definition at line 128 of file soc_manager_pimpl.cpp.

References foedus::soc::SharedMemoryRepo::attach_shared_memories(), foedus::soc::SharedMemoryRepo::change_child_status(), COERCE_ERROR, engine_, foedus::Engine::get_master_eid(), foedus::Engine::get_master_upid(), foedus::Engine::get_nonconst_options(), foedus::Engine::get_soc_id(), foedus::ErrorStack::is_error(), foedus::kRetOk, foedus::soc::ChildEngineStatus::kSharedMemoryAttached, foedus::soc::MasterEngineStatus::kSharedMemoryReservedReclamation, memory_repo_, and wait_for_master_status().

Referenced by initialize_once().

128  {
129  Upid master_upid = engine_->get_master_upid();
130  Eid master_eid = engine_->get_master_eid();
131  SocId soc_id = engine_->get_soc_id();
132  pid_t pid = ::getpid();
133  ErrorStack attach_error = memory_repo_.attach_shared_memories(
134  master_upid,
135  master_eid,
136  soc_id,
138  if (attach_error.is_error()) {
139  std::cerr << "[FOEDUS-Child] MasterUpid=" << master_upid << ", ChildPid=" << pid
140  << ", Node=" << soc_id << ". Failed to attach shared memory. error=" << attach_error
141  << " This is an unrecoverable error. This process quits shortly" << std::endl;
142  ::_exit(1);
143  }
145 
146  // child engines could just move on, but it's safer to wait for at least the reclamation
147  // of shared memory by master engine.
149  return kRetOk;
150 }
Eid get_master_eid() const
Returns Engine ID of the master engine.
Definition: engine.cpp:76
#define COERCE_ERROR(x)
This macro calls x and aborts if encounters an error.
Child engine successfully attached shared memory and waiting for master's kWaitingForChildInitializat...
soc::Upid get_master_upid() const
Returns Universal (or Unique) ID of the master process.
Definition: engine.cpp:75
ErrorStack attach_shared_memories(uint64_t master_upid, Eid master_eid, SocId my_soc_id, EngineOptions *options)
Child processes (emulated or not) set a reference to shared memory and receive the EngnieOption value...
ErrorStack wait_for_master_status(MasterEngineStatus::StatusCode target_status)
Wait for master engine to finish upto the specified status.
uint64_t Upid
Universal (or Unique) ID of a process.
Definition: soc_id.hpp:48
EngineOptions * get_nonconst_options()
Returns an updatable reference to options.
Definition: engine.cpp:40
uint16_t SocId
Represents an ID of an SOC, or NUMA node.
Definition: soc_id.hpp:41
const ErrorStack kRetOk
Normal return value for no-error case.
soc::SocId get_soc_id() const
If this is a child instance, returns its SOC ID (NUMA node).
Definition: engine.cpp:73
uint64_t Eid
An Engine ID to differentiate two Engine objects instantiated in the same process.
Definition: engine_type.hpp:29
void change_child_status(SocId node, ChildEngineStatus::StatusCode new_status)
Master engine successfully confirmed child's attach and reserved the reclamation of the shared memori...

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorStack foedus::soc::SocManagerPimpl::initialize_master ( )

Called as part of initialize_once() if this is a master engine.

Definition at line 86 of file soc_manager_pimpl.cpp.

References foedus::soc::SharedMemoryRepo::allocate_shared_memories(), CHECK_ERROR, child_emulated_engines_, child_emulated_threads_, foedus::soc::NodeMemoryAnchors::child_status_memory_, child_upids_, foedus::soc::SharedMemoryRepo::deallocate_shared_memories(), engine_, foedus::soc::SharedMemoryRepo::get_global_memory_anchors(), foedus::Engine::get_master_eid(), foedus::Engine::get_master_upid(), foedus::soc::SharedMemoryRepo::get_node_memory_anchors(), foedus::Engine::get_options(), foedus::thread::ThreadOptions::group_count_, foedus::soc::MasterEngineStatus::initialized_modules_, foedus::soc::ChildEngineStatus::initialized_modules_, foedus::ErrorStack::is_error(), foedus::kChildForked, foedus::kChildLocalSpawned, foedus::kChildRemoteSpawned, foedus::kDummyTail, foedus::soc::ChildEngineStatus::kInitial, foedus::kInvalid, foedus::kRetOk, foedus::soc::MasterEngineStatus::kSharedMemoryAllocated, launch_emulated_children(), launch_forked_children(), launch_spawned_children(), foedus::soc::GlobalMemoryAnchors::master_status_memory_, memory_repo_, foedus::EngineOptions::soc_, foedus::soc::SocOptions::soc_type_, foedus::fs::status(), foedus::soc::MasterEngineStatus::status_code_, foedus::soc::ChildEngineStatus::status_code_, foedus::EngineOptions::thread_, foedus::soc::MasterEngineStatus::uninitialized_modules_, and foedus::soc::ChildEngineStatus::uninitialized_modules_.

Referenced by initialize_once().

86  {
87  ErrorStack alloc_error = memory_repo_.allocate_shared_memories(
90  engine_->get_options());
91  if (alloc_error.is_error()) {
93  return alloc_error;
94  }
95 
96  // shared memory allocated. now launch child SOCs
99  std::memset(child_upids_, 0, sizeof(child_upids_));
100 
101  // set initial value of initialize/uninitialize status now
102  {
105  status->initialized_modules_ = kInvalid;
106  status->uninitialized_modules_ = kDummyTail;
107  }
108  uint16_t soc_count = engine_->get_options().thread_.group_count_;
109  for (uint16_t node = 0; node < soc_count; ++node) {
110  ChildEngineStatus* status = memory_repo_.get_node_memory_anchors(node)->child_status_memory_;
112  status->initialized_modules_ = kInvalid;
113  status->uninitialized_modules_ = kDummyTail;
114  }
115 
117  if (soc_type == kChildForked) {
119  } else if (soc_type == kChildLocalSpawned || soc_type == kChildRemoteSpawned) {
120  // so far remote spawn does local spawn
122  } else {
124  }
125  return kRetOk;
126 }
Upid child_upids_[kMaxSocs]
Process IDs of child SOCs.
ErrorStack allocate_shared_memories(uint64_t upid, Eid eid, const EngineOptions &options)
Master process creates shared memories by calling this method.
ErrorStack launch_forked_children()
Launch children via fork.
GlobalMemoryAnchors * get_global_memory_anchors()
Eid get_master_eid() const
Returns Engine ID of the master engine.
Definition: engine.cpp:76
std::vector< std::thread > child_emulated_threads_
Threads that emulate child SOCs.
void deallocate_shared_memories()
Detaches and releases the shared memories.
EngineType soc_type_
How to launch SOC engine instances.
Definition: soc_options.hpp:54
FileStatus status(const Path &p)
Returns the status of the file.
Definition: filesystem.cpp:45
A child SOC instance launched in other machines.
Definition: engine_type.hpp:87
NodeMemoryAnchors * get_node_memory_anchors(SocId node)
const EngineOptions & get_options() const
Definition: engine.cpp:39
soc::Upid get_master_upid() const
Returns Universal (or Unique) ID of the master process.
Definition: engine.cpp:75
ErrorStack launch_emulated_children()
Launch emulated children as threads.
A child SOC instance launched via spawn().
Definition: engine_type.hpp:78
std::vector< Engine * > child_emulated_engines_
And their engines.
EngineType
Type of an engine instance of how to launch it.
Definition: engine_type.hpp:35
ErrorStack launch_spawned_children()
Launch children via spawn.
A child SOC instance launched via fork().
Definition: engine_type.hpp:65
uint16_t group_count_
Number of ThreadGroup in the engine.
thread::ThreadOptions thread_
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
const ErrorStack kRetOk
Normal return value for no-error case.
MasterEngineStatus * master_status_memory_
This tiny piece of memory contains the current status of the master engine and its synchronization me...
ChildEngineStatus * child_status_memory_
This tiny piece of memory contains the current status of the child engine on this node...
Master engine successfully allocated shared memory and waiting for child's attach.

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorStack foedus::soc::SocManagerPimpl::initialize_once ( )
overridevirtual

Implements foedus::DefaultInitializable.

Definition at line 49 of file soc_manager_pimpl.cpp.

References engine_, initialize_child(), initialize_master(), and foedus::Engine::is_master().

49  {
50  if (engine_->is_master()) {
51  return initialize_master();
52  } else {
53  return initialize_child();
54  }
55 }
ErrorStack initialize_master()
Called as part of initialize_once() if this is a master engine.
bool is_master() const
Returns if this engine object is a master instance.
Definition: engine.cpp:68
ErrorStack initialize_child()
Called as part of initialize_once() if this is a child SOC engine.

Here is the call graph for this function:

ErrorStack foedus::soc::SocManagerPimpl::launch_emulated_children ( )

Launch emulated children as threads.

Definition at line 445 of file soc_manager_pimpl.cpp.

References CHECK_ERROR, child_emulated_engines_, child_emulated_threads_, emulated_child_main(), engine_, foedus::Engine::get_options(), foedus::thread::ThreadOptions::group_count_, foedus::kRetOk, foedus::EngineOptions::thread_, and wait_for_child_attach().

Referenced by initialize_master().

445  {
446  uint16_t soc_count = engine_->get_options().thread_.group_count_;
447  for (uint16_t node = 0; node < soc_count; ++node) {
448  child_emulated_engines_.push_back(nullptr);
449  }
450  // from now on child_emulated_engines_ doesn't grow/shrink
451  for (uint16_t node = 0; node < soc_count; ++node) {
452  child_emulated_threads_.emplace_back(std::thread(
454  this,
455  node));
456  }
457 
459  return kRetOk;
460 }
void emulated_child_main(SocId node)
Main routine of emulated SOCs.
std::vector< std::thread > child_emulated_threads_
Threads that emulate child SOCs.
const EngineOptions & get_options() const
Definition: engine.cpp:39
ErrorStack wait_for_child_attach()
Wait for child SOCs to start up and at least finish attaching shared memory.
std::vector< Engine * > child_emulated_engines_
And their engines.
uint16_t group_count_
Number of ThreadGroup in the engine.
thread::ThreadOptions thread_
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
const ErrorStack kRetOk
Normal return value for no-error case.

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorStack foedus::soc::SocManagerPimpl::launch_forked_children ( )

Launch children via fork.

Definition at line 479 of file soc_manager_pimpl.cpp.

References foedus::soc::SharedMemoryRepo::change_master_status(), CHECK_ERROR, child_upids_, foedus::soc::SharedMemoryRepo::deallocate_shared_memories(), engine_, ERROR_STACK, forked_child_main(), foedus::Engine::get_options(), foedus::thread::ThreadOptions::group_count_, foedus::kErrorCodeSocForkFailed, foedus::soc::MasterEngineStatus::kFatalError, foedus::kRetOk, memory_repo_, foedus::assorted::os_error(), foedus::EngineOptions::thread_, and wait_for_child_attach().

Referenced by initialize_master().

479  {
480  uint16_t soc_count = engine_->get_options().thread_.group_count_;
481  for (uint16_t node = 0; node < soc_count; ++node) {
482  pid_t pid = ::fork();
483  if (pid == -1) {
484  // failed to fork! immediately release shared memory and return.
487  std::cerr << "[FOEDUS] Failed to fork child SOC. error=" << assorted::os_error() << std::endl;
488  // the already forked children will shortly notice that the parent failed and exits.
490  } else if (pid == 0) {
491  // child
492  int child_ret = forked_child_main(node);
493  ::_exit(child_ret);
494  } else {
495  // parent. move on.
496  child_upids_[node] = pid;
497  }
498  }
500  return kRetOk;
501 }
Upid child_upids_[kMaxSocs]
Process IDs of child SOCs.
void change_master_status(MasterEngineStatus::StatusCode new_status)
#define ERROR_STACK(e)
Instantiates ErrorStack with the given foedus::error_code, creating an error stack with the current f...
void deallocate_shared_memories()
Detaches and releases the shared memories.
Whenever child observes this, they will call _exit() asap.
const EngineOptions & get_options() const
Definition: engine.cpp:39
0x0C03 : "SOC : Failed to fork child SOCs." .
Definition: error_code.hpp:222
ErrorStack wait_for_child_attach()
Wait for child SOCs to start up and at least finish attaching shared memory.
int forked_child_main(SocId node)
Main routine of forked SOCs.
uint16_t group_count_
Number of ThreadGroup in the engine.
std::string os_error()
Thread-safe strerror(errno).
thread::ThreadOptions thread_
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
const ErrorStack kRetOk
Normal return value for no-error case.

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorStack foedus::soc::SocManagerPimpl::launch_spawned_children ( )

Launch children via spawn.

Definition at line 523 of file soc_manager_pimpl.cpp.

References foedus::soc::SharedMemoryRepo::change_master_status(), CHECK_ERROR, child_upids_, foedus::soc::SocOptions::convert_spawn_executable_pattern(), foedus::soc::SocOptions::convert_spawn_ld_library_path_pattern(), foedus::soc::SharedMemoryRepo::deallocate_shared_memories(), engine_, ERROR_STACK, foedus::Engine::get_master_eid(), foedus::Engine::get_master_upid(), foedus::Engine::get_options(), foedus::thread::ThreadOptions::group_count_, foedus::kErrorCodeSocSpawnFailed, foedus::soc::MasterEngineStatus::kFatalError, foedus::kRetOk, memory_repo_, foedus::assorted::os_error(), foedus::EngineOptions::soc_, foedus::EngineOptions::thread_, and wait_for_child_attach().

Referenced by initialize_master().

523  {
524  Upid master_upid = engine_->get_master_upid();
525  Eid master_eid = engine_->get_master_eid();
526  uint16_t soc_count = engine_->get_options().thread_.group_count_;
527  for (uint16_t node = 0; node < soc_count; ++node) {
528  posix_spawn_file_actions_t file_actions;
529  posix_spawnattr_t attr;
530  ::posix_spawn_file_actions_init(&file_actions);
531  ::posix_spawnattr_init(&attr);
532  std::string executable = engine_->get_options().soc_.convert_spawn_executable_pattern(node);
533  std::string ld_path = engine_->get_options().soc_.convert_spawn_ld_library_path_pattern(node);
534  std::string ld_env("LD_LIBRARY_PATH=");
535  ld_env += ld_path;
536  std::string pid_env("FOEDUS_MASTER_UPID=");
537  pid_env += std::to_string(master_upid);
538  std::string eid_env("FOEDUS_MASTER_EID=");
539  eid_env += std::to_string(master_eid);
540  std::string soc_id_env("FOEDUS_SOC_ID=");
541  soc_id_env += std::to_string(node);
542 
543  char* const argv[] = { const_cast<char*>(executable.c_str()), nullptr};
544  char* const envp[] = {
545  const_cast<char*>(ld_env.c_str()),
546  const_cast<char*>(pid_env.c_str()),
547  const_cast<char*>(eid_env.c_str()),
548  const_cast<char*>(soc_id_env.c_str()),
549  nullptr};
550 
551  pid_t child_pid;
552  int ret = ::posix_spawn(&child_pid, executable.c_str(), &file_actions, &attr, argv, envp);
553  if (ret == -1) {
554  // failed to spawn! immediately release shared memory and return.
557  std::cerr << "[FOEDUS] Failed to spawn child SOC. error="
558  << assorted::os_error() << std::endl;
559  // the already spawned children will shortly notice that the parent failed and exits.
561  }
562  child_upids_[node] = child_pid;
563  }
565  return kRetOk;
566 }
Upid child_upids_[kMaxSocs]
Process IDs of child SOCs.
0x0C04 : "SOC : Failed to spawn child SOCs." .
Definition: error_code.hpp:223
void change_master_status(MasterEngineStatus::StatusCode new_status)
#define ERROR_STACK(e)
Instantiates ErrorStack with the given foedus::error_code, creating an error stack with the current f...
Eid get_master_eid() const
Returns Engine ID of the master engine.
Definition: engine.cpp:76
void deallocate_shared_memories()
Detaches and releases the shared memories.
Whenever child observes this, they will call _exit() asap.
const EngineOptions & get_options() const
Definition: engine.cpp:39
ErrorStack wait_for_child_attach()
Wait for child SOCs to start up and at least finish attaching shared memory.
std::string convert_spawn_executable_pattern(int node) const
converts spawn_executable_pattern_ into a string with the given node ID.
Definition: soc_options.cpp:36
soc::Upid get_master_upid() const
Returns Universal (or Unique) ID of the master process.
Definition: engine.cpp:75
uint64_t Upid
Universal (or Unique) ID of a process.
Definition: soc_id.hpp:48
uint16_t group_count_
Number of ThreadGroup in the engine.
std::string os_error()
Thread-safe strerror(errno).
thread::ThreadOptions thread_
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
const ErrorStack kRetOk
Normal return value for no-error case.
uint64_t Eid
An Engine ID to differentiate two Engine objects instantiated in the same process.
Definition: engine_type.hpp:29
std::string convert_spawn_ld_library_path_pattern(int node) const
converts spawn_ld_library_path_pattern_ into a string with the given node ID.
Definition: soc_options.cpp:44

Here is the call graph for this function:

Here is the caller graph for this function:

void foedus::soc::SocManagerPimpl::report_engine_fatal_error ( )

Definition at line 67 of file soc_manager_pimpl.cpp.

References foedus::soc::MasterEngineStatus::change_status_atomic(), foedus::soc::ChildEngineStatus::change_status_atomic(), engine_, foedus::soc::SharedMemoryRepo::get_global_memory_anchors(), foedus::soc::SharedMemoryRepo::get_node_memory_anchors(), foedus::Engine::get_soc_id(), foedus::DefaultInitializable::is_initialized(), foedus::Engine::is_master(), foedus::soc::MasterEngineStatus::kFatalError, foedus::soc::ChildEngineStatus::kFatalError, foedus::soc::GlobalMemoryAnchors::master_status_memory_, memory_repo_, and foedus::fs::status().

Referenced by foedus::soc::SocManager::report_engine_fatal_error().

67  {
68  if (!is_initialized()) {
69  std::cerr << "[FOEDUS] Shared memory not initialized yet. Can't report errors" << std::endl;
70  return;
71  }
72  if (engine_->is_master()) {
74  if (status) {
76  }
77  } else {
78  ChildEngineStatus* status = memory_repo_.get_node_memory_anchors(
79  engine_->get_soc_id())->child_status_memory_;
80  if (status) {
81  status->change_status_atomic(ChildEngineStatus::kFatalError);
82  }
83  }
84 }
GlobalMemoryAnchors * get_global_memory_anchors()
void change_status_atomic(StatusCode new_status)
Update the value of status_code_ with fence.
Whenever child observes this, they will call _exit() asap.
FileStatus status(const Path &p)
Returns the status of the file.
Definition: filesystem.cpp:45
NodeMemoryAnchors * get_node_memory_anchors(SocId node)
bool is_master() const
Returns if this engine object is a master instance.
Definition: engine.cpp:68
MasterEngineStatus * master_status_memory_
This tiny piece of memory contains the current status of the master engine and its synchronization me...
soc::SocId get_soc_id() const
If this is a child instance, returns its SOC ID (NUMA node).
Definition: engine.cpp:73
bool is_initialized() const override final
Returns whether the object has been already initialized or not.
The child engine observed some unrecoverable error and has exit.

Here is the call graph for this function:

Here is the caller graph for this function:

void foedus::soc::SocManagerPimpl::spawned_child_main ( const std::vector< proc::ProcAndName > &  procedures)
static

Main routine of spawned SOCs.

This is invoked from user's main(), so it's static.

Definition at line 568 of file soc_manager_pimpl.cpp.

References child_main_common(), foedus::ErrorStack::is_error(), and foedus::kChildLocalSpawned.

Referenced by foedus::soc::SocManager::trap_spawned_soc_main().

568  {
569  const char* master_upid_str = std::getenv("FOEDUS_MASTER_UPID");
570  const char* master_eid_str = std::getenv("FOEDUS_MASTER_EID");
571  const char* soc_id_str = std::getenv("FOEDUS_SOC_ID");
572  if (master_upid_str == nullptr || master_eid_str == nullptr || soc_id_str == nullptr) {
573  return; // not launched as an SOC engine. exit
574  }
575 
576  Upid master_upid = std::atoll(master_upid_str);
577  Eid master_eid = std::atoll(master_eid_str);
578  SocId node = std::atol(master_upid_str);
579  ErrorStack ret = child_main_common(kChildLocalSpawned, master_upid, master_eid, node, procedures);
580  if (ret.is_error()) {
581  std::cerr << "[FOEDUS-Child] Spawned SOC-" << node
582  << " exits with an error: " << ret << std::endl;
583  ::_exit(EXIT_FAILURE);
584  } else {
585  ::_exit(EXIT_SUCCESS);
586  }
587 }
static ErrorStack child_main_common(EngineType engine_type, Upid master_upid, Eid master_eid, SocId node, const std::vector< proc::ProcAndName > &procedures)
A child SOC instance launched via spawn().
Definition: engine_type.hpp:78
uint64_t Upid
Universal (or Unique) ID of a process.
Definition: soc_id.hpp:48
uint16_t SocId
Represents an ID of an SOC, or NUMA node.
Definition: soc_id.hpp:41
uint64_t Eid
An Engine ID to differentiate two Engine objects instantiated in the same process.
Definition: engine_type.hpp:29

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorStack foedus::soc::SocManagerPimpl::uninitialize_once ( )
overridevirtual

Implements foedus::DefaultInitializable.

Definition at line 57 of file soc_manager_pimpl.cpp.

References foedus::soc::SharedMemoryRepo::change_master_status(), CHECK_ERROR, foedus::soc::SharedMemoryRepo::deallocate_shared_memories(), engine_, foedus::soc::SharedMemoryRepo::get_global_memory(), foedus::Engine::is_master(), foedus::soc::MasterEngineStatus::kTerminated, memory_repo_, SUMMARIZE_ERROR_BATCH, and wait_for_child_terminate().

57  {
58  ErrorStackBatch batch;
59  if (engine_->is_master() && memory_repo_.get_global_memory() != nullptr) {
60  CHECK_ERROR(wait_for_child_terminate()); // wait for children to terminate
62  }
64  return SUMMARIZE_ERROR_BATCH(batch);
65 }
The master engine has normally terminated.
void change_master_status(MasterEngineStatus::StatusCode new_status)
void deallocate_shared_memories()
Detaches and releases the shared memories.
bool is_master() const
Returns if this engine object is a master instance.
Definition: engine.cpp:68
#define SUMMARIZE_ERROR_BATCH(x)
This macro calls ErrorStackBatch::summarize() with automatically provided parameters.
ErrorStack wait_for_child_terminate()
Wait for child SOCs to terminate.
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.

Here is the call graph for this function:

ErrorStack foedus::soc::SocManagerPimpl::wait_for_child_attach ( )

Wait for child SOCs to start up and at least finish attaching shared memory.

Definition at line 152 of file soc_manager_pimpl.cpp.

References foedus::soc::SharedMemoryRepo::change_master_status(), child_upids_, foedus::soc::SharedMemoryRepo::deallocate_shared_memories(), engine_, ERROR_STACK, foedus::soc::SharedMemoryRepo::get_child_status(), foedus::Engine::get_options(), foedus::thread::ThreadOptions::group_count_, foedus::kChildEmulated, foedus::kErrorCodeSocLaunchTimeout, foedus::kErrorCodeSocShmAttachFailed, foedus::soc::MasterEngineStatus::kFatalError, foedus::soc::ChildEngineStatus::kInitial, foedus::kRetOk, foedus::soc::ChildEngineStatus::kSharedMemoryAttached, foedus::soc::MasterEngineStatus::kSharedMemoryReservedReclamation, foedus::soc::SharedMemoryRepo::mark_for_release(), memory_repo_, foedus::assorted::os_error(), foedus::EngineOptions::soc_, foedus::soc::SocOptions::soc_type_, foedus::assorted::spinlock_yield(), foedus::fs::status(), and foedus::EngineOptions::thread_.

Referenced by launch_emulated_children(), launch_forked_children(), and launch_spawned_children().

152  {
153  // As of this method, glog is not initialized. So, use std::cerr only.
154  // When this method begins, the shared memory is in the most fragile state, not marked for
155  // reclamation but needs to be open for shmget. Be careful in this method!
156  // We avoid even assertions in this method.
157  // As soon as something unusual happens, we conservatively release the shared memory.
158  uint16_t soc_count = engine_->get_options().thread_.group_count_;
159 
160  // robustly wait until all children attached the shared memory.
161  // mark-for-reclaim as soon as possible.
162  const uint32_t kIntervalMillisecond = 20;
163  const uint32_t kTimeoutMillisecond = 10000;
164  uint32_t trials = 0;
165  bool child_as_process = engine_->get_options().soc_.soc_type_ != kChildEmulated;
166  while (true) {
168  std::this_thread::sleep_for(std::chrono::milliseconds(kIntervalMillisecond));
169  bool error_happened = false;
170  bool remaining = false;
171  for (uint16_t node = 0; node < soc_count; ++node) {
173  switch (child_status) {
175  remaining = true;
176  break;
178  break;
179  default:
180  // all other statuses are unexpected
181  error_happened = true;
182  break;
183  }
184  if (child_as_process) {
185  // if we launched the child as a process, let's also check with waitpid()
186  // this doesn't do anything if they are emulated children
187  if (!error_happened && child_upids_[node] != 0) {
188  int status = 0;
189  pid_t wait_ret = ::waitpid(child_upids_[node], &status, WNOHANG | __WALL);
190  if (wait_ret == -1) {
191  std::cerr << "[FOEDUS] FATAL! waitpid() for child-process " << child_upids_[node]
192  << " failed. os error=" << assorted::os_error() << std::endl;
193  error_happened = true;
194  break;
195  } else if (wait_ret != 0) {
196  std::cerr << "[FOEDUS] FATAL! child-process " << child_upids_[node] << " has exit"
197  << " unexpectedly. status=" << status << std::endl;
198  error_happened = true;
199  break;
200  }
201  }
202  }
203  }
204 
205  if (error_happened) {
206  std::cerr << "[FOEDUS] FATAL! Some child failed to attach shared memory." << std::endl;
210  } else if (!remaining) {
211  break; // done!
212  } else if ((++trials) * kIntervalMillisecond > kTimeoutMillisecond) {
213  std::cerr << "[FOEDUS] FATAL! Timeout happend while waiting for child SOCs to start up."
214  " Probably child SOC(s) hanged or did not trap SOC execution (if spawned)." << std::endl;
218  }
219  }
220 
221  // as soon as all children ack-ed, mark the shared memory for release.
222  // no one will newly issue shmget.
224  memory_repo_.mark_for_release(); // now it's safe. closed attaching and marked for reclaim.
225  return kRetOk;
226 }
Upid child_upids_[kMaxSocs]
Process IDs of child SOCs.
0x0C02 : "SOC : Failed to attach a shared memory." .
Definition: error_code.hpp:221
void change_master_status(MasterEngineStatus::StatusCode new_status)
#define ERROR_STACK(e)
Instantiates ErrorStack with the given foedus::error_code, creating an error stack with the current f...
StatusCode
These statuses represent each step described in SocManager comment.
void deallocate_shared_memories()
Detaches and releases the shared memories.
Whenever child observes this, they will call _exit() asap.
EngineType soc_type_
How to launch SOC engine instances.
Definition: soc_options.hpp:54
FileStatus status(const Path &p)
Returns the status of the file.
Definition: filesystem.cpp:45
void mark_for_release()
Marks shared memories as being removed so that it will be reclaimed when all processes detach it...
const EngineOptions & get_options() const
Definition: engine.cpp:39
Child engine successfully attached shared memory and waiting for master's kWaitingForChildInitializat...
uint16_t group_count_
Number of ThreadGroup in the engine.
0x0C06 : "SOC : Timeout happend while waiting for child SOCs to start up. Probably child SOC(s) ha...
Definition: error_code.hpp:225
void spinlock_yield()
Invoke _mm_pause(), x86 PAUSE instruction, or something equivalent in the env.
std::string os_error()
Thread-safe strerror(errno).
thread::ThreadOptions thread_
const ErrorStack kRetOk
Normal return value for no-error case.
ChildEngineStatus::StatusCode get_child_status(SocId node) const
Master engine successfully confirmed child's attach and reserved the reclamation of the shared memori...
A child SOC instance launched just as a thread in the same process as master.
Definition: engine_type.hpp:51

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorStack foedus::soc::SocManagerPimpl::wait_for_child_terminate ( )

Wait for child SOCs to terminate.

Definition at line 228 of file soc_manager_pimpl.cpp.

References foedus::soc::SharedMemoryRepo::change_master_status(), child_emulated_threads_, child_upids_, engine_, ERROR_STACK, foedus::soc::SharedMemoryRepo::get_child_status(), foedus::Engine::get_options(), foedus::thread::ThreadOptions::group_count_, foedus::kChildEmulated, foedus::kErrorCodeSocTerminateFailed, foedus::kErrorCodeSocTerminateTimeout, foedus::soc::MasterEngineStatus::kFatalError, foedus::soc::ChildEngineStatus::kFatalError, foedus::kRetOk, foedus::soc::ChildEngineStatus::kRunning, foedus::soc::ChildEngineStatus::kTerminated, memory_repo_, foedus::EngineOptions::soc_, foedus::soc::SocOptions::soc_type_, foedus::assorted::spinlock_yield(), foedus::fs::status(), and foedus::EngineOptions::thread_.

Referenced by uninitialize_once().

228  {
229  uint16_t soc_count = engine_->get_options().thread_.group_count_;
230  const uint32_t kIntervalMillisecond = 20;
231  const uint32_t kTimeoutMillisecond = 10000;
232  uint32_t trials = 0;
233  bool child_as_process = engine_->get_options().soc_.soc_type_ != kChildEmulated;
234  while (true) {
236  std::this_thread::sleep_for(std::chrono::milliseconds(kIntervalMillisecond));
237  bool remaining = false;
238  for (uint16_t node = 0; node < soc_count; ++node) {
240  if (!child_as_process) {
241  if (child_status == ChildEngineStatus::kTerminated
242  || child_status == ChildEngineStatus::kFatalError) {
243  if (child_emulated_threads_[node].joinable()) {
244  child_emulated_threads_[node].join();
245  }
246  } else {
247  if (child_emulated_threads_[node].joinable()) {
248  remaining = true;
249  }
250  }
251  continue;
252  }
253  if (child_status == ChildEngineStatus::kRunning) {
254  // also check with waitpid(). if the child process terminated, it's fine.
255  if (child_upids_[node] != 0) {
256  int status = 0;
257  pid_t wait_ret = ::waitpid(child_upids_[node], &status, WNOHANG | __WALL);
258  if (wait_ret == -1) {
259  // this is okay, too. the process has already terminated
260  } else if (wait_ret == 0) {
261  remaining = true;
262  } else if (WIFSIGNALED(status)) {
263  std::cerr << "[FOEDUS] ERROR! child-process " << child_upids_[node] << " has been"
264  << " terminated by signal. status=" << status << std::endl;
267  }
268  }
269  }
270  }
271 
272  if (!remaining) {
273  break; // done!
274  } else if ((++trials) * kIntervalMillisecond > kTimeoutMillisecond) {
275  std::cerr << "[FOEDUS] ERROR! Timeout happend while waiting for child SOCs to terminate."
276  " Probably child SOC(s) hanged or did not trap SOC execution (if spawned)." << std::endl;
279  }
280  }
281 
282  return kRetOk;
283 }
Upid child_upids_[kMaxSocs]
Process IDs of child SOCs.
void change_master_status(MasterEngineStatus::StatusCode new_status)
#define ERROR_STACK(e)
Instantiates ErrorStack with the given foedus::error_code, creating an error stack with the current f...
StatusCode
These statuses represent each step described in SocManager comment.
std::vector< std::thread > child_emulated_threads_
Threads that emulate child SOCs.
Whenever child observes this, they will call _exit() asap.
EngineType soc_type_
How to launch SOC engine instances.
Definition: soc_options.hpp:54
0x0C0A : "SOC : Failed to normally terminate some SOC(s).." .
Definition: error_code.hpp:229
FileStatus status(const Path &p)
Returns the status of the file.
Definition: filesystem.cpp:45
const EngineOptions & get_options() const
Definition: engine.cpp:39
The child engine has normally terminated.
0x0C09 : "SOC : Timeout happend while waiting for child SOCs to terminate. Probably child SOC(s) h...
Definition: error_code.hpp:228
uint16_t group_count_
Number of ThreadGroup in the engine.
void spinlock_yield()
Invoke _mm_pause(), x86 PAUSE instruction, or something equivalent in the env.
thread::ThreadOptions thread_
const ErrorStack kRetOk
Normal return value for no-error case.
Done all initialization and running transactions.
ChildEngineStatus::StatusCode get_child_status(SocId node) const
The child engine observed some unrecoverable error and has exit.
A child SOC instance launched just as a thread in the same process as master.
Definition: engine_type.hpp:51

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorStack foedus::soc::SocManagerPimpl::wait_for_children_module ( bool  init,
ModuleType  module 
)

Definition at line 360 of file soc_manager_pimpl.cpp.

References ASSERT_ND, foedus::soc::NodeMemoryAnchors::child_status_memory_, child_upids_, engine_, ERROR_STACK, foedus::soc::SharedMemoryRepo::get_node_memory_anchors(), foedus::Engine::get_options(), foedus::thread::ThreadOptions::group_count_, foedus::soc::ChildEngineStatus::initialized_modules_, foedus::kChildEmulated, foedus::kErrorCodeSocChildInitFailed, foedus::kErrorCodeSocChildUninitFailed, foedus::soc::ChildEngineStatus::kFatalError, foedus::kRetOk, foedus::kSoc, foedus::assorted::memory_fence_acq_rel(), memory_repo_, foedus::EngineOptions::soc_, foedus::soc::SocOptions::soc_type_, foedus::assorted::spinlock_yield(), foedus::fs::status(), foedus::soc::ChildEngineStatus::status_code_, foedus::EngineOptions::thread_, and foedus::soc::ChildEngineStatus::uninitialized_modules_.

Referenced by foedus::soc::SocManager::wait_for_children_module().

360  {
361  ASSERT_ND(desired != kSoc); // this method assumes SOC manager is active
362  uint16_t soc_count = engine_->get_options().thread_.group_count_;
363  bool child_as_process = engine_->get_options().soc_.soc_type_ != kChildEmulated;
364 
365  // TASK(Hideaki) should be a function in soc manager
366  // We also check if the child died unexpectedly
367  const uint32_t kWarnSleeps = 400;
368  for (uint32_t count = 0;; ++count) {
369  if (count > 0 && count % kWarnSleeps == 0) {
370  LOG(WARNING) << "Suspiciously long wait for child " << (init ? "" : "un") << "initializing"
371  << " module-" << desired << ". count=" << count;
372  }
374  std::this_thread::sleep_for(std::chrono::milliseconds(5));
376  bool error_happened = false;
377  bool remaining = false;
378  for (uint16_t node = 0; node < soc_count; ++node) {
379  soc::ChildEngineStatus* status
381  if (status->status_code_ == soc::ChildEngineStatus::kFatalError) {
382  error_happened = true;
383  break;
384  }
385  if (init) {
386  if (status->initialized_modules_ == desired) {
387  continue; // ok
388  } else if (static_cast<int>(status->initialized_modules_)
389  > static_cast<int>(desired)) {
390  LOG(ERROR) << "[FOEDUS] child init went too far??";
391  error_happened = true;
392  break;
393  }
394  } else {
395  if (status->uninitialized_modules_ == desired) {
396  continue; // ok
397  } else if (static_cast<int>(status->uninitialized_modules_)
398  < static_cast<int>(desired)) {
399  LOG(ERROR) << "[FOEDUS] ERROR! child uninit went too far??";
400  error_happened = true;
401  break;
402  }
403  }
404  remaining = true;
405  if (child_as_process) {
406  // TASK(Hideaki) check child process status with waitpid
407  if (child_upids_[node] != 0) {
408  int status = 0;
409  pid_t wait_ret = ::waitpid(child_upids_[node], &status, WNOHANG | __WALL);
410  if (wait_ret == -1) {
411  // this is okay, too. the process has already terminated
412  error_happened = true;
413  LOG(ERROR) << "waitpid() while waiting for child module status failed";
414  break;
415  } else if (wait_ret != 0) {
416  // this is okay
417  error_happened = true;
418  LOG(ERROR) << "child process has already exit while waiting for child module status";
419  break;
420  }
421  }
422  }
423  }
424 
425  if (error_happened) {
426  LOG(ERROR) << "Error encountered in wait_for_children_module";
427  if (init) {
429  } else {
431  }
432  } else if (!remaining) {
433  break;
434  }
435  }
436  return kRetOk;
437 }
Upid child_upids_[kMaxSocs]
Process IDs of child SOCs.
#define ERROR_STACK(e)
Instantiates ErrorStack with the given foedus::error_code, creating an error stack with the current f...
EngineType soc_type_
How to launch SOC engine instances.
Definition: soc_options.hpp:54
FileStatus status(const Path &p)
Returns the status of the file.
Definition: filesystem.cpp:45
NodeMemoryAnchors * get_node_memory_anchors(SocId node)
0x0C0B : "SOC : Child SOC failed to initialize a module." .
Definition: error_code.hpp:230
const EngineOptions & get_options() const
Definition: engine.cpp:39
uint16_t group_count_
Number of ThreadGroup in the engine.
void spinlock_yield()
Invoke _mm_pause(), x86 PAUSE instruction, or something equivalent in the env.
thread::ThreadOptions thread_
const ErrorStack kRetOk
Normal return value for no-error case.
ChildEngineStatus * child_status_memory_
This tiny piece of memory contains the current status of the child engine on this node...
0x0C0C : "SOC : Child SOC failed to uninitialize a module." .
Definition: error_code.hpp:231
#define ASSERT_ND(x)
A warning-free wrapper macro of assert() that has no performance effect in release mode even when 'x'...
Definition: assert_nd.hpp:72
The child engine observed some unrecoverable error and has exit.
void memory_fence_acq_rel()
Equivalent to std::atomic_thread_fence(std::memory_order_acq_rel).
A child SOC instance launched just as a thread in the same process as master.
Definition: engine_type.hpp:51

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorStack foedus::soc::SocManagerPimpl::wait_for_master_module ( bool  init,
ModuleType  module 
)

Definition at line 327 of file soc_manager_pimpl.cpp.

References ERROR_STACK, foedus::soc::SharedMemoryRepo::get_global_memory_anchors(), foedus::soc::MasterEngineStatus::initialized_modules_, foedus::kErrorCodeSocChildInitFailed, foedus::kErrorCodeSocChildUninitFailed, foedus::soc::MasterEngineStatus::kFatalError, foedus::kRetOk, foedus::soc::MasterEngineStatus::kTerminated, foedus::soc::GlobalMemoryAnchors::master_status_memory_, foedus::assorted::memory_fence_acq_rel(), memory_repo_, foedus::assorted::spinlock_yield(), foedus::fs::status(), foedus::soc::MasterEngineStatus::status_code_, and foedus::soc::MasterEngineStatus::uninitialized_modules_.

Referenced by foedus::soc::SocManager::wait_for_master_module().

327  {
328  const uint32_t kWarnSleeps = 400;
329  for (uint32_t count = 0;; ++count) {
330  if (count > 0 && count % kWarnSleeps == 0) {
331  LOG(WARNING) << "Suspiciously long wait for master " << (init ? "" : "un") << "initializing"
332  << " module-" << desired << ". count=" << count;
333  }
334  soc::MasterEngineStatus* status
336  if (status->status_code_ == MasterEngineStatus::kFatalError
337  || status->status_code_ == MasterEngineStatus::kTerminated) {
338  LOG(ERROR) << "Master apparently died while wait_for_master_module";
339  if (init) {
341  } else {
343  }
344  }
347  ModuleType cur;
348  if (init) {
349  cur = status->initialized_modules_;
350  } else {
351  cur = status->uninitialized_modules_;
352  }
353  if (cur == desired) {
354  break;
355  }
356  std::this_thread::sleep_for(std::chrono::milliseconds(5));
357  }
358  return kRetOk;
359 }
The master engine has normally terminated.
#define ERROR_STACK(e)
Instantiates ErrorStack with the given foedus::error_code, creating an error stack with the current f...
GlobalMemoryAnchors * get_global_memory_anchors()
Whenever child observes this, they will call _exit() asap.
FileStatus status(const Path &p)
Returns the status of the file.
Definition: filesystem.cpp:45
0x0C0B : "SOC : Child SOC failed to initialize a module." .
Definition: error_code.hpp:230
ModuleType
Enumerates modules in FOEDUS engine.
Definition: module_type.hpp:26
void spinlock_yield()
Invoke _mm_pause(), x86 PAUSE instruction, or something equivalent in the env.
const ErrorStack kRetOk
Normal return value for no-error case.
MasterEngineStatus * master_status_memory_
This tiny piece of memory contains the current status of the master engine and its synchronization me...
0x0C0C : "SOC : Child SOC failed to uninitialize a module." .
Definition: error_code.hpp:231
void memory_fence_acq_rel()
Equivalent to std::atomic_thread_fence(std::memory_order_acq_rel).

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorStack foedus::soc::SocManagerPimpl::wait_for_master_status ( MasterEngineStatus::StatusCode  target_status)

Wait for master engine to finish upto the specified status.

Definition at line 286 of file soc_manager_pimpl.cpp.

References ASSERT_ND, engine_, ERROR_STACK, foedus::soc::SharedMemoryRepo::get_master_status(), foedus::Engine::is_master(), foedus::kErrorCodeSocMasterDied, foedus::kErrorCodeSocMasterUnexpectedState, foedus::soc::MasterEngineStatus::kFatalError, foedus::kRetOk, memory_repo_, and foedus::assorted::spinlock_yield().

Referenced by child_main_common(), and initialize_child().

286  {
288  const uint32_t kIntervalMillisecond = 10;
289 // bool child_as_process = engine_->get_options().soc_.soc_type_ != kChildEmulated;
290  while (true) {
292  std::this_thread::sleep_for(std::chrono::milliseconds(kIntervalMillisecond));
294  if (master_status == target_status) {
295  break; // wait done
296  } else if (master_status == MasterEngineStatus::kFatalError) {
298  } else if (static_cast<int>(master_status) > static_cast<int>(target_status)) {
300  }
301 /*
302  this doesn't work because waitpid is only for child processes.
303  As an alternative to die when parent dies, we use prctl().
304  if (child_as_process) {
305  // Also check parent's process status.
306  Upid master_upid = engine_->get_master_upid();
307  int status = 0;
308  pid_t wait_ret = ::waitpid(master_upid, &status, WNOHANG);
309  if (wait_ret == -1) {
310  std::cerr << "[FOEDUS-Child] FATAL! waitpid() for master-process " << master_upid
311  << " failed. os error:" << assorted::os_error() << std::endl;
312  return ERROR_STACK(kErrorCodeSocMasterDied);
313  } else if (WIFEXITED(status)) {
314  std::cerr << "[FOEDUS-Child] FATAL! master-process " << master_upid << " has exit"
315  << " unexpectedly. status=" << status << std::endl;
316  return ERROR_STACK(kErrorCodeSocMasterDied);
317  } else if (WIFSIGNALED(status)) {
318  std::cerr << "[FOEDUS-Child] FATAL! master-process " << master_upid << " has been"
319  << " terminated by signal. status=" << status << std::endl;
320  return ERROR_STACK(kErrorCodeSocMasterDied);
321  }
322  }
323 */
324  }
325  return kRetOk;
326 }
#define ERROR_STACK(e)
Instantiates ErrorStack with the given foedus::error_code, creating an error stack with the current f...
Whenever child observes this, they will call _exit() asap.
bool is_master() const
Returns if this engine object is a master instance.
Definition: engine.cpp:68
0x0C07 : "SOC : Master engine died unexpectedly. This child engine will follow." .
Definition: error_code.hpp:226
void spinlock_yield()
Invoke _mm_pause(), x86 PAUSE instruction, or something equivalent in the env.
const ErrorStack kRetOk
Normal return value for no-error case.
0x0C08 : "SOC : The status of master engine is unexpected." .
Definition: error_code.hpp:227
#define ASSERT_ND(x)
A warning-free wrapper macro of assert() that has no performance effect in release mode even when 'x'...
Definition: assert_nd.hpp:72
StatusCode
These statuses represent each step described in SocManager comment.
MasterEngineStatus::StatusCode get_master_status() const

Here is the call graph for this function:

Here is the caller graph for this function:

Member Data Documentation

std::vector< Engine* > foedus::soc::SocManagerPimpl::child_emulated_engines_

And their engines.

These pointers become invalid when the threads quit

Definition at line 95 of file soc_manager_pimpl.hpp.

Referenced by initialize_master(), and launch_emulated_children().

std::vector<std::thread> foedus::soc::SocManagerPimpl::child_emulated_threads_

Threads that emulate child SOCs.

Used when this is a master engine and also children are emulated.

Definition at line 93 of file soc_manager_pimpl.hpp.

Referenced by initialize_master(), launch_emulated_children(), and wait_for_child_terminate().

Upid foedus::soc::SocManagerPimpl::child_upids_[kMaxSocs]

Process IDs of child SOCs.

Used when this is a master engine and also children are not emulated.

Definition at line 101 of file soc_manager_pimpl.hpp.

Referenced by initialize_master(), launch_forked_children(), launch_spawned_children(), wait_for_child_attach(), wait_for_child_terminate(), and wait_for_children_module().


The documentation for this class was generated from the following files: