NVBIO
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mmap.cpp
Go to the documentation of this file.
1 /*
2  * nvbio
3  * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the NVIDIA CORPORATION nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include <nvbio/basic/mmap.h>
29 #include <nvbio/basic/console.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <string>
34 
35 #ifdef WIN32
36 
37 #include <windows.h>
38 #include <conio.h>
39 
40 namespace nvbio {
41 
42 struct MappedFile::Impl
43 {
44  Impl() : h_file( INVALID_HANDLE_VALUE ), buffer( NULL ) {}
45 
46  HANDLE h_file;
47  void* buffer;
48 };
49 struct ServerMappedFile::Impl
50 {
51  Impl() : h_file( INVALID_HANDLE_VALUE ), buffer( NULL ) {}
52 
53  HANDLE h_file;
54  void* buffer;
55 };
56 
57 MappedFile::MappedFile() : impl( new Impl() ) {}
58 
59 void* MappedFile::init(const char* name, const uint64 file_size)
60 {
61  std::string sname = std::string("Global\\") + std::string( name );
62  std::wstring wname( sname.begin(), sname.end() );
63 
64  impl->h_file = OpenFileMapping(
65  FILE_MAP_READ, // read/write access
66  FALSE, // do not inherit the name
67 #ifdef UNICODE
68  wname.c_str() // name of mapping object
69 #else
70  (LPCSTR)wname.c_str()
71 #endif
72  );
73 
74  if (impl->h_file == NULL)
75  throw mapping_error( name, GetLastError() );
76 
77  impl->buffer = MapViewOfFile(
78  impl->h_file, // handle to map object
79  FILE_MAP_READ, // read/write permission
80  0,
81  uint32(file_size >> 32),
82  uint32(file_size & 0xFFFFFFFFu) );
83 
84  if (impl->buffer == NULL)
85  throw view_error( name, GetLastError() );
86 
87  log_verbose(stderr, "created mapped file object \"%s\" (%.2f %s)\n", name, (file_size > 1024*1024 ? float(file_size)/float(1024*1024) : float(file_size)), (file_size > 1024*1024 ? TEXT("MB") : TEXT("B")));
88  return impl->buffer;
89 }
90 MappedFile::~MappedFile()
91 {
92  if (impl->buffer != NULL) UnmapViewOfFile( impl->buffer );
93  if (impl->h_file != INVALID_HANDLE_VALUE) CloseHandle( impl->h_file );
94 
95  delete impl;
96 }
97 
98 ServerMappedFile::ServerMappedFile() : impl( new Impl() ) {}
99 
100 void* ServerMappedFile::init(const char* name, const uint64 file_size, const void* src)
101 {
102  std::string sname = std::string("Global\\") + std::string( name );
103  std::wstring wname( sname.begin(), sname.end() );
104 
105  impl->h_file = CreateFileMapping(
106  INVALID_HANDLE_VALUE, // use paging file
107  NULL, // default security
108  PAGE_READWRITE, // read/write access
109  uint32(file_size >> 32), // maximum object size (high-order DWORD)
110  uint32(file_size & 0xFFFFFFFFu), // maximum object size (low-order DWORD)
111 #ifdef UNICODE
112  wname.c_str() // name of mapping object
113 #else
114  (LPCSTR) wname.c_str()
115 #endif
116  );
117 
118  if (impl->h_file == NULL)
119  throw mapping_error( name, GetLastError() );
120 
121  impl->buffer = MapViewOfFile(
122  impl->h_file, // handle to map object
123  FILE_MAP_WRITE, // read/write permission
124  0,
125  uint32(file_size >> 32),
126  uint32(file_size & 0xFFFFFFFFu) );
127 
128  if (impl->buffer == NULL)
129  throw view_error( name, GetLastError() );
130 
131  if (src != NULL)
132  CopyMemory( impl->buffer, src, file_size );
133 
134  log_verbose(stderr, "created file mapping object \"%s\" (%.2f %s)\n", name, (file_size > 1024*1024 ? float(file_size)/float(1024*1024) : float(file_size)), (file_size > 1024*1024 ? "MB" : "B"));
135  return impl->buffer;
136 }
137 ServerMappedFile::~ServerMappedFile()
138 {
139  if (impl->buffer != NULL) UnmapViewOfFile( impl->buffer );
140  if (impl->h_file != INVALID_HANDLE_VALUE) CloseHandle( impl->h_file );
141 
142  delete impl;
143 }
144 
145 } // namespace nvbio
146 
147 #else
148 
149 //
150 // POSIX shared memory files
151 //
152 
153 #include <sys/mman.h>
154 #include <sys/stat.h> /* For mode constants */
155 #include <fcntl.h> /* For O_* constants */
156 #include <errno.h>
157 #include <unistd.h>
158 #include <sys/types.h>
159 
160 namespace nvbio {
161 
163 {
164  Impl() : h_file( -1 ), buffer( NULL ) {}
165 
166  int h_file;
167  void* buffer;
168  std::string file_name;
170 };
172 {
173  Impl() : h_file( -1 ), buffer( NULL ) {}
174 
175  int h_file;
176  void* buffer;
177  std::string file_name;
179 };
180 
181 MappedFile::MappedFile() : impl( new Impl() ) {}
182 
183 void* MappedFile::init(const char* name, const uint64 file_size)
184 {
185  impl->file_name = std::string("/") + std::string(name);
186  impl->file_size = file_size;
187  impl->h_file = shm_open(
188  impl->file_name.c_str(),
189  O_RDONLY,
190  S_IRWXU );
191 
192  if (impl->h_file == -1)
193  throw mapping_error( impl->file_name.c_str(), errno );
194 
195  ftruncate( impl->h_file, file_size );
196 
197  impl->buffer = mmap(
198  NULL,
199  file_size,
200  PROT_READ,
201  MAP_SHARED,
202  impl->h_file,
203  0 );
204 
205  if (impl->buffer == NULL)
206  throw view_error( impl->file_name.c_str(), errno );
207 
208  log_verbose(stderr, "created file mapping object \"%s\" (%.2f %s)\n", name, (file_size > 1024*1024 ? float(file_size)/float(1024*1024) : float(file_size)), (file_size > 1024*1024 ? "MB" : "B"));
209  return impl->buffer;
210 }
212 {
213  if (impl->buffer != NULL) munmap( impl->buffer, impl->file_size );
214  //if (impl->h_file != -1) shm_unlink( impl->file_name.c_str() );
215 
216  delete impl;
217 }
218 
220 
221 void* ServerMappedFile::init(const char* name, const uint64 file_size, const void* src)
222 {
223  impl->file_name = std::string("/") + std::string(name);
224  impl->file_size = file_size;
225  impl->h_file = shm_open(
226  impl->file_name.c_str(),
227  O_RDWR | O_CREAT,
228  S_IRWXU );
229 
230  if (impl->h_file == -1)
231  throw mapping_error( impl->file_name.c_str(), errno );
232 
233  ftruncate( impl->h_file, file_size );
234 
235  impl->buffer = mmap(
236  NULL,
237  file_size,
238  PROT_READ | PROT_WRITE,
239  MAP_SHARED,
240  impl->h_file,
241  0 );
242 
243  if (impl->buffer == NULL)
244  throw view_error( impl->file_name.c_str(), errno );
245 
246  if (src != NULL)
247  memcpy( impl->buffer, src, file_size );
248 
249  log_verbose(stderr, "created file mapping object \"%s\" (%.2f %s)\n", name, (file_size > 1024*1024 ? float(file_size)/float(1024*1024) : float(file_size)), (file_size > 1024*1024 ? "MB" : "B"));
250  return impl->buffer;
251 }
253 {
254  if (impl->buffer != NULL) munmap( impl->buffer, impl->file_size );
255  if (impl->h_file != -1) shm_unlink( impl->file_name.c_str() );
256 
257  delete impl;
258 }
259 
260 } // namespace nvbio
261 
262 #endif