Skip to content

Commit 5453804

Browse files
authored
Merge pull request #506 from ldorau/Replace_an_anonymous_file_with_a_shared_memory_object
Add support for a named POSIX shared memory to OS memory provider
2 parents 9902c0f + 2b8b84f commit 5453804

20 files changed

+433
-86
lines changed

CMakeLists.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -479,9 +479,10 @@ install(
479479
examples/basic/utils_level_zero.h
480480
examples/basic/basic.c
481481
examples/basic/ipc_level_zero.c
482-
examples/basic/ipc_shm_ipcapi.sh
483-
examples/basic/ipc_shm_ipcapi_consumer.c
484-
examples/basic/ipc_shm_ipcapi_producer.c
482+
examples/basic/ipc_ipcapi_anon_fd.sh
483+
examples/basic/ipc_ipcapi_consumer.c
484+
examples/basic/ipc_ipcapi_producer.c
485+
examples/basic/ipc_ipcapi_shm.sh
485486
DESTINATION "${CMAKE_INSTALL_DOCDIR}/examples")
486487

487488
# Add the include directory and the headers target to the install.

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,18 @@ More detailed documentation is available here: https://oneapi-src.github.io/unif
142142
#### OS memory provider
143143

144144
A memory provider that provides memory from an operating system.
145-
It supports two types of memory mappings
145+
146+
OS memory provider supports two types of memory mappings (set by the `visibility` parameter):
146147
1) private memory mapping (`UMF_MEM_MAP_PRIVATE`)
147148
2) shared memory mapping (`UMF_MEM_MAP_SHARED` - supported on Linux only yet)
148149

149-
If the shared memory mapping is used then an anonymous file descriptor for memory mapping is created using:
150+
There are available two mechanisms for the shared memory mapping:
151+
1) a named shared memory object (used if the `shm_name` parameter is not NULL) or
152+
2) an anonymous file descriptor (used if the `shm_name` parameter is NULL)
153+
154+
The `shm_name` parameter should be a null-terminated string of up to NAME_MAX (i.e., 255) characters none of which are slashes.
155+
156+
An anonymous file descriptor for the shared memory mapping will be created using:
150157
1) `memfd_secret()` syscall - (if it is implemented and) if the `UMF_MEM_FD_FUNC` environment variable does not contain the "memfd_create" string or
151158
2) `memfd_create()` syscall - otherwise (and if it is implemented).
152159

examples/CMakeLists.txt

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ else()
116116
)
117117
endif()
118118

119-
if(LINUX)
120-
set(BASE_NAME ipc_shm_ipcapi)
119+
function(build_umf_ipc_example name)
120+
set(BASE_NAME ${name})
121121
set(EXAMPLE_NAME umf_example_${BASE_NAME})
122122

123123
foreach(loop_var IN ITEMS "producer" "consumer")
@@ -133,22 +133,32 @@ if(LINUX)
133133

134134
target_link_directories(${EX_NAME} PRIVATE ${LIBHWLOC_LIBRARY_DIRS})
135135
endforeach(loop_var)
136+
endfunction()
137+
138+
function(add_umf_ipc_example script)
139+
set(EXAMPLE_NAME umf_example_${script})
136140

137-
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/basic/${BASE_NAME}.sh
141+
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/basic/${script}.sh
138142
DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
139143

140144
add_test(
141145
NAME ${EXAMPLE_NAME}
142-
COMMAND ${BASE_NAME}.sh
146+
COMMAND ${script}.sh
143147
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
144148

145149
set_tests_properties(${EXAMPLE_NAME} PROPERTIES LABELS "example")
146150
if(NOT UMF_TESTS_FAIL_ON_SKIP)
147151
set_tests_properties(${EXAMPLE_NAME} PROPERTIES SKIP_RETURN_CODE 125)
148152
endif()
153+
endfunction()
154+
155+
if(LINUX)
156+
build_umf_ipc_example(ipc_ipcapi)
157+
add_umf_ipc_example(ipc_ipcapi_anon_fd)
158+
add_umf_ipc_example(ipc_ipcapi_shm)
149159
else()
150160
message(
151161
STATUS
152-
"IPC shared memory example with UMF pool API is supported on Linux only - skipping"
162+
"IPC examples with UMF pool API are supported on Linux only - skipping"
153163
)
154164
endif()

examples/basic/ipc_shm_ipcapi.sh renamed to examples/basic/ipc_ipcapi_anon_fd.sh

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77

88
#!/bin/bash
99

10+
set -e
11+
1012
# port should be a number from the range <1024, 65535>
1113
PORT=$(( 1024 + ( $$ % ( 65535 - 1024 ))))
1214

13-
# The ipc_shm_ipcapi example requires using pidfd_getfd(2)
15+
# The ipc_ipcapi_anon_fd example requires using pidfd_getfd(2)
1416
# to obtain a duplicate of another process's file descriptor.
1517
# Permission to duplicate another process's file descriptor
1618
# is governed by a ptrace access mode PTRACE_MODE_ATTACH_REALCREDS check (see ptrace(2))
@@ -27,11 +29,11 @@ fi
2729

2830
UMF_LOG_VAL="level:debug;flush:debug;output:stderr;pid:yes"
2931

30-
echo "Starting ipc_shm_ipcapi CONSUMER on port $PORT ..."
31-
UMF_LOG=$UMF_LOG_VAL ./umf_example_ipc_shm_ipcapi_consumer $PORT &
32+
echo "Starting ipc_ipcapi_anon_fd CONSUMER on port $PORT ..."
33+
UMF_LOG=$UMF_LOG_VAL ./umf_example_ipc_ipcapi_consumer $PORT &
3234

3335
echo "Waiting 1 sec ..."
3436
sleep 1
3537

36-
echo "Starting ipc_shm_ipcapi PRODUCER on port $PORT ..."
37-
UMF_LOG=$UMF_LOG_VAL ./umf_example_ipc_shm_ipcapi_producer $PORT
38+
echo "Starting ipc_ipcapi_anon_fd PRODUCER on port $PORT ..."
39+
UMF_LOG=$UMF_LOG_VAL ./umf_example_ipc_ipcapi_producer $PORT

examples/basic/ipc_shm_ipcapi_consumer.c renamed to examples/basic/ipc_ipcapi_consumer.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ int main(int argc, char *argv[]) {
9292
int ret = -1;
9393

9494
if (argc < 2) {
95-
fprintf(stderr, "usage: %s port\n", argv[0]);
95+
fprintf(stderr, "usage: %s <port> [shm_name]\n", argv[0]);
9696
return -1;
9797
}
9898

@@ -104,6 +104,9 @@ int main(int argc, char *argv[]) {
104104

105105
os_params = umfOsMemoryProviderParamsDefault();
106106
os_params.visibility = UMF_MEM_MAP_SHARED;
107+
if (argc >= 3) {
108+
os_params.shm_name = argv[2];
109+
}
107110

108111
// create OS memory provider
109112
umf_result = umfMemoryProviderCreate(umfOsMemoryProviderOps(), &os_params,

examples/basic/ipc_shm_ipcapi_producer.c renamed to examples/basic/ipc_ipcapi_producer.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ int main(int argc, char *argv[]) {
6363
int ret = -1;
6464

6565
if (argc < 2) {
66-
fprintf(stderr, "Usage: %s port\n", argv[0]);
66+
fprintf(stderr, "usage: %s <port> [shm_name]\n", argv[0]);
6767
return -1;
6868
}
6969

@@ -75,6 +75,9 @@ int main(int argc, char *argv[]) {
7575

7676
os_params = umfOsMemoryProviderParamsDefault();
7777
os_params.visibility = UMF_MEM_MAP_SHARED;
78+
if (argc >= 3) {
79+
os_params.shm_name = argv[2];
80+
}
7881

7982
// create OS memory provider
8083
umf_result = umfMemoryProviderCreate(umfOsMemoryProviderOps(), &os_params,

examples/basic/ipc_ipcapi_shm.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#
2+
# Copyright (C) 2024 Intel Corporation
3+
#
4+
# Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
5+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
#
7+
8+
#!/bin/bash
9+
10+
set -e
11+
12+
SHM_NAME="umf_shm_example"
13+
14+
# port should be a number from the range <1024, 65535>
15+
PORT=$(( 1024 + ( $$ % ( 65535 - 1024 ))))
16+
17+
UMF_LOG_VAL="level:debug;flush:debug;output:stderr;pid:yes"
18+
19+
# make sure the SHM file does not exist
20+
rm -f /dev/shm/${SHM_NAME}
21+
22+
echo "Starting ipc_ipcapi_shm CONSUMER on port $PORT ..."
23+
UMF_LOG=$UMF_LOG_VAL ./umf_example_ipc_ipcapi_consumer $PORT $SHM_NAME &
24+
25+
echo "Waiting 1 sec ..."
26+
sleep 1
27+
28+
echo "Starting ipc_ipcapi_shm PRODUCER on port $PORT ..."
29+
UMF_LOG=$UMF_LOG_VAL ./umf_example_ipc_ipcapi_producer $PORT $SHM_NAME
30+
31+
# remove the SHM file
32+
rm -f /dev/shm/${SHM_NAME}

include/umf/providers/provider_os_memory.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ typedef struct umf_os_memory_provider_params_t {
6969
unsigned protection;
7070
/// memory visibility mode
7171
umf_memory_visibility_t visibility;
72+
/// (optional) a name of a shared memory file (valid only in case of the shared memory visibility)
73+
char *shm_name;
7274

7375
// NUMA config
7476
/// ordered list of numa nodes
@@ -103,10 +105,11 @@ umfOsMemoryProviderParamsDefault(void) {
103105
umf_os_memory_provider_params_t params = {
104106
UMF_PROTECTION_READ | UMF_PROTECTION_WRITE, /* protection */
105107
UMF_MEM_MAP_PRIVATE, /* visibility mode */
106-
NULL, /* numa_list */
107-
0, /* numa_list_len */
108-
UMF_NUMA_MODE_DEFAULT, /* numa_mode */
109-
0 /* part_size */
108+
NULL, /* (optional) a name of a shared memory file (valid only in case of the shared memory visibility) */
109+
NULL, /* numa_list */
110+
0, /* numa_list_len */
111+
UMF_NUMA_MODE_DEFAULT, /* numa_mode */
112+
0 /* part_size */
110113
};
111114

112115
return params;

src/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ set(UMF_PRIVATE_LIBRARY_DIRS ${UMF_PRIVATE_LIBRARY_DIRS}
103103

104104
if(LINUX)
105105
set(UMF_SOURCES ${UMF_SOURCES} ${UMF_SOURCES_LINUX})
106-
set(UMF_LIBS ${UMF_LIBS} dl)
106+
set(UMF_LIBS ${UMF_LIBS} dl rt) # librt for shm_open()
107107
elseif(WINDOWS)
108108
set(UMF_SOURCES ${UMF_SOURCES} ${UMF_SOURCES_WINDOWS})
109109
elseif(MACOSX)

0 commit comments

Comments
 (0)