Skip to content

Commit 4989269

Browse files
committed
windows mmap
1 parent a6202d0 commit 4989269

File tree

2 files changed

+63
-16
lines changed

2 files changed

+63
-16
lines changed

src/common/io.cc

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
#include <fcntl.h> // for open, O_RDONLY
66
#include <sys/mman.h> // for mmap, mmap64, munmap
77
#include <sys/stat.h>
8-
#include <unistd.h> // for close
8+
#include <unistd.h> // for close, getpagesize
9+
#elif defined(_MSC_VER)
10+
#include <windows.h>
911
#endif // defined(__unix__)
12+
1013
#include <algorithm>
1114
#include <cerrno> // for errno
1215
#include <cstdio>
@@ -157,34 +160,78 @@ std::string FileExtension(std::string fname, bool lower) {
157160
}
158161
}
159162

160-
void* PrivateMmapStream::Open(StringView path, bool read_only, std::size_t offset,
163+
std::size_t GetPageSize() {
164+
#if defined(_MSC_VER)
165+
SYSTEM_INFO sys_info;
166+
GetSystemInfo(&sys_info);
167+
return sys_info.dwPageSize;
168+
#else
169+
return getpagesize();
170+
#endif
171+
}
172+
173+
struct PrivateMmapStream::MMAPFile {
174+
#if defined(_MSC_VER)
175+
HANDLE fd;
176+
#else
177+
std::int32_t fd;
178+
#endif
179+
std::string path;
180+
};
181+
182+
PrivateMmapStream::PrivateMmapStream(std::string path, bool read_only, std::size_t offset,
183+
std::size_t length)
184+
: MemoryFixSizeBuffer{Open(std::move(path), read_only, offset, length), length} {}
185+
186+
void* PrivateMmapStream::Open(std::string path, bool read_only, std::size_t offset,
161187
std::size_t length) {
162-
fd_ = open(path.c_str(), O_RDONLY);
163-
CHECK_GE(fd_, 0) << "Failed to open:" << path << ". " << strerror(errno);
188+
#if defined(_MSC_VER)
189+
HANDLE fd = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
190+
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr);
191+
CHECK_NE(fd, INVALID_HANDLE_VALUE) << "Failed to open:" << path;
192+
#else
193+
auto fd = open(path.c_str(), O_RDONLY);
194+
#endif
195+
CHECK_GE(fd, 0) << "Failed to open:" << path << ". " << strerror(errno);
196+
handle_ = std::make_unique<MMAPFile>(fd, std::move(path));
164197

165-
char* ptr{nullptr};
198+
void* ptr{nullptr};
199+
#if defined(__linux__) || defined(__GLIBC__)
166200
int prot{PROT_READ};
167201
if (!read_only) {
168202
prot |= PROT_WRITE;
169203
}
170-
#if defined(__linux__) || defined(__GLIBC__)
171204
ptr = reinterpret_cast<char*>(mmap64(nullptr, length, prot, MAP_PRIVATE, fd_, offset));
205+
CHECK_NE(ptr, MAP_FAILED) << "Failed to map: " << path << ". " << strerror(errno);
172206
#elif defined(_MSC_VER)
173-
// fixme: not yet implemented
174-
ptr = reinterpret_cast<char*>(mmap(nullptr, length, prot, MAP_PRIVATE, fd_, offset));
207+
auto file_size = GetFileSize(handle_->fd, nullptr);
208+
DWORD access = read_only ? PAGE_READONLY : PAGE_READWRITE;
209+
auto map_file = CreateFileMapping(handle_->fd, nullptr, access, 0, file_size, nullptr);
210+
access = read_only ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS;
211+
ptr = MapViewOfFile(map_file, access, 0, offset, length);
212+
CHECK_NE(ptr, nullptr) << "Failed to map: " << path << ". " << GetLastError();
175213
#else
176214
CHECK_LE(offset, std::numeric_limits<off_t>::max())
177215
<< "File size has exceeded the limit on the current system.";
216+
int prot{PROT_READ};
217+
if (!read_only) {
218+
prot |= PROT_WRITE;
219+
}
178220
ptr = reinterpret_cast<char*>(mmap(nullptr, length, prot, MAP_PRIVATE, fd_, offset));
179-
#endif // defined(__linux__)
180221
CHECK_NE(ptr, MAP_FAILED) << "Failed to map: " << path << ". " << strerror(errno);
222+
#endif // defined(__linux__)
181223
return ptr;
182224
}
183225

184226
PrivateMmapStream::~PrivateMmapStream() {
227+
#if defined(_MSC_VER)
228+
CHECK(UnmapViewOfFile(p_buffer_)) "Faled to munmap." << path_ << ". " << GetLastError();
229+
CloseHandle();
230+
#else
185231
CHECK_NE(munmap(p_buffer_, buffer_size_), -1)
186232
<< "Faled to munmap." << path_ << ". " << strerror(errno);
187233
CHECK_NE(close(fd_), -1) << "Faled to close: " << path_ << ". " << strerror(errno);
234+
#endif
188235
}
189236
} // namespace common
190237
} // namespace xgboost

src/common/io.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010

1111
#include <dmlc/io.h>
1212
#include <rabit/rabit.h>
13-
#include <xgboost/string_view.h>
1413

1514
#include <cstring>
1615
#include <fstream>
1716
#include <string> // for string
17+
#include <utility> // for move
1818

1919
#include "common.h"
2020

@@ -129,14 +129,16 @@ inline std::string ReadAll(std::string const &path) {
129129
return content;
130130
}
131131

132+
std::size_t GetPageSize();
132133
/**
133134
* \brief Private mmap file, copy-on-write
134135
*/
135136
class PrivateMmapStream : public MemoryFixSizeBuffer {
136-
std::int32_t fd_;
137-
std::string path_;
137+
struct MMAPFile;
138138

139-
void* Open(StringView path, bool read_only, std::size_t offset, std::size_t length);
139+
std::unique_ptr<MMAPFile> handle_;
140+
141+
void* Open(std::string path, bool read_only, std::size_t offset, std::size_t length);
140142

141143
public:
142144
/**
@@ -148,9 +150,7 @@ class PrivateMmapStream : public MemoryFixSizeBuffer {
148150
* @param length See the `length` parameter of `mmap` for details.
149151
*/
150152
explicit PrivateMmapStream(std::string path, bool read_only, std::size_t offset,
151-
std::size_t length)
152-
: MemoryFixSizeBuffer{Open(StringView{path}, read_only, offset, length), length},
153-
path_{path} {}
153+
std::size_t length);
154154

155155
~PrivateMmapStream() override;
156156
};

0 commit comments

Comments
 (0)