CPN
Computational Process Networks
Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
MirrorBufferSet Class Reference

#include <MirrorBufferSet.h>

+ Collaboration diagram for MirrorBufferSet:

Public Types

enum  { eNotSupported =0, eSupportedPosixShm, eSupportedTmpFile }
 
typedef unsigned long ulong
 

Public Member Functions

 MirrorBufferSet (ulong bufferSz, ulong mirrorSz, int nBuffers=1)
 
 ~MirrorBufferSet (void)
 
ulong BufferSize (void) const
 
ulong MirrorSize (void) const
 
ulong NumBuffers (void) const
 
 operator void * (void) const
 

Static Public Member Functions

static int Supported (void)
 
static ulong PageSize (void)
 

Protected Member Functions

int GetFileDescriptor (void)
 

Protected Attributes

void * bufferBase
 
ulong bufferSize
 
ulong mirrorSize
 
int numBuffers
 
char fileName [112]
 

Detailed Description

Definition at line 27 of file MirrorBufferSet.h.

Member Typedef Documentation

typedef unsigned long MirrorBufferSet::ulong

Definition at line 29 of file MirrorBufferSet.h.

Member Enumeration Documentation

anonymous enum
Enumerator
eNotSupported 
eSupportedPosixShm 
eSupportedTmpFile 

Definition at line 38 of file MirrorBufferSet.h.

Constructor & Destructor Documentation

MirrorBufferSet::MirrorBufferSet ( ulong  bufferSz,
ulong  mirrorSz,
int  nBuffers = 1 
)

Definition at line 140 of file MirrorBufferSet.cc.

References bufferBase, bufferSize, fileName, fprintf1, fprintf2, GetFileDescriptor(), MAP_FAILED, MAP_NORESERVE, mirrorSize, numBuffers, PageSize(), and StrError().

142 : bufferBase(0),
143  bufferSize(bufferSz),
144  mirrorSize(mirrorSz),
145  numBuffers(nBuffers)
146 {
147  fileName[0] = 0;
148  ulong pageSize = PageSize();
149 
150  // if bufferSize or mirrorSize are not a multiple of pageSize, round them up
151  if (bufferSize % pageSize) {
152  bufferSize += pageSize - (bufferSize % pageSize);
153  }
154  if (mirrorSize % pageSize) {
155  mirrorSize += pageSize - (mirrorSize % pageSize);
156  }
157 
158 #if 1
159  // do a sanity check for our math
160  if ( bufferSize % pageSize)
161  fprintf(stderr, "### Error: bufferSize = %lu is not a multiple of pageSize = %lu\n",
162  bufferSize, pageSize);
163  if ( mirrorSize % pageSize)
164  fprintf(stderr, "### Error: mirrorSize = %lu is not a multiple of pageSize = %lu\n",
165  mirrorSize, pageSize);
166 #endif
167 
168  int fd = GetFileDescriptor();
169 
170  // make the file large enough
171  ulong numBytes = (bufferSize+mirrorSize) * numBuffers;
172  if ( ftruncate(fd, numBytes) ) {
173  perror("ftruncate");
174  close(fd);
175  throw std::runtime_error(StrError(errno));
176  }
177 
178  // map the entire buffer space, so there will be enough space reserved
179  fprintf1((stderr,"MirrorBufferSet: reserving %lu bytes for mapping ", numBytes));
180  caddr_t baseAddr = (caddr_t) mmap(0, numBytes, PROT_READ|PROT_WRITE,
181  MAP_SHARED|MAP_NORESERVE, fd, (off_t)0);
182  if (baseAddr == MAP_FAILED) {
183  fprintf1((stderr,"failed\n"));
184  perror("mmap");
185  close(fd);
186  throw std::runtime_error(StrError(errno));
187  }
188  bufferBase = baseAddr;
189  fprintf1((stderr,"[%p - %p)\n", (void*)baseAddr, (void*)(baseAddr+numBytes)));
190  fprintf1((stderr,"MirrorBufferSet: file \"%s\" is %d bytes\n",
191  fileName, (int)(bufferSize*numBuffers)));
192 
193  // now map each of the individual buffers twice
194  for (int buf=0; buf<numBuffers; buf++) {
195  // once for the buffer
196  caddr_t theAddr = baseAddr+buf*(bufferSize+mirrorSize);
197  size_t theSize = bufferSize;
198  off_t theOffset = buf*bufferSize;
199  fprintf2((stderr,"mapping 0x%06lX bytes @ offset 0x%06lX ", (long unsigned)theSize, (long unsigned)theOffset));
200  caddr_t addr = (caddr_t) mmap(theAddr, theSize, PROT_READ|PROT_WRITE,
201  MAP_SHARED|MAP_FIXED|MAP_NORESERVE, fd, theOffset);
202  if (addr == MAP_FAILED) {
203  fprintf2((stderr,"failed\n"));
204  perror("mmap");
205  close(fd);
206  throw std::runtime_error(StrError(errno));
207  }
208  fprintf2((stderr,"to [%p - %p)\n", (void*)theAddr, (void*)(theAddr+theSize)));
209  if (addr!=theAddr) {
210  fprintf(stderr, "### Error: mapped to 0x%p instead of 0x%p\n",
211  addr, theAddr );
212  close(fd);
213  throw std::runtime_error(StrError(errno));
214  }
215 
216  // and again for the mirror
217  theAddr +=bufferSize;
218  theSize = mirrorSize;
219  fprintf2((stderr,"mapping 0x%06lX bytes @ offset 0x%06lX ", (long unsigned)theSize, (long unsigned)theOffset));
220  addr = (caddr_t) mmap(theAddr, theSize, PROT_READ|PROT_WRITE,
221  MAP_SHARED|MAP_FIXED|MAP_NORESERVE, fd, theOffset);
222  if (addr == MAP_FAILED) {
223  fprintf2((stderr,"failed\n"));
224  perror("mmap");
225  close(fd);
226  throw std::runtime_error(StrError(errno));
227  }
228  fprintf2((stderr,"to [%p - %p)\n", (void*)theAddr, (void*)(theAddr+theSize)));
229  if (addr!=theAddr) {
230  fprintf(stderr, "### Error: mapped to 0x%p instead of 0x%p\n", addr, theAddr );
231  close(fd);
232  throw std::runtime_error(StrError(errno));
233  }
234  }
235 
236  // close the file
237  if ( close(fd) ) {
238  perror("close");
239  }
240 }
#define fprintf2(p)
#define fprintf1(p)
std::string StrError(int error)
int GetFileDescriptor(void)
unsigned long ulong
char fileName[112]
static ulong PageSize(void)
#define MAP_NORESERVE
#define MAP_FAILED

+ Here is the call graph for this function:

MirrorBufferSet::~MirrorBufferSet ( void  )

Definition at line 290 of file MirrorBufferSet.cc.

References bufferBase, bufferSize, fileName, fprintf2, mirrorSize, and numBuffers.

292 {
293  if (!bufferBase) return;
294 
295  // unmap the file
296  if ( munmap((caddr_t)bufferBase, (bufferSize+mirrorSize)*numBuffers) ) {
297  perror("munmap");
298  }
299  fprintf2((stderr,"unmapped- \"%s\" [%p - %p), %lu bytes\n",
300  fileName, bufferBase,
301  (void*)((char*)bufferBase+((bufferSize+mirrorSize)*numBuffers)),
302  ((bufferSize+mirrorSize)*numBuffers)));
303 }
#define fprintf2(p)
char fileName[112]

Member Function Documentation

ulong MirrorBufferSet::BufferSize ( void  ) const
inline

Definition at line 34 of file MirrorBufferSet.h.

References bufferSize.

Referenced by ThresholdQueueBase::AllocateBuf().

34 { return bufferSize; }

+ Here is the caller graph for this function:

int MirrorBufferSet::GetFileDescriptor ( void  )
protected

Definition at line 244 of file MirrorBufferSet.cc.

References fileName, and fprintf2.

Referenced by MirrorBufferSet().

246 {
247  // get a temporary file name
248 #if MBS_USE_POSIX_SHM
249  unsigned i = 0;
250  while (true) {
251  sprintf(fileName, "/MirrorBufferSet-%u", i);
252  #if defined(OS_IRIX) || defined(OS_HPUX)
253  // these platforms don't do shm_open as defined in the spec
254  tmpnam(fileName);
255  fprintf2((stderr,"tmpnam returned \"%s\"\n",fileName));
256  #endif
257  fprintf2((stderr,"calling shm_open with \"%s\"\n",fileName));
258  int fd = shm_open(fileName,O_RDWR|O_CREAT|O_EXCL,0600);
259  if (fd < 0) {
260  if (errno == EEXIST) {
261  ++i;
262  } else{
263  fprintf(stderr, "shm_open \"%s\": ", fileName);
264  perror(0);
265  return -1;
266  }
267  } else {
268  // remove the shared memory object
269  if ( shm_unlink(fileName) ) {
270  fprintf(stderr, "### shm_unlink(\"%s\") failed: ", fileName);
271  perror(0);
272  }
273  return fd;
274  }
275  }
276 #else
277  sprintf(fileName, "/tmp/MirrorBufferSet-XXXXXX");
278  int fd = mkstemp(fileName);
279  // remove the temporary file
280  if ( unlink(fileName) ) {
281  fprintf(stderr, "### unlink(\"%s\") failed: ", fileName);
282  perror(0);
283  }
284  return fd;
285 #endif
286 }
#define fprintf2(p)
char fileName[112]

+ Here is the caller graph for this function:

ulong MirrorBufferSet::MirrorSize ( void  ) const
inline

Definition at line 35 of file MirrorBufferSet.h.

References mirrorSize.

Referenced by ThresholdQueueBase::AllocateBuf().

35 { return mirrorSize; }

+ Here is the caller graph for this function:

ulong MirrorBufferSet::NumBuffers ( void  ) const
inline

Definition at line 36 of file MirrorBufferSet.h.

References numBuffers.

36 { return numBuffers; }
MirrorBufferSet::operator void * ( void  ) const
inline

Definition at line 43 of file MirrorBufferSet.h.

References bufferBase.

43 { return bufferBase; }
unsigned long MirrorBufferSet::PageSize ( void  )
static

Definition at line 307 of file MirrorBufferSet.cc.

Referenced by MirrorBufferSet(), and ThresholdQueueBase::ThresholdQueueBase().

309 {
310 #ifdef __APPLE__
311  return getpagesize();
312 #else
313  return sysconf(_SC_PAGESIZE);
314 #endif
315 }

+ Here is the caller graph for this function:

int MirrorBufferSet::Supported ( void  )
static

Definition at line 27 of file MirrorBufferSet.cc.

References eNotSupported, eSupportedPosixShm, and eSupportedTmpFile.

Referenced by ThresholdQueueBase::AllocateBuf().

29 {
30  #if !MirrorBufferSet_SUPPORTED
31  return eNotSupported;
32  #endif
33 
34  #if MBS_USE_POSIX_SHM
35  return eSupportedPosixShm;
36  #else
37  return eSupportedTmpFile;
38  #endif
39 }

+ Here is the caller graph for this function:

Member Data Documentation

void* MirrorBufferSet::bufferBase
protected

Definition at line 48 of file MirrorBufferSet.h.

Referenced by MirrorBufferSet(), operator void *(), and ~MirrorBufferSet().

ulong MirrorBufferSet::bufferSize
protected

Definition at line 49 of file MirrorBufferSet.h.

Referenced by BufferSize(), MirrorBufferSet(), and ~MirrorBufferSet().

char MirrorBufferSet::fileName[112]
protected

Definition at line 52 of file MirrorBufferSet.h.

Referenced by GetFileDescriptor(), MirrorBufferSet(), and ~MirrorBufferSet().

ulong MirrorBufferSet::mirrorSize
protected

Definition at line 50 of file MirrorBufferSet.h.

Referenced by MirrorBufferSet(), MirrorSize(), and ~MirrorBufferSet().

int MirrorBufferSet::numBuffers
protected

Definition at line 51 of file MirrorBufferSet.h.

Referenced by MirrorBufferSet(), NumBuffers(), and ~MirrorBufferSet().


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