diff --git a/src/utils/utils_common.h b/src/utils/utils_common.h index 6920d97cf6..9ef2b3cf13 100644 --- a/src/utils/utils_common.h +++ b/src/utils/utils_common.h @@ -23,8 +23,10 @@ extern "C" { #endif typedef enum umf_purge_advise_t { - UMF_PURGE_LAZY, + UMF_PURGE_LAZY = 1, UMF_PURGE_FORCE, + + UMF_PURGE_MAX, // must be the last one } umf_purge_advise_t; #define DO_WHILE_EMPTY \ @@ -117,6 +119,8 @@ int utils_gettid(void); // close file descriptor int utils_close_fd(int fd); +umf_result_t utils_errno_to_umf_result(int err); + // obtain a duplicate of another process's file descriptor umf_result_t utils_duplicate_fd(int pid, int fd_in, int *fd_out); @@ -130,6 +134,8 @@ umf_result_t utils_translate_flags(unsigned in_flags, unsigned max, umf_result_t utils_translate_mem_protection_flags(unsigned in_protection, unsigned *out_protection); +int utils_translate_purge_advise(umf_purge_advise_t advise); + umf_result_t utils_translate_mem_visibility_flag(umf_memory_visibility_t in_flag, unsigned *out_flag); diff --git a/src/utils/utils_posix_common.c b/src/utils/utils_posix_common.c index b0add36b90..4a60cbb1f2 100644 --- a/src/utils/utils_posix_common.c +++ b/src/utils/utils_posix_common.c @@ -64,8 +64,7 @@ int utils_gettid(void) { int utils_close_fd(int fd) { return close(fd); } -#ifndef __APPLE__ -static umf_result_t errno_to_umf_result(int err) { +umf_result_t utils_errno_to_umf_result(int err) { switch (err) { case EBADF: case EINVAL: @@ -83,7 +82,6 @@ static umf_result_t errno_to_umf_result(int err) { return UMF_RESULT_ERROR_UNKNOWN; } } -#endif umf_result_t utils_duplicate_fd(int pid, int fd_in, int *fd_out) { #ifdef __APPLE__ @@ -102,14 +100,14 @@ umf_result_t utils_duplicate_fd(int pid, int fd_in, int *fd_out) { int pid_fd = syscall(__NR_pidfd_open, pid, 0); if (pid_fd == -1) { LOG_PERR("__NR_pidfd_open"); - return errno_to_umf_result(errno); + return utils_errno_to_umf_result(errno); } int fd_dup = syscall(__NR_pidfd_getfd, pid_fd, fd_in, 0); close(pid_fd); if (fd_dup == -1) { LOG_PERR("__NR_pidfd_open"); - return errno_to_umf_result(errno); + return utils_errno_to_umf_result(errno); } *fd_out = fd_dup; @@ -147,14 +145,15 @@ umf_result_t utils_translate_mem_protection_flags(unsigned in_protection, out_protection); } -static int utils_translate_purge_advise(umf_purge_advise_t advise) { +int utils_translate_purge_advise(umf_purge_advise_t advise) { switch (advise) { case UMF_PURGE_LAZY: return MADV_FREE; case UMF_PURGE_FORCE: return MADV_DONTNEED; + default: + return -1; } - return -1; } void *utils_mmap(void *hint_addr, size_t length, int prot, int flag, int fd, diff --git a/src/utils/utils_windows_common.c b/src/utils/utils_windows_common.c index e941b317d7..b6c5b0b4ee 100644 --- a/src/utils/utils_windows_common.c +++ b/src/utils/utils_windows_common.c @@ -45,6 +45,11 @@ int utils_close_fd(int fd) { return -1; } +umf_result_t utils_errno_to_umf_result(int err) { + (void)err; // unused + return UMF_RESULT_ERROR_NOT_SUPPORTED; +} + umf_result_t utils_duplicate_fd(int pid, int fd_in, int *fd_out) { (void)pid; // unused (void)fd_in; // unused @@ -87,6 +92,11 @@ umf_result_t utils_translate_mem_protection_flags(unsigned in_protection, return UMF_RESULT_ERROR_INVALID_ARGUMENT; } +int utils_translate_purge_advise(umf_purge_advise_t advise) { + (void)advise; // unused + return -1; +} + umf_result_t utils_translate_mem_visibility_flag(umf_memory_visibility_t in_flag, unsigned *out_flag) { diff --git a/test/utils/utils_linux.cpp b/test/utils/utils_linux.cpp index cbe99ae74c..7aa0a9d834 100644 --- a/test/utils/utils_linux.cpp +++ b/test/utils/utils_linux.cpp @@ -2,6 +2,8 @@ // Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include + #include "base.hpp" #include "utils/utils_common.h" @@ -77,3 +79,93 @@ TEST_F(test, utils_get_size_threshold) { EXPECT_EQ(utils_get_size_threshold((char *)"size.threshold=abc"), -1); EXPECT_EQ(utils_get_size_threshold((char *)"size.threshold=-111"), -1); } + +TEST_F(test, utils_errno_to_umf_result) { + EXPECT_EQ(utils_errno_to_umf_result(EBADF), + UMF_RESULT_ERROR_INVALID_ARGUMENT); + EXPECT_EQ(utils_errno_to_umf_result(EINVAL), + UMF_RESULT_ERROR_INVALID_ARGUMENT); + EXPECT_EQ(utils_errno_to_umf_result(ESRCH), + UMF_RESULT_ERROR_INVALID_ARGUMENT); + EXPECT_EQ(utils_errno_to_umf_result(EPERM), + UMF_RESULT_ERROR_INVALID_ARGUMENT); + + EXPECT_EQ(utils_errno_to_umf_result(EMFILE), + UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY); + EXPECT_EQ(utils_errno_to_umf_result(ENOMEM), + UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY); + + EXPECT_EQ(utils_errno_to_umf_result(ENODEV), + UMF_RESULT_ERROR_NOT_SUPPORTED); + EXPECT_EQ(utils_errno_to_umf_result(ENOSYS), + UMF_RESULT_ERROR_NOT_SUPPORTED); + EXPECT_EQ(utils_errno_to_umf_result(ENOTSUP), + UMF_RESULT_ERROR_NOT_SUPPORTED); + + EXPECT_EQ(utils_errno_to_umf_result(E2BIG), UMF_RESULT_ERROR_UNKNOWN); +} + +TEST_F(test, utils_translate_mem_protection_flags) { + umf_result_t umf_result; + unsigned out_protection; + + umf_result = utils_translate_mem_protection_flags(UMF_PROTECTION_NONE, + &out_protection); + EXPECT_EQ(umf_result, UMF_RESULT_SUCCESS); + EXPECT_EQ(out_protection, PROT_NONE); + + umf_result = utils_translate_mem_protection_flags(UMF_PROTECTION_READ, + &out_protection); + EXPECT_EQ(umf_result, UMF_RESULT_SUCCESS); + EXPECT_EQ(out_protection, PROT_READ); + + umf_result = utils_translate_mem_protection_flags(UMF_PROTECTION_WRITE, + &out_protection); + EXPECT_EQ(umf_result, UMF_RESULT_SUCCESS); + EXPECT_EQ(out_protection, PROT_WRITE); + + umf_result = utils_translate_mem_protection_flags(UMF_PROTECTION_EXEC, + &out_protection); + EXPECT_EQ(umf_result, UMF_RESULT_SUCCESS); + EXPECT_EQ(out_protection, PROT_EXEC); + + umf_result = utils_translate_mem_protection_flags( + UMF_PROTECTION_READ | UMF_PROTECTION_WRITE, &out_protection); + EXPECT_EQ(umf_result, UMF_RESULT_SUCCESS); + EXPECT_EQ(out_protection, PROT_READ | PROT_WRITE); + + umf_result = utils_translate_mem_protection_flags( + UMF_PROTECTION_READ | UMF_PROTECTION_WRITE | UMF_PROTECTION_EXEC, + &out_protection); + EXPECT_EQ(umf_result, UMF_RESULT_SUCCESS); + EXPECT_EQ(out_protection, PROT_READ | PROT_WRITE | PROT_EXEC); + + umf_result = utils_translate_mem_protection_flags( + UMF_PROTECTION_READ | UMF_PROTECTION_EXEC, &out_protection); + EXPECT_EQ(umf_result, UMF_RESULT_SUCCESS); + EXPECT_EQ(out_protection, PROT_READ | PROT_EXEC); + + umf_result = utils_translate_mem_protection_flags( + UMF_PROTECTION_WRITE | UMF_PROTECTION_EXEC, &out_protection); + EXPECT_EQ(umf_result, UMF_RESULT_SUCCESS); + EXPECT_EQ(out_protection, PROT_WRITE | PROT_EXEC); + + // see https://github.com/oneapi-src/unified-memory-framework/issues/923 + out_protection = 0; + umf_result = utils_translate_mem_protection_flags( + 0xFFFF & ~(((UMF_PROTECTION_MAX - 1) << 1) - 1), &out_protection); + EXPECT_EQ(umf_result, UMF_RESULT_ERROR_INVALID_ARGUMENT); + EXPECT_EQ(out_protection, 0); +} + +TEST_F(test, utils_translate_purge_advise) { + EXPECT_EQ(utils_translate_purge_advise(UMF_PURGE_LAZY), MADV_FREE); + EXPECT_EQ(utils_translate_purge_advise(UMF_PURGE_FORCE), MADV_DONTNEED); + EXPECT_EQ(utils_translate_purge_advise(UMF_PURGE_MAX), -1); +} + +TEST_F(test, utils_open) { + EXPECT_EQ(utils_devdax_open(NULL), -1); + EXPECT_EQ(utils_file_open(NULL), -1); + EXPECT_EQ(utils_file_open_or_create(NULL), -1); +}