The open source OpenXR runtime
at prediction-2 193 lines 3.9 kB view raw
1// Copyright 2020, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief IPC shared memory helpers 6 * @author Rylie Pavlik <rylie.pavlik@collabora.com> 7 * @author Pete Black <pblack@collabora.com> 8 * @author Jakob Bornecrantz <jakob@collabora.com> 9 * @ingroup ipc_shared 10 */ 11 12#include <xrt/xrt_config_os.h> 13 14#include "shared/ipc_shmem.h" 15 16#if defined(XRT_OS_UNIX) 17#include <sys/mman.h> 18#include <unistd.h> 19#endif 20 21#if defined(XRT_OS_ANDROID) 22#include <android/sharedmem.h> 23#elif defined(XRT_OS_UNIX) 24// non-android unix 25#include <sys/stat.h> 26#include <fcntl.h> 27#endif 28 29#if defined(XRT_OS_ANDROID) 30 31#if __ANDROID_API__ < 26 32#error "Android API level 26 or higher needed for ASharedMemory_create" 33#endif 34xrt_result_t 35 36ipc_shmem_create(size_t size, xrt_shmem_handle_t *out_handle, void **out_map) 37{ 38 39 int fd = ASharedMemory_create("monado", size); 40 if (fd < 0) { 41 return XRT_ERROR_IPC_FAILURE; 42 } 43 xrt_result_t result = ipc_shmem_map(fd, size, out_map); 44 if (result != XRT_SUCCESS) { 45 close(fd); 46 return result; 47 } 48 *out_handle = fd; 49 return XRT_SUCCESS; 50} 51 52#elif defined(XRT_OS_UNIX) 53 54#define MONADO_SHMEM_NAME "/monado_shm" 55// Impl for non-Android Unix. 56xrt_result_t 57ipc_shmem_create(size_t size, xrt_shmem_handle_t *out_handle, void **out_map) 58{ 59 *out_handle = -1; 60 int fd = shm_open(MONADO_SHMEM_NAME, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); 61 if (fd < 0) { 62 return XRT_ERROR_IPC_FAILURE; 63 } 64 65 if (ftruncate(fd, size) < 0) { 66 close(fd); 67 return XRT_ERROR_IPC_FAILURE; 68 } 69 xrt_result_t result = ipc_shmem_map(fd, size, out_map); 70 if (result != XRT_SUCCESS) { 71 close(fd); 72 return result; 73 } 74 75 // Don't need the name entry anymore, we can share the FD. 76 shm_unlink(MONADO_SHMEM_NAME); 77 *out_handle = fd; 78 return XRT_SUCCESS; 79} 80 81#elif defined(XRT_OS_WINDOWS) 82 83xrt_result_t 84ipc_shmem_create(size_t size, xrt_shmem_handle_t *out_handle, void **out_map) 85{ 86 *out_handle = NULL; 87 LARGE_INTEGER sz = {.QuadPart = size}; 88 HANDLE handle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, sz.HighPart, sz.LowPart, NULL); 89 if (handle == NULL) { 90 return XRT_ERROR_IPC_FAILURE; 91 } 92 93 xrt_result_t result = ipc_shmem_map(handle, size, out_map); 94 if (result != XRT_SUCCESS) { 95 CloseHandle(handle); 96 return result; 97 } 98 99 *out_handle = handle; 100 return XRT_SUCCESS; 101} 102 103#else 104#error "OS not yet supported" 105#endif 106 107#if defined(XRT_OS_UNIX) 108 109void 110ipc_shmem_destroy(xrt_shmem_handle_t *handle_ptr, void **map_ptr, size_t size) 111{ 112 // Checks for NULL. 113 ipc_shmem_unmap((void **)map_ptr, size); 114 115 if (handle_ptr == NULL) { 116 return; 117 } 118 xrt_shmem_handle_t handle = *handle_ptr; 119 if (handle < 0) { 120 return; 121 } 122 close(handle); 123 *handle_ptr = -1; 124} 125 126xrt_result_t 127ipc_shmem_map(xrt_shmem_handle_t handle, size_t size, void **out_map) 128{ 129 130 const int access = PROT_READ | PROT_WRITE; 131 const int flags = MAP_SHARED; 132 void *ptr = mmap(NULL, size, access, flags, handle, 0); 133 if (ptr == NULL) { 134 return XRT_ERROR_IPC_FAILURE; 135 } 136 *out_map = ptr; 137 return XRT_SUCCESS; 138} 139 140void 141ipc_shmem_unmap(void **map_ptr, size_t size) 142{ 143 if (map_ptr == NULL) { 144 return; 145 } 146 munmap(*map_ptr, size); 147 *map_ptr = NULL; 148} 149 150#elif defined(XRT_OS_WINDOWS) 151 152void 153ipc_shmem_destroy(xrt_shmem_handle_t *handle_ptr, void **map_ptr, size_t size) 154{ 155 // Checks for NULL. 156 ipc_shmem_unmap((void **)map_ptr, size); 157 158 if (handle_ptr == NULL) { 159 return; 160 } 161 xrt_shmem_handle_t handle = *handle_ptr; 162 CloseHandle(handle); 163 *handle_ptr = NULL; 164} 165 166xrt_result_t 167ipc_shmem_map(xrt_shmem_handle_t handle, size_t size, void **out_map) 168{ 169 void *ptr = MapViewOfFile(handle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, size); 170 if (ptr == NULL) { 171 return XRT_ERROR_IPC_FAILURE; 172 } 173 *out_map = ptr; 174 return XRT_SUCCESS; 175} 176 177void 178ipc_shmem_unmap(void **map_ptr, size_t size) 179{ 180 if (map_ptr == NULL) { 181 return; 182 } 183 void *map = *map_ptr; 184 if (map == NULL) { 185 return; 186 } 187 UnmapViewOfFile(map); 188 *map_ptr = NULL; 189} 190 191#else 192#error "OS not yet supported" 193#endif