SST  15.1.0
StructuralSimulationToolkit
shmparent.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_SHM_PARENT_H
13 #define SST_CORE_INTERPROCESS_TUNNEL_SHM_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 /** Class supports an IPC tunnel between two or more processes via posix shared memory
30  * This class creates the tunnel for the parent/master process
31  *
32  * @tparam TunnelType Tunnel definition
33  */
34 template <typename TunnelType>
35 class SHMParent
36 {
37 
38 public:
39  /** Parent/master manager for an IPC tunnel
40  * Creates a shared memory region and initializes a
41  * TunnelType data strucgture in the region
42  *
43  * @param comp_id Component ID of owner
44  * @param numBuffers Number of buffers for which we should tunnel
45  * @param bufferSize How large each core's buffer should be
46  * @param expectedChildren How many child processes will connect to the tunnel
47  */
48  SHMParent(uint32_t comp_id, size_t numBuffers, size_t bufferSize, uint32_t expectedChildren = 1) :
49  shmPtr(nullptr),
50  fd(-1)
51  {
52  char key[256];
53  memset(key, '\0', sizeof(key));
54  do {
55  snprintf(key, sizeof(key), "/sst_shmem_%u-%" PRIu32 "-%d", getpid(), comp_id, rand());
56  filename = key;
57 
58  fd = shm_open(filename.c_str(), O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
59  /* There's a rare chance that a file we are looking to use exists.
60  * It's unlikely, but perhaps a previous run (with the same PID
61  * and random number) crashed before the * clients all connected.
62  *
63  * So, if we get an error, and the error is EEXIST, try again with
64  * a different random number.
65  */
66  } while ( (fd < 0) && (errno == EEXIST) );
67  if ( fd < 0 ) {
68  // Not using Output because IPC means Output might not be available
69  fprintf(stderr, "Failed to create IPC region '%s': %s\n", filename.c_str(), strerror(errno));
70  exit(1);
71  }
72 
73  tunnel = new TunnelType(numBuffers, bufferSize, expectedChildren);
74  shmSize = tunnel->getTunnelSize();
75 
76  if ( ftruncate(fd, shmSize) ) {
77  // Not using Output because IPC means Output might not be available
78  fprintf(stderr, "Resizing shared file '%s' failed: %s\n", filename.c_str(), strerror(errno));
79  exit(1);
80  }
81 
82  shmPtr = mmap(nullptr, shmSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
83  if ( shmPtr == MAP_FAILED ) {
84  // Not using Output because IPC means Output might not be available
85  fprintf(stderr, "mmap failed: %s\n", strerror(errno));
86  exit(1);
87  }
88  memset(shmPtr, '\0', shmSize);
89  tunnel->initialize(shmPtr);
90  }
91 
92  /** Destructor */
93  virtual ~SHMParent()
94  {
95  delete tunnel;
96  if ( shmPtr ) {
97  munmap(shmPtr, shmSize);
98  shmPtr = nullptr;
99  shmSize = 0;
100  }
101  if ( fd >= 0 ) {
102  close(fd);
103  fd = -1;
104  }
105  }
106 
107  /** returns name of the mmap'd region */
108  const std::string& getRegionName() const { return filename; }
109 
110  /** return the created tunnel pointer */
111  TunnelType* getTunnel() { return tunnel; }
112 
113 private:
114  void* shmPtr;
115  int fd;
116 
117  std::string filename;
118  size_t shmSize;
119 
120  TunnelType* tunnel;
121 };
122 
123 } // namespace SST::Core::Interprocess
124 
125 #endif // SST_CORE_INTERPROCESS_TUNNEL_SHM_PARENT_H
virtual ~SHMParent()
Destructor.
Definition: shmparent.h:93
const std::string & getRegionName() const
returns name of the mmap&#39;d region
Definition: shmparent.h:108
Definition: circularBuffer.h:20
SHMParent(uint32_t comp_id, size_t numBuffers, size_t bufferSize, uint32_t expectedChildren=1)
Parent/master manager for an IPC tunnel Creates a shared memory region and initializes a TunnelType d...
Definition: shmparent.h:48
Class supports an IPC tunnel between two or more processes via posix shared memory This class creates...
Definition: shmparent.h:35
TunnelType * getTunnel()
return the created tunnel pointer
Definition: shmparent.h:111