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