mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-19 21:28:50 +00:00
ipc: Define shmem utilities for Linux and Android
This commit is contained in:
parent
25627e55ca
commit
20c65e74e3
|
@ -24,6 +24,8 @@ proto_gen(${CMAKE_CURRENT_BINARY_DIR}/ipc_server_generated.c)
|
||||||
|
|
||||||
set(IPC_COMMON_SOURCES
|
set(IPC_COMMON_SOURCES
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/ipc_protocol_generated.h
|
${CMAKE_CURRENT_BINARY_DIR}/ipc_protocol_generated.h
|
||||||
|
ipc_shmem.c
|
||||||
|
ipc_shmem.h
|
||||||
ipc_utils.c
|
ipc_utils.c
|
||||||
ipc_utils.h)
|
ipc_utils.h)
|
||||||
###
|
###
|
||||||
|
|
116
src/xrt/ipc/ipc_shmem.c
Normal file
116
src/xrt/ipc/ipc_shmem.c
Normal 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
70
src/xrt/ipc/ipc_shmem.h
Normal 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
|
|
@ -9,6 +9,8 @@ ipc_include = include_directories('.')
|
||||||
prog_python = import('python').find_installation('python3')
|
prog_python = import('python').find_installation('python3')
|
||||||
|
|
||||||
common_sources = [
|
common_sources = [
|
||||||
|
'ipc_shmem.c',
|
||||||
|
'ipc_shmem.h',
|
||||||
'ipc_utils.c',
|
'ipc_utils.c',
|
||||||
'ipc_utils.h',
|
'ipc_utils.h',
|
||||||
]
|
]
|
||||||
|
@ -44,7 +46,7 @@ lib_ipc_client = static_library(
|
||||||
include_directories: [
|
include_directories: [
|
||||||
xrt_include,
|
xrt_include,
|
||||||
],
|
],
|
||||||
dependencies: [aux]
|
dependencies: [aux, rt]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue