Swarm-NG  1.1
memorymap.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Mario Juric *
3  * mjuric@astro.Princeton.EDU *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
20 
26 #ifndef __astro_system_memorymap_h
27 #define __astro_system_memorymap_h
28 
29 #ifdef _WIN32
30 #pragma warning "Using fake memory mapping"
31 #include "fakemmap.h"
32 #define mmap fakemmap
33 #define munmap fakemunmap
34 #define msync fakemsync
35 #else
36 #include <sys/mman.h>
37 #endif
38 
39 #include <fcntl.h>
40 #include <string>
41 #include <iosfwd>
42 
43 #include <map>
44 #include <deque>
45 #include <list>
46 #include <vector>
47 #include <iostream>
48 #include <stdexcept>
49 
50 namespace peyton {
51 namespace system {
52 
54 class MemoryMap
55 {
56 protected:
57  std::string filename;
58  int fd;
59 
60  size_t length;
61  void *map;
62 
63  bool closefd;
64 public:
66  enum {
67  ro = PROT_READ,
68  wo = PROT_WRITE,
69  rw = PROT_READ | PROT_WRITE,
70  none = PROT_NONE,
71  exec = PROT_EXEC
72  };
73 
75  enum {
76  shared = MAP_SHARED,
77  priv = MAP_PRIVATE
78  };
79 
80  static const int pagesize;
82  static void pagesizealign(std::ostream &out);
83  static void pagesizealign(std::istream &in);
84 public:
86  void open(int fd, size_t length_, size_t offset, int mode, int mapstyle, bool closefd = false);
87 public:
89  MemoryMap();
90  MemoryMap(const std::string &filename, size_t length = 0, size_t offset = 0, int mode = ro, int map = shared);
92  void open(const std::string &filename, size_t length = 0, size_t offset = 0, int mode = ro, int map = shared);
94  void sync();
96  void close();
97 
99  ~MemoryMap();
100 
102  operator void *() { return map; }
103 
105  size_t size() const { return length; }
106 };
107 
109 template<typename T>
111 {
112 public:
113  typedef T* iterator;
114  size_t siz;
115 public:
116  MemoryMapVector() : MemoryMap(), siz(0) {}
117 
119  void open(const std::string &filename, size_t size = -1, size_t offset = 0, int mode = ro, int mapstyle = shared)
120  {
121  MemoryMap::open(filename, sizeof(T)*size, offset, mode, mapstyle);
122  if(size < 0) { siz = length/sizeof(T); } else { siz = size; }
123  }
124 
126  const T &operator[](int i) const { return ((const T *)map)[i]; }
127  T &operator[](int i) { return ((T *)map)[i]; }
128 
130  iterator begin() { return (T *)map; }
132  iterator end() { return ((T *)map) + siz; }
133 
135  T& front() { return *(T *)map; }
136  T& back() { return ((T *)map) + (siz-1); }
137 
139  size_t size() const { return siz; }
140  size_t allocated() { return length / sizeof(T); }
141 };
142 
144 struct MemoryMapError : public std::runtime_error {
145  MemoryMapError(const std::string &msg): std::runtime_error(msg) {};
146  virtual ~MemoryMapError() throw() {};
147 };
148 
149 
150 } // namespace system
151 } // namespace peyton
152 
154 template<typename Header>
156 {
157  protected:
158  Header *fh;
159  char *m_data;
160  size_t m_size;
161 
162  public:
164  mmapped_file_with_header(const std::string &filename = "", const std::string &type = "", int mode = ro, bool validate = true)
165  : fh(NULL), m_data(NULL)
166  {
167  if(!filename.empty())
168  {
169  open(filename, type, mode, validate);
170  }
171  }
172 
174  void open(const std::string &filename, const std::string &type, int mode = ro, bool validate = true)
175  {
176  MemoryMap::open(filename.c_str(), 0, 0, mode, shared);
177 
178  // read/check header
179  fh = (Header *)map;
180  Header ref_ver(type);
181  if(validate && !ref_ver.is_compatible(*fh))
182  {
183  std::cerr << "Expecting: " << ref_ver.type() << "\n";
184  std::cerr << "Got : " << fh->type() << "\n";
185  throw peyton::system::MemoryMapError("Input file corrupted or incompatible with this version of swarm");
186  }
187 
188  // get the pointer to data
189  m_data = (char *)&fh[1];
190 
191  // data size
192  m_size = length - sizeof(Header);
193  }
194 
196  size_t size() const { return m_size; }
197 
199  char *data() const { return m_data; }
200  Header &hdr() const { return *fh; }
201 };
202 
203 using namespace peyton::system;
204 
205 #define __peyton_system peyton::system
206 #endif
207