ipc: Define shmem utilities for Linux and Android

This commit is contained in:
Ryan Pavlik 2020-07-16 11:21:13 -05:00
parent 25627e55ca
commit 20c65e74e3
4 changed files with 191 additions and 1 deletions

View file

@ -24,6 +24,8 @@ proto_gen(${CMAKE_CURRENT_BINARY_DIR}/ipc_server_generated.c)
set(IPC_COMMON_SOURCES
${CMAKE_CURRENT_BINARY_DIR}/ipc_protocol_generated.h
ipc_shmem.c
ipc_shmem.h
ipc_utils.c
ipc_utils.h)
###

116
src/xrt/ipc/ipc_shmem.c Normal file
View file

@ -0,0 +1,116 @@
// Copyright 2020, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief IPC shared memory helpers
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
* @author Pete Black <pblack@collabora.com>
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup ipc_internal
*/
#include <xrt/xrt_config_os.h>
#include "ipc_shmem.h"
#if defined(XRT_OS_UNIX)
#include <sys/mman.h>
#include <unistd.h>
#endif
#if defined(XRT_OS_ANDROID)
#include <android/sharedmem.h>
#elif defined(XRT_OS_UNIX)
// non-android unix
#include <sys/stat.h>
#include <fcntl.h>
#endif
#if defined(XRT_OS_ANDROID)
#if __ANDROID_API__ < 26
#error "Android API level 26 or higher needed for ASharedMemory_create"
#endif
xrt_result_t
ipc_shmem_create(size_t size, xrt_shmem_handle_t *out_handle, void **out_map)
{
int fd = ASharedMemory_create("monado", size);
if (fd < 0) {
return XRT_ERROR_IPC_FAILURE;
}
xrt_result_t result = ipc_shmem_map(fd, size, out_map);
if (result != XRT_SUCCESS) {
close(fd);
return result;
}
*out_handle = fd;
return XRT_SUCCESS;
}
#elif defined(XRT_OS_UNIX)
#define MONADO_SHMEM_NAME "/monado_shm"
// Impl for non-Android Unix.
xrt_result_t
ipc_shmem_create(size_t size, xrt_shmem_handle_t *out_handle, void **out_map)
{
*out_handle = -1;
int fd =
shm_open(MONADO_SHMEM_NAME, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
return XRT_ERROR_IPC_FAILURE;
}
if (ftruncate(fd, size) < 0) {
close(fd);
return XRT_ERROR_IPC_FAILURE;
}
xrt_result_t result = ipc_shmem_map(fd, size, out_map);
if (result != XRT_SUCCESS) {
close(fd);
return result;
}
// Don't need the name entry anymore, we can share the FD.
shm_unlink(MONADO_SHMEM_NAME);
*out_handle = fd;
return XRT_SUCCESS;
}
#else
#error "OS not yet supported"
#endif
#if defined(XRT_OS_UNIX)
void
ipc_shmem_destroy(xrt_shmem_handle_t *handle_ptr)
{
if (handle_ptr == NULL) {
return;
}
xrt_shmem_handle_t handle = *handle_ptr;
if (handle < 0) {
return;
}
close(handle);
*handle_ptr = -1;
}
xrt_result_t
ipc_shmem_map(xrt_shmem_handle_t handle, size_t size, void **out_map)
{
const int access = PROT_READ | PROT_WRITE;
const int flags = MAP_SHARED;
void *ptr = mmap(NULL, size, access, flags, handle, 0);
if (ptr == NULL) {
return XRT_ERROR_IPC_FAILURE;
}
*out_map = ptr;
return XRT_SUCCESS;
}
#else
#error "OS not yet supported"
#endif

70
src/xrt/ipc/ipc_shmem.h Normal file
View file

@ -0,0 +1,70 @@
// Copyright 2020, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Shared memory helpers
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
* @ingroup ipc_internal
*/
#pragma once
#include <xrt/xrt_handles.h>
#include <xrt/xrt_results.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @class xrt_shmem_handle_t
* @brief Generic typedef for platform-specific shared memory handle.
*/
/*!
* Create and map a shared memory region.
*
* @param[in] size Desired size of region
* @param[in,out] out_handle Pointer to the handle to populate. Receives the
* handle if this succeeds, or the invalid value if it fails.
* @param[in,out] out_map Pointer to the pointer to populate with the mapping of
* this shared memory region. On failure, contents are undefined.
*
* @public @memberof xrt_shmem_handle_t
*/
xrt_result_t
ipc_shmem_create(size_t size, xrt_shmem_handle_t *out_handle, void **out_map);
/*!
* Map a shared memory region.
*
* @param[in] handle Handle for region
* @param[in] size Size of region
* @param[in,out] out_map Pointer to the pointer to populate with the mapping of
* this shared memory region.
*
* @public @memberof xrt_shmem_handle_t
*/
xrt_result_t
ipc_shmem_map(xrt_shmem_handle_t handle, size_t size, void **out_map);
/*!
* Destroy a handle to a shared memory region.
*
* This probably does not destroy the underlying region, if other references to
* it (in this process or others) are still open.
*
* @param[in,out] handle_ptr Pointer to the handle to destroy - will be checked
* for validity, destroyed, and cleared.
*
* @public @memberof xrt_shmem_handle_t
*/
void
ipc_shmem_destroy(xrt_shmem_handle_t *handle_ptr);
#ifdef __cplusplus
}
#endif

View file

@ -9,6 +9,8 @@ ipc_include = include_directories('.')
prog_python = import('python').find_installation('python3')
common_sources = [
'ipc_shmem.c',
'ipc_shmem.h',
'ipc_utils.c',
'ipc_utils.h',
]
@ -44,7 +46,7 @@ lib_ipc_client = static_library(
include_directories: [
xrt_include,
],
dependencies: [aux]
dependencies: [aux, rt]
)