Skip to content

Commit

Permalink
Windows compatibility fixes for posix_memalign() and mmap()
Browse files Browse the repository at this point in the history
  • Loading branch information
mehrdadn authored and Name committed Jul 27, 2016
1 parent 0707062 commit 1f5b48d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 7 deletions.
42 changes: 36 additions & 6 deletions cpp/src/arrow/ipc/memory.cc
Expand Up @@ -17,7 +17,12 @@

#include "arrow/ipc/memory.h"

#ifdef _WIN32
#include <Windows.h>
#include <io.h>
#else
#include <sys/mman.h> // For memory-mapping
#endif

#include <algorithm>
#include <cerrno>
Expand All @@ -41,23 +46,32 @@ MemorySource::~MemorySource() {}

class MemoryMappedSource::Impl {
public:
Impl() : file_(nullptr), is_open_(false), is_writable_(false), data_(nullptr) {}
Impl() : file_(nullptr),
#ifdef _WIN32
mapping_(nullptr),
#endif
is_open_(false), is_writable_(false), data_(nullptr) {}

~Impl() {
if (is_open_) {
#ifdef _WIN32
UnmapViewOfFile(data_);
CloseHandle(mapping_);
#else
munmap(data_, size_);
#endif
fclose(file_);
}
}

Status Open(const std::string& path, MemorySource::AccessMode mode) {
if (is_open_) { return Status::IOError("A file is already open"); }

int prot_flags = PROT_READ;
bool write = false;

if (mode == MemorySource::READ_WRITE) {
file_ = fopen(path.c_str(), "r+b");
prot_flags |= PROT_WRITE;
write = true;
is_writable_ = true;
} else {
file_ = fopen(path.c_str(), "rb");
Expand All @@ -75,7 +89,20 @@ class MemoryMappedSource::Impl {
fseek(file_, 0L, SEEK_SET);
is_open_ = true;

void* result = mmap(nullptr, size_, prot_flags, MAP_SHARED, fileno(file_), 0);
#ifdef _WIN32
static void *const MAP_FAILED = NULL;
void *result = MAP_FAILED;
mapping_ = CreateFileMapping(reinterpret_cast<HANDLE>(_get_osfhandle(fileno(file_))), NULL, write ? PAGE_READWRITE : PAGE_READONLY, 0, 0, NULL);
if (mapping_) {
result = MapViewOfFile(mapping_, FILE_MAP_READ | (write ? FILE_MAP_WRITE : 0), 0, 0, static_cast<SIZE_T>(size_));
if (!result) {
CloseHandle(mapping_);
mapping_ = NULL;
}
}
#else
void* result = mmap(nullptr, size_, PROT_READ | (write ? PROT_WRITE : 0), MAP_SHARED, fileno(file_), 0);
#endif
if (result == MAP_FAILED) {
std::stringstream ss;
ss << "Memory mapping file failed, errno: " << errno;
Expand All @@ -96,6 +123,9 @@ class MemoryMappedSource::Impl {

private:
FILE* file_;
#ifdef _WIN32
HANDLE mapping_;
#endif
int64_t size_;
bool is_open_;
bool is_writable_;
Expand Down Expand Up @@ -133,7 +163,7 @@ Status MemoryMappedSource::ReadAt(
return Status::Invalid("position is out of bounds");
}

nbytes = std::min(nbytes, impl_->size() - position);
nbytes = (std::min)(nbytes, impl_->size() - position);
*out = std::make_shared<Buffer>(impl_->data() + position, nbytes);
return Status::OK();
}
Expand Down Expand Up @@ -166,7 +196,7 @@ Status MockMemorySource::ReadAt(
}

Status MockMemorySource::Write(int64_t position, const uint8_t* data, int64_t nbytes) {
extent_bytes_written_ = std::max(extent_bytes_written_, position + nbytes);
extent_bytes_written_ = (std::max)(extent_bytes_written_, position + nbytes);
return Status::OK();
}

Expand Down
12 changes: 11 additions & 1 deletion cpp/src/arrow/util/memory-pool.cc
Expand Up @@ -32,7 +32,13 @@ namespace {
Status AllocateAligned(int64_t size, uint8_t** out) {
// TODO(emkornfield) find something compatible with windows
constexpr size_t kAlignment = 64;
const int result = posix_memalign(reinterpret_cast<void**>(out), kAlignment, size);
const int result =
#ifdef _WIN32
((*out = static_cast<uint8_t *>(_aligned_malloc(size, kAlignment))) ? 0 : errno)
#else
posix_memalign(reinterpret_cast<void**>(out), kAlignment, size)
#endif
;
if (result == ENOMEM) {
std::stringstream ss;
ss << "malloc of size " << size << " failed";
Expand Down Expand Up @@ -81,7 +87,11 @@ int64_t InternalMemoryPool::bytes_allocated() const {

void InternalMemoryPool::Free(uint8_t* buffer, int64_t size) {
std::lock_guard<std::mutex> guard(pool_lock_);
#ifdef _WIN32
_aligned_free(buffer);
#else
std::free(buffer);
#endif
bytes_allocated_ -= size;
}

Expand Down

0 comments on commit 1f5b48d

Please sign in to comment.