SST  15.1.0
StructuralSimulationToolkit
mmapparent.h
1 // Copyright 2009-2025 NTESS. Under the terms
2 // of Contract DE-NA0003525 with NTESS, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2025, NTESS
6 // All rights reserved.
7 //
8 // This file is part of the SST software package. For license
9 // information, see the LICENSE file in the top level directory of the
10 // distribution.
11 
12 #ifndef SST_CORE_INTERPROCESS_TUNNEL_MMAP_PARENT_H
13 #define SST_CORE_INTERPROCESS_TUNNEL_MMAP_PARENT_H
14 
15 #include <cstddef>
16 #include <cstdio>
17 #include <cstdlib>
18 #include <cstring>
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <inttypes.h>
22 #include <string>
23 #include <sys/mman.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 
27 namespace SST::Core::Interprocess {
28 
29 /** EXPERIMENTAL: Launch an MPI application. This is a wrapper around MPI_Comm_spawn_multiple
30  * that hides all MPI information from the calling process. This is intended to be used
31  * by elements that need to launch other processes, such as Ariel. Even if the launched
32  * application does not use MPI, this function should be used as fork() should not be used
33  * by MPI applications.
34  *
35  * @param count Number of commands
36  * @param array_of_commands Commands to run
37  * @param array_of_argv Argv for each command
38  * @param array_of_maxprocs The maximum number of procs for each command
39  * @param array_of_env A newline-delimited list of environment variables for each command
40  */
41 int SST_MPI_Comm_spawn_multiple(int count, char* array_of_commands[], char** array_of_argv[],
42  const int array_of_maxprocs[], const char* array_of_env[]);
43 
44 /** Class supports an IPC tunnel between two or more processes, via an mmap'd file.
45  * This class creates the tunnel for the parent/master process
46  *
47  * @tparam TunnelType Tunnel definition
48  */
49 template <typename TunnelType>
51 {
52 
53 public:
54  /** Parent/master manager for an IPC Tunnel
55  * Creates a memory-mapped file and initializes a
56  * TunnelType data structure in the mmap'd region
57  *
58  * @param comp_id Component ID of owner
59  * @param numBuffers Number of buffers for which we should tunnel
60  * @param bufferSize How large each core's buffer should be
61  * @expectedChildren How many child processes will connect to the tunnel
62  */
63  MMAPParent(uint32_t comp_id, size_t numBuffers, size_t bufferSize, uint32_t expectedChildren = 1) :
64  shmPtr(nullptr),
65  fd(-1)
66  {
67  char key[256];
68  memset(key, '\0', sizeof(key));
69  do {
70  snprintf(key, sizeof(key), "/tmp/sst_shmem_%u-%" PRIu32 "-%d", getpid(), comp_id, rand());
71  filename = key;
72 
73  fd = open(filename.c_str(), O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
74  /* There's a rare chance that a file we are looking to use exists.
75  * It's unlikely, but perhaps a previous run (with the same PID
76  * and random number) crashed before the * clients all connected.
77  *
78  * So, if we get an error, and the error is EEXIST, try again with
79  * a different random number.
80  */
81  } while ( (fd < 0) && (errno == EEXIST) );
82 
83  if ( fd < 0 ) {
84  // Not using Output because IPC means Output might not be available
85  fprintf(stderr, "Failed to create IPC region '%s': %s\n", filename.c_str(), strerror(errno));
86  exit(1);
87  }
88 
89  tunnel = new TunnelType(numBuffers, bufferSize, expectedChildren);
90  shmSize = tunnel->getTunnelSize();
91 
92  if ( ftruncate(fd, shmSize) ) {
93  // Not using Output because IPC means Output might not be available
94  fprintf(stderr, "Resizing shared file '%s' failed: %s\n", filename.c_str(), strerror(errno));
95  exit(1);
96  }
97 
98  shmPtr = mmap(nullptr, shmSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
99  if ( shmPtr == MAP_FAILED ) {
100  // Not using Output because IPC means Output might not be available
101  fprintf(stderr, "mmap failed: %s\n", strerror(errno));
102  exit(1);
103  }
104  close(fd);
105 
106  memset(shmPtr, '\0', shmSize);
107  tunnel->initialize(shmPtr);
108  }
109 
110  /** Destructor */
111  virtual ~MMAPParent()
112  {
113  delete tunnel;
114 
115  munmap(shmPtr, shmSize);
116  if ( remove(filename.c_str()) != 0 ) {
117  fprintf(stderr, "Error deleting tunnel file: %s\n", filename.c_str());
118  }
119  }
120 
121  /** returns name of the mmap'd file */
122  const std::string& getRegionName() const { return filename; }
123 
124  /** return the created tunnel pointer */
125  TunnelType* getTunnel() { return tunnel; }
126 
127 private:
128  void* shmPtr;
129  int fd;
130 
131  std::string filename;
132  size_t shmSize;
133 
134  TunnelType* tunnel;
135 };
136 
137 } // namespace SST::Core::Interprocess
138 
139 #endif // SST_CORE_INTERPROCESS_TUNNEL_MMAP_PARENT_H
virtual ~MMAPParent()
Destructor.
Definition: mmapparent.h:111
Definition: circularBuffer.h:20
const std::string & getRegionName() const
returns name of the mmap&#39;d file
Definition: mmapparent.h:122
MMAPParent(uint32_t comp_id, size_t numBuffers, size_t bufferSize, uint32_t expectedChildren=1)
Parent/master manager for an IPC Tunnel Creates a memory-mapped file and initializes a TunnelType dat...
Definition: mmapparent.h:63
TunnelType * getTunnel()
return the created tunnel pointer
Definition: mmapparent.h:125
Class supports an IPC tunnel between two or more processes, via an mmap&#39;d file.
Definition: mmapparent.h:50