From 480c03101a50de18561a7b62d3946d2f7c7abe0a Mon Sep 17 00:00:00 2001 From: qgymib <4520263+qgymib@users.noreply.github.com> Date: Fri, 23 Aug 2024 01:56:08 +0800 Subject: [PATCH] support mmap offset --- ev.c | 106 +++++++++++++++++++++--------------- ev.h | 46 ++++++++++++---- include/ev/defines.h | 8 +++ include/ev/fs.h | 19 +++++-- include/ev/misc.h | 7 +++ src/ev/defs.h | 8 --- src/ev/ringbuffer.c | 4 +- src/ev/unix/fs_unix.c | 24 +++++--- src/ev/unix/misc_unix.c | 5 ++ src/ev/win/fs_win.c | 34 ++++++++---- src/ev/win/misc_win.c | 7 +++ test/CMakeLists.txt | 1 + test/cases/fs_mmap.c | 4 +- test/cases/fs_mmap_offset.c | 67 +++++++++++++++++++++++ 14 files changed, 248 insertions(+), 92 deletions(-) create mode 100644 test/cases/fs_mmap_offset.c diff --git a/ev.c b/ev.c index f7a0abab0..c878396be 100644 --- a/ev.c +++ b/ev.c @@ -98,8 +98,8 @@ EV_LOCAL void ev__assertion_failure(const char* exp, const char* file, int line, // #line 7 "ev.c" //////////////////////////////////////////////////////////////////////////////// // FILE: ev/defs.h -// SIZE: 9624 -// SHA-256: 397cbb95b00be264a95f39db5e607b9583ecd696c2588903bfbba79dbb4d4d68 +// SIZE: 9330 +// SHA-256: 542c3bb6deeb790c5433ac0545f29b7172a449fd30e6c5162a831539cd3109a6 //////////////////////////////////////////////////////////////////////////////// // #line 1 "ev/defs.h" #ifndef __EV_DEFINES_INTERNAL_H__ @@ -132,14 +132,6 @@ extern "C" { #define EV_JOIN(a, b) EV_JOIN_2(a, b) #define EV_JOIN_2(a, b) a##b -/** - * @brief Align \p size to \p align, who's value is larger or equal to \p size - * and can be divided with no remainder by \p align. - * @note \p align must equal to 2^n - */ -#define ALIGN_SIZE(size, align) \ - (((uintptr_t)(size) + ((uintptr_t)(align) - 1)) & ~((uintptr_t)(align) - 1)) - #define ACCESS_ONCE(TYPE, var) (*(volatile TYPE*) &(var)) /** @@ -4415,8 +4407,8 @@ int ev_queue_empty(const ev_queue_node_t* node) // #line 32 "ev.c" //////////////////////////////////////////////////////////////////////////////// // FILE: ev/ringbuffer.c -// SIZE: 17434 -// SHA-256: cf0084b784304bb96bffadf083efde81ecb6bfe4f7bbed5d6cdf16d909323a50 +// SIZE: 17440 +// SHA-256: 8ffd298ee30c5fb60ba540fcbf3262ae6197fd992dc226f964fba3bd44ec5cb9 //////////////////////////////////////////////////////////////////////////////// // #line 1 "ev/ringbuffer.c" @@ -4866,12 +4858,12 @@ static int _ring_buffer_commit_for_consume(ring_buffer_t* rb, EV_LOCAL size_t ring_buffer_heap_cost(void) { /* need to align with machine size */ - return ALIGN_SIZE(sizeof(struct ring_buffer), sizeof(void*)); + return EV_ALIGN_SIZE(sizeof(struct ring_buffer), sizeof(void*)); } EV_LOCAL size_t ring_buffer_node_cost(size_t size) { - return ALIGN_SIZE(sizeof(ring_buffer_node_t) + size, sizeof(void*)); + return EV_ALIGN_SIZE(sizeof(ring_buffer_node_t) + size, sizeof(void*)); } EV_LOCAL ring_buffer_t* ring_buffer_init(void* buffer, size_t size) @@ -6633,8 +6625,8 @@ void ev_async_wakeup(ev_async_t* handle) // #line 56 "ev.c" //////////////////////////////////////////////////////////////////////////////// // FILE: ev/win/fs_win.c -// SIZE: 25618 -// SHA-256: 09ccbb955078ce7dc36361df1aa4ce13d475941639a08b584012ae6a29c5adb3 +// SIZE: 25900 +// SHA-256: e90b06bf000f60cd8805af8146676e5d0197cce4b21721991d0db6b5ac6e1550 //////////////////////////////////////////////////////////////////////////////// // #line 1 "ev/win/fs_win.c" #include @@ -7483,23 +7475,30 @@ EV_LOCAL int ev__fs_mkdir(const char* path, int mode) return (int)ret; } -int ev_file_mmap(ev_file_map_t* view, ev_file_t* file, uint64_t size, int flags) +int ev_file_mmap(ev_file_map_t* view, ev_file_t* file, uint64_t offset, + size_t size, int flags) { DWORD errcode; - if (size == 0) + LARGE_INTEGER file_sz; + if (!GetFileSizeEx(file->file, &file_sz)) { - LARGE_INTEGER file_sz; - if (!GetFileSizeEx(file->file, &file_sz)) - { - errcode = GetLastError(); - return ev__translate_sys_error(errcode); - } - size = file_sz.QuadPart; + errcode = GetLastError(); + return ev__translate_sys_error(errcode); + } + + if (offset >= (uint64_t)file_sz.QuadPart) + { + EV_ASSERT(size > 0); + } + else if (size == 0) + { + size = file_sz.QuadPart - offset; } + const uint64_t map_sz = offset + size; - const DWORD dwMaximumSizeHigh = size >> 32; - const DWORD dwMaximumSizeLow = (DWORD)size; + const DWORD dwMaximumSizeHigh = map_sz >> 32; + const DWORD dwMaximumSizeLow = (DWORD)map_sz; const DWORD flProtect = _ev_file_mmap_to_native_protect_win32(flags); view->backend.file_map_obj = CreateFileMappingW(file->file, NULL, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, NULL); @@ -7510,7 +7509,10 @@ int ev_file_mmap(ev_file_map_t* view, ev_file_t* file, uint64_t size, int flags) } const DWORD dwDesiredAccess = _ev_file_mmap_to_native_access(flags); - view->addr = MapViewOfFile(view->backend.file_map_obj, dwDesiredAccess, 0, 0, 0); + const DWORD dwFileOffsetHigh = offset >> 32; + const DWORD dwFileOffsetLow = (DWORD)offset; + view->addr = MapViewOfFile(view->backend.file_map_obj, dwDesiredAccess, + dwFileOffsetHigh, dwFileOffsetLow, size); if (view->addr == NULL) { CloseHandle(view->backend.file_map_obj); @@ -7711,8 +7713,8 @@ EV_LOCAL int ev__ipv6only_win(SOCKET sock, int opt) // #line 58 "ev.c" //////////////////////////////////////////////////////////////////////////////// // FILE: ev/win/misc_win.c -// SIZE: 8476 -// SHA-256: 76c9ae35bd7d8d498f7b49e4f447142a2890f0c6ef676b0f50dcb1787e1384ac +// SIZE: 8625 +// SHA-256: 0e43dab773bd2448c59947523c91b3f7df3a491c49b9fe290499ce01e960d318 //////////////////////////////////////////////////////////////////////////////// // #line 1 "ev/win/misc_win.c" #include @@ -7913,6 +7915,13 @@ size_t ev_os_page_size(void) return sys_info.dwPageSize; } +size_t ev_os_mmap_offset_granularity(void) +{ + SYSTEM_INFO sys_info; + GetSystemInfo(&sys_info); + return sys_info.dwAllocationGranularity; +} + // #line 59 "ev.c" //////////////////////////////////////////////////////////////////////////////// // FILE: ev/win/mutex_win.c @@ -13319,8 +13328,8 @@ void ev_async_wakeup(ev_async_t* handle) // #line 85 "ev.c" //////////////////////////////////////////////////////////////////////////////// // FILE: ev/unix/fs_unix.c -// SIZE: 10916 -// SHA-256: de509585567d26895bc6a3d136916d9099502dfc2b876c7a84b322725e52a85e +// SIZE: 11011 +// SHA-256: d55950af00cfc687270ff530af495a8c0332e9d0c5eea57f9c6233d0388bd2b2 //////////////////////////////////////////////////////////////////////////////// // #line 1 "ev/unix/fs_unix.c" #define _GNU_SOURCE @@ -13691,22 +13700,28 @@ EV_LOCAL int ev__fs_mkdir(const char* path, int mode) return ret; } -int ev_file_mmap(ev_file_map_t* view, ev_file_t* file, uint64_t size, int flags) +int ev_file_mmap(ev_file_map_t* view, ev_file_t* file, uint64_t offset, + size_t size, int flags) { int ret; const int prot = _ev_file_mmap_to_native_prot_unix(flags); - if (size == 0) + ev_fs_stat_t stat = EV_FS_STAT_INVALID; + if ((ret = ev__fs_fstat(file->file, &stat)) != 0) + { + return ret; + } + + if (offset >= stat.st_size) { - ev_fs_stat_t stat; - if ((ret = ev__fs_fstat(file->file, &stat)) != 0) - { - return ret; - } - size = stat.st_size; + EV_ASSERT(size > 0); + } + else if (size == 0) + { + size = stat.st_size - offset; } - view->addr = mmap(NULL, size, prot, MAP_SHARED, file->file, 0); + view->addr = mmap(NULL, size, prot, MAP_SHARED, file->file, offset); if (view->addr == NULL) { ret = errno; @@ -14345,8 +14360,8 @@ EV_LOCAL void ev__poll(ev_loop_t* loop, uint32_t timeout) // #line 88 "ev.c" //////////////////////////////////////////////////////////////////////////////// // FILE: ev/unix/misc_unix.c -// SIZE: 212 -// SHA-256: 90af43ebc9cc72905c18f356f4a92faa3b2f70093b6deebd5b3af78966a437c7 +// SIZE: 290 +// SHA-256: ef5ea84a17556676433ac6add4ad05896431bdb8111b1da636198ac411014bee //////////////////////////////////////////////////////////////////////////////// // #line 1 "ev/unix/misc_unix.c" #include @@ -14362,6 +14377,11 @@ size_t ev_os_page_size(void) return sysconf(_SC_PAGE_SIZE); } +size_t ev_os_mmap_offset_granularity(void) +{ + return ev_os_page_size(); +} + // #line 89 "ev.c" //////////////////////////////////////////////////////////////////////////////// // FILE: ev/unix/mutex_unix.c diff --git a/ev.h b/ev.h index 00598543b..45e3c386d 100644 --- a/ev.h +++ b/ev.h @@ -713,8 +713,8 @@ EV_API ev_map_node_t* ev_map_prev(const ev_map_node_t* node); // #line 71 "ev.h" //////////////////////////////////////////////////////////////////////////////// // FILE: ev/defines.h -// SIZE: 2966 -// SHA-256: 83cd017868cb72323696bfed0f1e7bd921fe031fb8bfaed953cc860724603bc2 +// SIZE: 3268 +// SHA-256: def87553c746184a16b6fbcaabae80b298f4a50e485e6098525402a19524ce60 //////////////////////////////////////////////////////////////////////////////// // #line 1 "ev/defines.h" #ifndef __EV_DEFINES_H__ @@ -790,6 +790,14 @@ EV_API ev_map_node_t* ev_map_prev(const ev_map_node_t* node); ((type *) ((char *) (ptr) - EV_OFFSETOF(type, member))) #endif + /** + * @brief Align \p size to \p align, who's value is larger or equal to \p size + * and can be divided with no remainder by \p align. + * @note \p align must equal to 2^n + */ +#define EV_ALIGN_SIZE(size, align) \ + (((uintptr_t)(size) + ((uintptr_t)(align) - 1)) & ~((uintptr_t)(align) - 1)) + /** * @} EV_DEFINE */ @@ -4141,8 +4149,8 @@ EV_API void ev_pipe_close(ev_os_pipe_t fd); // #line 97 "ev.h" //////////////////////////////////////////////////////////////////////////////// // FILE: ev/fs.h -// SIZE: 20679 -// SHA-256: 6e9aa38874af630f7c65b78b0f9934ae68829fe660334b0ce3c6cedaf4c570a3 +// SIZE: 21150 +// SHA-256: 66980df2ff6f8e600260f3725a4f9e771c58572c0d0ea3d4751e474e1f2ab369 //////////////////////////////////////////////////////////////////////////////// // #line 1 "ev/fs.h" #ifndef __EV_FILE_SYSTEM_H__ @@ -4603,11 +4611,19 @@ EV_API int ev_file_stat(ev_file_t* file, ev_fs_req_t* req, ev_fs_stat_t* stat, ev_file_cb cb); /** - * @brief Maps a view of a file mapping into the address space of a calling process. + * @brief Maps a view of a file mapping into the address space of a calling + * process. * @param[out] view The mapped object. - * @param[in] file The file to map. The file is safe to close after this call. - * @param[in] size The maximum size of the file mapping object. Set to 0 to - * use current size of the \p file. + * @param[in] file The file to map. The file is safe to close after this + * call. + * @param[in] offset The offset where the view is to begin. It must be a + * multiple of the value of #ev_os_mmap_offset_granularity(). You can use + * #EV_ALIGN_SIZE() to align the offset to requirements. The \p offset can + * larger than the file size, in this case the gapping data is undefined. + * @param[in] size The maximum size of the file mapping object. + * + If \p offset is in range of \p file, set to 0 to use the range from + * \p offset to the end of the file. + * + If \p offset is not less than file size, it must larger than 0. * @param[in] flags Map flags. Can be one or more of the following attributes: * + #EV_FS_S_IRUSR: Pages may be read. * + #EV_FS_S_IWUSR: Pages may be written. @@ -4618,7 +4634,8 @@ EV_API int ev_file_stat(ev_file_t* file, ev_fs_req_t* req, ev_fs_stat_t* stat, * only, you will also get read access. * @return #ev_errno_t */ -EV_API int ev_file_mmap(ev_file_map_t* view, ev_file_t* file, uint64_t size, int flags); +EV_API int ev_file_mmap(ev_file_map_t* view, ev_file_t* file, uint64_t offset, + size_t size, int flags); /** * @brief Unmap the file. @@ -5008,8 +5025,8 @@ EV_API ssize_t ev_exepath(char* buffer, size_t size); // #line 99 "ev.h" //////////////////////////////////////////////////////////////////////////////// // FILE: ev/misc.h -// SIZE: 3677 -// SHA-256: addf568943d162a75af910eea251e30a42601b3f87668ed0a16256235a12e3ac +// SIZE: 3893 +// SHA-256: 56501cd5d5377f20c0f1df0e8de5a806809f3426f5b3a2dccb7866e5475f2f35 //////////////////////////////////////////////////////////////////////////////// // #line 1 "ev/misc.h" #ifndef __EV_MISC_H__ @@ -5147,6 +5164,13 @@ EV_API void ev_library_shutdown(void); */ EV_API size_t ev_os_page_size(void); +/** + * @brief Offset granularity for #ev_file_mmap(). + * @note The Offset granularity does not always equal to system page size. + * @return Offset granularity. + */ +EV_API size_t ev_os_mmap_offset_granularity(void); + /** * @} EV_MISC */ diff --git a/include/ev/defines.h b/include/ev/defines.h index 1951e9384..3ce268904 100644 --- a/include/ev/defines.h +++ b/include/ev/defines.h @@ -71,6 +71,14 @@ ((type *) ((char *) (ptr) - EV_OFFSETOF(type, member))) #endif + /** + * @brief Align \p size to \p align, who's value is larger or equal to \p size + * and can be divided with no remainder by \p align. + * @note \p align must equal to 2^n + */ +#define EV_ALIGN_SIZE(size, align) \ + (((uintptr_t)(size) + ((uintptr_t)(align) - 1)) & ~((uintptr_t)(align) - 1)) + /** * @} EV_DEFINE */ diff --git a/include/ev/fs.h b/include/ev/fs.h index 43e38f272..8d295ba84 100644 --- a/include/ev/fs.h +++ b/include/ev/fs.h @@ -456,11 +456,19 @@ EV_API int ev_file_stat(ev_file_t* file, ev_fs_req_t* req, ev_fs_stat_t* stat, ev_file_cb cb); /** - * @brief Maps a view of a file mapping into the address space of a calling process. + * @brief Maps a view of a file mapping into the address space of a calling + * process. * @param[out] view The mapped object. - * @param[in] file The file to map. The file is safe to close after this call. - * @param[in] size The maximum size of the file mapping object. Set to 0 to - * use current size of the \p file. + * @param[in] file The file to map. The file is safe to close after this + * call. + * @param[in] offset The offset where the view is to begin. It must be a + * multiple of the value of #ev_os_mmap_offset_granularity(). You can use + * #EV_ALIGN_SIZE() to align the offset to requirements. The \p offset can + * larger than the file size, in this case the gapping data is undefined. + * @param[in] size The maximum size of the file mapping object. + * + If \p offset is in range of \p file, set to 0 to use the range from + * \p offset to the end of the file. + * + If \p offset is not less than file size, it must larger than 0. * @param[in] flags Map flags. Can be one or more of the following attributes: * + #EV_FS_S_IRUSR: Pages may be read. * + #EV_FS_S_IWUSR: Pages may be written. @@ -471,7 +479,8 @@ EV_API int ev_file_stat(ev_file_t* file, ev_fs_req_t* req, ev_fs_stat_t* stat, * only, you will also get read access. * @return #ev_errno_t */ -EV_API int ev_file_mmap(ev_file_map_t* view, ev_file_t* file, uint64_t size, int flags); +EV_API int ev_file_mmap(ev_file_map_t* view, ev_file_t* file, uint64_t offset, + size_t size, int flags); /** * @brief Unmap the file. diff --git a/include/ev/misc.h b/include/ev/misc.h index a92aa237d..f1acd8cc1 100644 --- a/include/ev/misc.h +++ b/include/ev/misc.h @@ -133,6 +133,13 @@ EV_API void ev_library_shutdown(void); */ EV_API size_t ev_os_page_size(void); +/** + * @brief Offset granularity for #ev_file_mmap(). + * @note The Offset granularity does not always equal to system page size. + * @return Offset granularity. + */ +EV_API size_t ev_os_mmap_offset_granularity(void); + /** * @} EV_MISC */ diff --git a/src/ev/defs.h b/src/ev/defs.h index fa941ba6a..a31905b12 100644 --- a/src/ev/defs.h +++ b/src/ev/defs.h @@ -28,14 +28,6 @@ extern "C" { #define EV_JOIN(a, b) EV_JOIN_2(a, b) #define EV_JOIN_2(a, b) a##b -/** - * @brief Align \p size to \p align, who's value is larger or equal to \p size - * and can be divided with no remainder by \p align. - * @note \p align must equal to 2^n - */ -#define ALIGN_SIZE(size, align) \ - (((uintptr_t)(size) + ((uintptr_t)(align) - 1)) & ~((uintptr_t)(align) - 1)) - #define ACCESS_ONCE(TYPE, var) (*(volatile TYPE*) &(var)) /** diff --git a/src/ev/ringbuffer.c b/src/ev/ringbuffer.c index c38e2d80a..91aec40e4 100644 --- a/src/ev/ringbuffer.c +++ b/src/ev/ringbuffer.c @@ -445,12 +445,12 @@ static int _ring_buffer_commit_for_consume(ring_buffer_t* rb, EV_LOCAL size_t ring_buffer_heap_cost(void) { /* need to align with machine size */ - return ALIGN_SIZE(sizeof(struct ring_buffer), sizeof(void*)); + return EV_ALIGN_SIZE(sizeof(struct ring_buffer), sizeof(void*)); } EV_LOCAL size_t ring_buffer_node_cost(size_t size) { - return ALIGN_SIZE(sizeof(ring_buffer_node_t) + size, sizeof(void*)); + return EV_ALIGN_SIZE(sizeof(ring_buffer_node_t) + size, sizeof(void*)); } EV_LOCAL ring_buffer_t* ring_buffer_init(void* buffer, size_t size) diff --git a/src/ev/unix/fs_unix.c b/src/ev/unix/fs_unix.c index ea882ba6b..dc9e238d8 100644 --- a/src/ev/unix/fs_unix.c +++ b/src/ev/unix/fs_unix.c @@ -366,22 +366,28 @@ EV_LOCAL int ev__fs_mkdir(const char* path, int mode) return ret; } -int ev_file_mmap(ev_file_map_t* view, ev_file_t* file, uint64_t size, int flags) +int ev_file_mmap(ev_file_map_t* view, ev_file_t* file, uint64_t offset, + size_t size, int flags) { int ret; const int prot = _ev_file_mmap_to_native_prot_unix(flags); - if (size == 0) + ev_fs_stat_t stat = EV_FS_STAT_INVALID; + if ((ret = ev__fs_fstat(file->file, &stat)) != 0) + { + return ret; + } + + if (offset >= stat.st_size) { - ev_fs_stat_t stat; - if ((ret = ev__fs_fstat(file->file, &stat)) != 0) - { - return ret; - } - size = stat.st_size; + EV_ASSERT(size > 0); + } + else if (size == 0) + { + size = stat.st_size - offset; } - view->addr = mmap(NULL, size, prot, MAP_SHARED, file->file, 0); + view->addr = mmap(NULL, size, prot, MAP_SHARED, file->file, offset); if (view->addr == NULL) { ret = errno; diff --git a/src/ev/unix/misc_unix.c b/src/ev/unix/misc_unix.c index c3f8ce8bc..79ca07441 100644 --- a/src/ev/unix/misc_unix.c +++ b/src/ev/unix/misc_unix.c @@ -10,3 +10,8 @@ size_t ev_os_page_size(void) { return sysconf(_SC_PAGE_SIZE); } + +size_t ev_os_mmap_offset_granularity(void) +{ + return ev_os_page_size(); +} diff --git a/src/ev/win/fs_win.c b/src/ev/win/fs_win.c index a795646af..fd4f533b6 100644 --- a/src/ev/win/fs_win.c +++ b/src/ev/win/fs_win.c @@ -844,23 +844,30 @@ EV_LOCAL int ev__fs_mkdir(const char* path, int mode) return (int)ret; } -int ev_file_mmap(ev_file_map_t* view, ev_file_t* file, uint64_t size, int flags) +int ev_file_mmap(ev_file_map_t* view, ev_file_t* file, uint64_t offset, + size_t size, int flags) { DWORD errcode; - if (size == 0) + LARGE_INTEGER file_sz; + if (!GetFileSizeEx(file->file, &file_sz)) { - LARGE_INTEGER file_sz; - if (!GetFileSizeEx(file->file, &file_sz)) - { - errcode = GetLastError(); - return ev__translate_sys_error(errcode); - } - size = file_sz.QuadPart; + errcode = GetLastError(); + return ev__translate_sys_error(errcode); + } + + if (offset >= (uint64_t)file_sz.QuadPart) + { + EV_ASSERT(size > 0); + } + else if (size == 0) + { + size = file_sz.QuadPart - offset; } + const uint64_t map_sz = offset + size; - const DWORD dwMaximumSizeHigh = size >> 32; - const DWORD dwMaximumSizeLow = (DWORD)size; + const DWORD dwMaximumSizeHigh = map_sz >> 32; + const DWORD dwMaximumSizeLow = (DWORD)map_sz; const DWORD flProtect = _ev_file_mmap_to_native_protect_win32(flags); view->backend.file_map_obj = CreateFileMappingW(file->file, NULL, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, NULL); @@ -871,7 +878,10 @@ int ev_file_mmap(ev_file_map_t* view, ev_file_t* file, uint64_t size, int flags) } const DWORD dwDesiredAccess = _ev_file_mmap_to_native_access(flags); - view->addr = MapViewOfFile(view->backend.file_map_obj, dwDesiredAccess, 0, 0, 0); + const DWORD dwFileOffsetHigh = offset >> 32; + const DWORD dwFileOffsetLow = (DWORD)offset; + view->addr = MapViewOfFile(view->backend.file_map_obj, dwDesiredAccess, + dwFileOffsetHigh, dwFileOffsetLow, size); if (view->addr == NULL) { CloseHandle(view->backend.file_map_obj); diff --git a/src/ev/win/misc_win.c b/src/ev/win/misc_win.c index 82cdbf620..eb9aff72e 100644 --- a/src/ev/win/misc_win.c +++ b/src/ev/win/misc_win.c @@ -195,3 +195,10 @@ size_t ev_os_page_size(void) GetSystemInfo(&sys_info); return sys_info.dwPageSize; } + +size_t ev_os_mmap_offset_granularity(void) +{ + SYSTEM_INFO sys_info; + GetSystemInfo(&sys_info); + return sys_info.dwAllocationGranularity; +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a11545c70..79cddc573 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,6 +4,7 @@ add_library(ev_test_lib SHARED "test/cases/buf.c" "test/cases/fs.c" "test/cases/fs_mmap.c" + "test/cases/fs_mmap_offset.c" "test/cases/fs_seek.c" "test/cases/ipv4_addr.c" "test/cases/list.c" diff --git a/test/cases/fs_mmap.c b/test/cases/fs_mmap.c index fef72bd27..c63f566a0 100644 --- a/test/cases/fs_mmap.c +++ b/test/cases/fs_mmap.c @@ -24,7 +24,7 @@ TEST_F(fs, mmap_size_0_rd) ASSERT_EQ_INT(ev_file_open(NULL, file, NULL, s_file_name, EV_FS_O_RDONLY, 0, NULL), 0); ev_file_map_t* view = ev_malloc(sizeof(ev_file_map_t)); - ASSERT_EQ_INT(ev_file_mmap(view, file, 0, EV_FS_S_IRUSR), 0); + ASSERT_EQ_INT(ev_file_mmap(view, file, 0, 0, EV_FS_S_IRUSR), 0); const char* content = view->addr; ASSERT_EQ_STR(content, s_file_content); @@ -48,7 +48,7 @@ TEST_F(fs, mmap_size_0_rdwr) ASSERT_EQ_INT(ev_file_open(NULL, file, NULL, s_file_name, EV_FS_O_RDWR, 0, NULL), 0); ev_file_map_t* view = ev_malloc(sizeof(ev_file_map_t)); - ASSERT_EQ_INT(ev_file_mmap(view, file, 0, EV_FS_S_IRUSR | EV_FS_S_IWUSR), 0); + ASSERT_EQ_INT(ev_file_mmap(view, file, 0, 0, EV_FS_S_IRUSR | EV_FS_S_IWUSR), 0); char* content = view->addr; ASSERT_EQ_STR(content, s_file_content); diff --git a/test/cases/fs_mmap_offset.c b/test/cases/fs_mmap_offset.c new file mode 100644 index 000000000..65dc2653f --- /dev/null +++ b/test/cases/fs_mmap_offset.c @@ -0,0 +1,67 @@ +#include "test.h" +#include "utils/file.h" +#include "utils/random.h" + +static const char* s_file_path = "29cc199c-ded0-4402-b910-a670aa64fcc1"; +static size_t s_mmap_offset_granularity = 0; +static uint8_t* s_file_data = NULL; +static size_t s_file_data_sz = 0; + +TEST_FIXTURE_SETUP(fs) +{ + s_mmap_offset_granularity = ev_os_mmap_offset_granularity(); + ASSERT_GT_SIZE(s_mmap_offset_granularity, 0); + + s_file_data_sz = s_mmap_offset_granularity * 2; + s_file_data = ev_malloc(s_file_data_sz); + test_random(s_file_data, s_file_data_sz); + + ev_fs_remove(NULL, NULL, s_file_path, 0, NULL); + test_write_file(s_file_path, s_file_data, s_file_data_sz); +} + +TEST_FIXTURE_TEARDOWN(fs) +{ + if (s_file_data != NULL) + { + ev_free(s_file_data); + s_file_data = NULL; + } + ev_fs_remove(NULL, NULL, s_file_path, 0, NULL); +} + +TEST_F(fs, mmap_offset_half_size_0) +{ + ev_file_t* file = ev_malloc(sizeof(ev_file_t)); + ASSERT_EQ_INT(ev_file_open(NULL, file, NULL, s_file_path, EV_FS_O_RDONLY, 0, NULL), 0); + + ev_file_map_t* view = ev_malloc(sizeof(ev_file_map_t)); + ASSERT_EQ_INT(ev_file_mmap(view, file, s_mmap_offset_granularity, 0, EV_FS_S_IRUSR), 0); + + const char* data = view->addr; + ASSERT_EQ_INT(memcmp(data, s_file_data + s_mmap_offset_granularity, s_mmap_offset_granularity), 0); + + ev_file_close(file, NULL); + ev_free(file); + + ev_file_munmap(view); + ev_free(view); +} + +TEST_F(fs, mmap_offset_half_size_half) +{ + ev_file_t* file = ev_malloc(sizeof(ev_file_t)); + ASSERT_EQ_INT(ev_file_open(NULL, file, NULL, s_file_path, EV_FS_O_RDONLY, 0, NULL), 0); + + ev_file_map_t* view = ev_malloc(sizeof(ev_file_map_t)); + ASSERT_EQ_INT(ev_file_mmap(view, file, s_mmap_offset_granularity, s_mmap_offset_granularity, EV_FS_S_IRUSR), 0); + + const char* data = view->addr; + ASSERT_EQ_INT(memcmp(data, s_file_data + s_mmap_offset_granularity, s_mmap_offset_granularity), 0); + + ev_file_close(file, NULL); + ev_free(file); + + ev_file_munmap(view); + ev_free(view); +}