Windows: re-enable the mmap ioengine and fix static asserts
authorRebecca Cran <bruce.cran@sandisk.com>
Thu, 9 Feb 2017 22:17:27 +0000 (22:17 +0000)
committerJens Axboe <axboe@fb.com>
Mon, 13 Feb 2017 22:38:59 +0000 (15:38 -0700)
Windows supports mmap functionality via the CreateFileMapping and
MapViewOfFile functions. Update posix.c and re-enable the mmap
ioengine in the Makefile.

Also, enable the built-in static asserts, without which the build
breaks when configured with --disable-optimizations.

Signed-off-by: Jens Axboe <axboe@fb.com>
Makefile
configure
os/windows/posix.c

index 491278e4dc290469c7a501add98173971fbabf00..a2842a0acdde2a8f2c8a149cc27ac19cef63b042 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -179,7 +179,6 @@ ifeq ($(CONFIG_TARGET_OS), Darwin)
   LIBS  += -lpthread -ldl
 endif
 ifneq (,$(findstring CYGWIN,$(CONFIG_TARGET_OS)))
   LIBS  += -lpthread -ldl
 endif
 ifneq (,$(findstring CYGWIN,$(CONFIG_TARGET_OS)))
-  SOURCE := $(filter-out engines/mmap.c,$(SOURCE))
   SOURCE += os/windows/posix.c
   LIBS  += -lpthread -lpsapi -lws2_32
   CFLAGS += -DPSAPI_VERSION=1 -Ios/windows/posix/include -Wno-format -static
   SOURCE += os/windows/posix.c
   LIBS  += -lpthread -lpsapi -lws2_32
   CFLAGS += -DPSAPI_VERSION=1 -Ios/windows/posix/include -Wno-format -static
index 4f17cf865c770f8ce3044425a69b7ad2c870bc93..0a258bf32ea68dbe5b168fee078dcd8ff39de0e0 100755 (executable)
--- a/configure
+++ b/configure
@@ -325,6 +325,7 @@ CYGWIN*)
   output_sym "CONFIG_SCHED_IDLE"
   output_sym "CONFIG_TCP_NODELAY"
   output_sym "CONFIG_TLS_THREAD"
   output_sym "CONFIG_SCHED_IDLE"
   output_sym "CONFIG_TCP_NODELAY"
   output_sym "CONFIG_TLS_THREAD"
+  output_sym "CONFIG_STATIC_ASSERT"
   output_sym "CONFIG_IPV6"
   echo "CC=$CC" >> $config_host_mak
   echo "BUILD_CFLAGS=$CFLAGS -I../zlib -include config-host.h -D_GNU_SOURCE" >> $config_host_mak
   output_sym "CONFIG_IPV6"
   echo "CC=$CC" >> $config_host_mak
   echo "BUILD_CFLAGS=$CFLAGS -I../zlib -include config-host.h -D_GNU_SOURCE" >> $config_host_mak
index bbd93e979522e098d9a438e0ccfdc10da0b89ec0..f468cbffeeaac5a8fac1a0f4310bdcbfe8a27b21 100755 (executable)
@@ -304,35 +304,76 @@ void *mmap(void *addr, size_t len, int prot, int flags,
                int fildes, off_t off)
 {
        DWORD vaProt = 0;
                int fildes, off_t off)
 {
        DWORD vaProt = 0;
+       DWORD mapAccess = 0;
+       DWORD lenlow;
+       DWORD lenhigh;
+       HANDLE hMap;
        void* allocAddr = NULL;
 
        if (prot & PROT_NONE)
                vaProt |= PAGE_NOACCESS;
 
        void* allocAddr = NULL;
 
        if (prot & PROT_NONE)
                vaProt |= PAGE_NOACCESS;
 
-       if ((prot & PROT_READ) && !(prot & PROT_WRITE))
+       if ((prot & PROT_READ) && !(prot & PROT_WRITE)) {
                vaProt |= PAGE_READONLY;
                vaProt |= PAGE_READONLY;
+               mapAccess = FILE_MAP_READ;
+       }
 
 
-       if (prot & PROT_WRITE)
+       if (prot & PROT_WRITE) {
                vaProt |= PAGE_READWRITE;
                vaProt |= PAGE_READWRITE;
+               mapAccess |= FILE_MAP_WRITE;
+       }
+
+       lenlow = len & 0xFFFF;
+       lenhigh = len >> 16;
+       /* If the low DWORD is zero and the high DWORD is non-zero, `CreateFileMapping`
+          will return ERROR_INVALID_PARAMETER. To avoid this, set both to zero. */
+       if (lenlow == 0) {
+               lenhigh = 0;
+       }
 
 
-       if ((flags & MAP_ANON) | (flags & MAP_ANONYMOUS))
+       if (flags & MAP_ANON || flags & MAP_ANONYMOUS)
        {
                allocAddr = VirtualAlloc(addr, len, MEM_COMMIT, vaProt);
                if (allocAddr == NULL)
                        errno = win_to_posix_error(GetLastError());
        }
        {
                allocAddr = VirtualAlloc(addr, len, MEM_COMMIT, vaProt);
                if (allocAddr == NULL)
                        errno = win_to_posix_error(GetLastError());
        }
+       else
+       {
+               hMap = CreateFileMapping((HANDLE)_get_osfhandle(fildes), NULL, vaProt, lenhigh, lenlow, NULL);
+
+               if (hMap != NULL)
+               {
+                       allocAddr = MapViewOfFile(hMap, mapAccess, off >> 16, off & 0xFFFF, len);
+               }
+
+               if (hMap == NULL || allocAddr == NULL)
+                       errno = win_to_posix_error(GetLastError());
+
+       }
 
        return allocAddr;
 }
 
 int munmap(void *addr, size_t len)
 {
 
        return allocAddr;
 }
 
 int munmap(void *addr, size_t len)
 {
-       if (!VirtualFree(addr, 0, MEM_RELEASE)) {
-               errno = win_to_posix_error(GetLastError());
-               return -1;
+       BOOL success;
+
+       /* We may have allocated the memory with either MapViewOfFile or
+                VirtualAlloc. Therefore, try calling UnmapViewOfFile first, and if that
+                fails, call VirtualFree. */
+       success = UnmapViewOfFile(addr);
+
+       if (!success)
+       {
+               success = VirtualFree(addr, 0, MEM_RELEASE);
        }
 
        }
 
-       return 0;
+       return !success;
+}
+
+int msync(void *addr, size_t len, int flags)
+{
+       return !FlushViewOfFile(addr, len);
 }
 
 int fork(void)
 }
 
 int fork(void)
@@ -702,17 +743,9 @@ int getrusage(int who, struct rusage *r_usage)
 
 int posix_madvise(void *addr, size_t len, int advice)
 {
 
 int posix_madvise(void *addr, size_t len, int advice)
 {
-       log_err("%s is not implemented\n", __func__);
        return ENOSYS;
 }
 
        return ENOSYS;
 }
 
-/* Windows doesn't support advice for memory pages. Just ignore it. */
-int msync(void *addr, size_t len, int flags)
-{
-       errno = ENOSYS;
-       return -1;
-}
-
 int fdatasync(int fildes)
 {
        return fsync(fildes);
 int fdatasync(int fildes)
 {
        return fsync(fildes);