port: mmap offset alignment on Windows
authorMichael Jeanson <mjeanson@efficios.com>
Tue, 17 Sep 2019 18:31:37 +0000 (14:31 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Mon, 30 Sep 2019 19:31:09 +0000 (15:31 -0400)
On Windows the mmap offset is not aligned to the page size but to the
allocator granularity which is usually bigger than the page size. Add a new
internal function to the mmap compat code to get the proper offset alignment
size for each platform.

See the "dwFileOffsetLow" section for more details :
https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffile

Change-Id: Ic26dc53862719892738a88b3dcea6a15901a0c94
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/2107
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
src/common/mmap-align.h
src/compat/mman.c
src/compat/mman.h
src/plugins/ctf/fs-src/data-stream-file.c

index 033d6c4a92916ce651fc14590887c52d46d82d5b..c42cdeb34da234b02490db1f0cf25c6fe877893f 100644 (file)
@@ -46,29 +46,11 @@ struct mmap_align {
        size_t length;                  /* virtual mmap length */
 };
 
-#ifdef __WIN32__
-#include <windows.h>
-
-/*
- * On windows the memory mapping offset must be aligned to the memory
- * allocator allocation granularity and not the page size.
- */
-static inline
-off_t get_page_aligned_offset(off_t offset, size_t page_size)
-{
-       SYSTEM_INFO sysinfo;
-
-       GetNativeSystemInfo(&sysinfo);
-
-       return ALIGN_FLOOR(offset, sysinfo.dwAllocationGranularity);
-}
-#else
 static inline
-off_t get_page_aligned_offset(off_t offset, size_t page_size)
+off_t get_page_aligned_offset(off_t offset, int log_level)
 {
-       return ALIGN_FLOOR(offset, page_size);
+       return ALIGN_FLOOR(offset, bt_mmap_get_offset_align_size(log_level));
 }
-#endif
 
 static inline
 struct mmap_align *mmap_align(size_t length, int prot,
@@ -84,7 +66,7 @@ struct mmap_align *mmap_align(size_t length, int prot,
        if (!mma)
                return MAP_FAILED;
        mma->length = length;
-       page_aligned_offset = get_page_aligned_offset(offset, page_size);
+       page_aligned_offset = get_page_aligned_offset(offset, log_level);
        /*
         * Page aligned length needs to contain the requested range.
         * E.g., for a small range that fits within a single page, we might
index 1a7638c98381e0d6511a3a78f597e43015d90df7..d2019d2bd2d6ed2a81679ba287db43b0754739df 100644 (file)
@@ -300,4 +300,17 @@ end:
        return ret;
 }
 
+BT_HIDDEN
+size_t bt_mmap_get_offset_align_size(int log_level)
+{
+       SYSTEM_INFO sysinfo;
+
+       GetNativeSystemInfo(&sysinfo);
+       BT_LOG_WRITE_CUR_LVL(BT_LOG_DEBUG, log_level, BT_LOG_TAG,
+               "Allocator granularity is %lu.",
+               sysinfo.dwAllocationGranularity);
+
+       return sysinfo.dwAllocationGranularity;
+}
+
 #endif
index bdab9d1903fbab5e08227f4d498cef8de69050c3..4ed889ace50d8f0b604598ee0161841656db859a 100644 (file)
@@ -50,9 +50,16 @@ void *bt_mmap(void *addr, size_t length, int prot, int flags, int fd,
 
 int bt_munmap(void *addr, size_t length);
 
+/*
+ * On Windows the memory mapping offset must be aligned to the memory
+ * allocator allocation granularity and not the page size.
+ */
+size_t bt_mmap_get_offset_align_size(int log_level);
+
 #else /* __MINGW32__ */
 
 #include <sys/mman.h>
+#include "common/common.h"
 
 static inline
 void *bt_mmap(void *addr, size_t length, int prot, int flags, int fd,
@@ -66,6 +73,16 @@ int bt_munmap(void *addr, size_t length)
 {
        return munmap(addr, length);
 }
+
+/*
+ * On other platforms the memory mapping offset must be aligned to the
+ * page size.
+ */
+static inline
+size_t bt_mmap_get_offset_align_size(int log_level)
+{
+       return bt_common_get_page_size(log_level);
+}
 #endif /* __MINGW32__ */
 
 #ifndef MAP_ANONYMOUS
index 6ddb8a34d0f861c921cde8fe3c50161e818a0902..924a2be788c5fe9b450862d82118005537ecdd2b 100644 (file)
@@ -251,7 +251,7 @@ enum bt_msg_iter_medium_status medop_seek(enum bt_msg_iter_seek_whence whence,
 
 map_requested_offset:
        offset_in_mapping = offset %
-               bt_common_get_page_size(ds_file->log_level);
+               bt_mmap_get_offset_align_size(ds_file->log_level);
 
        ds_file->mmap_offset = offset - offset_in_mapping;
        ds_file->request_offset = offset_in_mapping;
@@ -642,7 +642,7 @@ struct ctf_fs_ds_file *ctf_fs_ds_file_create(
                bt_logging_level log_level)
 {
        int ret;
-       const size_t page_size = bt_common_get_page_size(log_level);
+       const size_t offset_align = bt_mmap_get_offset_align_size(log_level);
        struct ctf_fs_ds_file *ds_file = g_new0(struct ctf_fs_ds_file, 1);
 
        if (!ds_file) {
@@ -672,7 +672,7 @@ struct ctf_fs_ds_file *ctf_fs_ds_file_create(
                goto error;
        }
 
-       ds_file->mmap_max_len = page_size * 2048;
+       ds_file->mmap_max_len = offset_align * 2048;
 
        goto end;
 
This page took 0.027119 seconds and 4 git commands to generate.