Skip to content

Commit 8b86b9d

Browse files
Merge pull request #750 from ldorau/Add_dram_and_fsdax_example
Add dram_and_fsdax example
2 parents ea53923 + b2c18af commit 8b86b9d

File tree

8 files changed

+321
-13
lines changed

8 files changed

+321
-13
lines changed

.github/workflows/dax.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#
1212
# The FSDAX device should be mounted in the OS (e.g. /mnt/pmem1)
1313
# and the UMF_TESTS_FSDAX_PATH environment variable
14-
# should contain a path to a file o this FSDAX device.
14+
# should contain a path to a file on this FSDAX device.
1515
#
1616

1717
name: Dax
@@ -96,6 +96,6 @@ jobs:
9696
9797
- name: Run the FSDAX tests
9898
working-directory: ${{env.BUILD_DIR}}
99-
run: >
100-
UMF_TESTS_FSDAX_PATH=${{env.UMF_TESTS_FSDAX_PATH}}
101-
ctest -C ${{matrix.build_type}} -R umf-provider_file_memory -V
99+
run: |
100+
UMF_TESTS_FSDAX_PATH=${{env.UMF_TESTS_FSDAX_PATH}} ctest -C ${{matrix.build_type}} -R umf-provider_file_memory -V
101+
UMF_TESTS_FSDAX_PATH=${{env.UMF_TESTS_FSDAX_PATH}} ctest -C ${{matrix.build_type}} -R umf_example_dram_and_fsdax -V

CMakeLists.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,9 +355,12 @@ if(UMF_BUILD_LIBUMF_POOL_JEMALLOC)
355355
if(NOT JEMALLOC_FOUND)
356356
find_package(JEMALLOC REQUIRED jemalloc)
357357
endif()
358-
# add PATH to DLL on Windows
359-
set(DLL_PATH_LIST
360-
"${DLL_PATH_LIST};PATH=path_list_append:${JEMALLOC_DLL_DIRS}")
358+
if(JEMALLOC_FOUND OR JEMALLOC_LIBRARIES)
359+
set(UMF_POOL_JEMALLOC_ENABLED TRUE)
360+
# add PATH to DLL on Windows
361+
set(DLL_PATH_LIST
362+
"${DLL_PATH_LIST};PATH=path_list_append:${JEMALLOC_DLL_DIRS}")
363+
endif()
361364
endif()
362365

363366
if(WINDOWS)

examples/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,19 @@ if(LINUX)
270270
COMMAND ${EXAMPLE_NAME}
271271
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
272272

273+
if(UMF_POOL_JEMALLOC_ENABLED)
274+
set(EXAMPLE_NAME umf_example_dram_and_fsdax)
275+
276+
add_umf_executable(
277+
NAME ${EXAMPLE_NAME}
278+
SRCS dram_and_fsdax/dram_and_fsdax.c
279+
LIBS umf jemalloc_pool)
280+
281+
add_test(
282+
NAME ${EXAMPLE_NAME}
283+
COMMAND ${EXAMPLE_NAME}
284+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
285+
endif()
273286
else()
274287
message(
275288
STATUS "Memspace examples API are supported on Linux only - skipping")

examples/cmake/FindJEMALLOC.cmake

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Copyright (C) 2024 Intel Corporation
2+
# Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
3+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
5+
message(STATUS "Checking for module 'jemalloc' using find_library()")
6+
7+
find_library(JEMALLOC_LIBRARY NAMES libjemalloc jemalloc)
8+
set(JEMALLOC_LIBRARIES ${JEMALLOC_LIBRARY})
9+
10+
get_filename_component(JEMALLOC_LIB_DIR ${JEMALLOC_LIBRARIES} DIRECTORY)
11+
set(JEMALLOC_LIBRARY_DIRS ${JEMALLOC_LIB_DIR})
12+
13+
find_file(JEMALLOC_HEADER NAMES "jemalloc/jemalloc.h")
14+
if(JEMALLOC_HEADER)
15+
get_filename_component(JEMALLOC_INCLUDE_DIR_TBB ${JEMALLOC_HEADER}
16+
DIRECTORY)
17+
get_filename_component(JEMALLOC_INCLUDE_DIR ${JEMALLOC_INCLUDE_DIR_TBB}
18+
DIRECTORY)
19+
set(JEMALLOC_INCLUDE_DIRS ${JEMALLOC_INCLUDE_DIR})
20+
else()
21+
set(MSG_NOT_FOUND "<jemalloc/jemalloc.h> header NOT found "
22+
"(set CMAKE_PREFIX_PATH to point the location)")
23+
if(JEMALLOC_FIND_REQUIRED)
24+
message(FATAL_ERROR ${MSG_NOT_FOUND})
25+
else()
26+
message(WARNING ${MSG_NOT_FOUND})
27+
endif()
28+
endif()
29+
30+
if(WINDOWS)
31+
find_file(JEMALLOC_DLL NAMES "bin/jemalloc.dll" "jemalloc.dll")
32+
get_filename_component(JEMALLOC_DLL_DIR ${JEMALLOC_DLL} DIRECTORY)
33+
set(JEMALLOC_DLL_DIRS ${JEMALLOC_DLL_DIR})
34+
endif()
35+
36+
if(JEMALLOC_LIBRARY)
37+
message(STATUS " Found jemalloc using find_library()")
38+
message(STATUS " JEMALLOC_LIBRARIES = ${JEMALLOC_LIBRARIES}")
39+
message(STATUS " JEMALLOC_INCLUDE_DIRS = ${JEMALLOC_INCLUDE_DIRS}")
40+
message(STATUS " JEMALLOC_LIBRARY_DIRS = ${JEMALLOC_LIBRARY_DIRS}")
41+
if(WINDOWS)
42+
message(STATUS " JEMALLOC_DLL_DIRS = ${JEMALLOC_DLL_DIRS}")
43+
endif()
44+
else()
45+
set(MSG_NOT_FOUND
46+
"jemalloc NOT found (set CMAKE_PREFIX_PATH to point the location)")
47+
if(JEMALLOC_FIND_REQUIRED)
48+
message(FATAL_ERROR ${MSG_NOT_FOUND})
49+
else()
50+
message(WARNING ${MSG_NOT_FOUND})
51+
endif()
52+
endif()
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Copyright (C) 2024 Intel Corporation
2+
# Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
3+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
5+
cmake_minimum_required(VERSION 3.14.0 FATAL_ERROR)
6+
project(umf_example_dram_and_fsdax LANGUAGES C)
7+
enable_testing()
8+
9+
set(UMF_EXAMPLE_DIR "${CMAKE_SOURCE_DIR}/..")
10+
list(APPEND CMAKE_MODULE_PATH "${UMF_EXAMPLE_DIR}/cmake")
11+
message(STATUS "CMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}")
12+
13+
find_package(PkgConfig)
14+
pkg_check_modules(LIBUMF libumf)
15+
if(NOT LIBUMF_FOUND)
16+
find_package(LIBUMF REQUIRED libumf)
17+
endif()
18+
19+
pkg_check_modules(LIBHWLOC hwloc>=2.3.0)
20+
if(NOT LIBHWLOC_FOUND)
21+
find_package(LIBHWLOC 2.3.0 REQUIRED hwloc)
22+
endif()
23+
24+
pkg_check_modules(JEMALLOC jemalloc)
25+
if(NOT JEMALLOC_FOUND)
26+
find_package(JEMALLOC REQUIRED jemalloc)
27+
endif()
28+
29+
# build the example
30+
set(EXAMPLE_NAME umf_example_dram_and_fsdax)
31+
add_executable(${EXAMPLE_NAME} dram_and_fsdax.c)
32+
target_include_directories(${EXAMPLE_NAME} PRIVATE ${LIBUMF_INCLUDE_DIRS})
33+
34+
target_link_directories(
35+
${EXAMPLE_NAME}
36+
PRIVATE
37+
${LIBUMF_LIBRARY_DIRS}
38+
${LIBHWLOC_LIBRARY_DIRS}
39+
${JEMALLOC_LIBRARY_DIRS})
40+
41+
target_link_libraries(
42+
${EXAMPLE_NAME} PRIVATE hwloc jemalloc_pool ${JEMALLOC_LIBRARIES}
43+
${LIBUMF_LIBRARIES})
44+
45+
# an optional part - adds a test of this example
46+
add_test(
47+
NAME ${EXAMPLE_NAME}
48+
COMMAND ${EXAMPLE_NAME}
49+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
50+
51+
set_tests_properties(${EXAMPLE_NAME} PROPERTIES LABELS "example-standalone")
52+
53+
if(LINUX)
54+
# set LD_LIBRARY_PATH
55+
set_property(
56+
TEST ${EXAMPLE_NAME}
57+
PROPERTY
58+
ENVIRONMENT_MODIFICATION
59+
"LD_LIBRARY_PATH=path_list_append:${LIBUMF_LIBRARY_DIRS};LD_LIBRARY_PATH=path_list_append:${LIBHWLOC_LIBRARY_DIRS};LD_LIBRARY_PATH=path_list_append:${JEMALLOC_LIBRARY_DIRS}"
60+
)
61+
endif()
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
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+
#include <stdio.h>
9+
#include <stdlib.h>
10+
#include <string.h>
11+
12+
#include <umf/memory_provider.h>
13+
#include <umf/providers/provider_file_memory.h>
14+
#include <umf/providers/provider_os_memory.h>
15+
16+
#include <umf/memory_pool.h>
17+
#include <umf/pools/pool_jemalloc.h>
18+
19+
static umf_memory_pool_handle_t create_dram_pool(void) {
20+
umf_memory_provider_handle_t provider_dram = NULL;
21+
umf_memory_pool_handle_t pool_dram;
22+
umf_result_t umf_result;
23+
24+
umf_os_memory_provider_params_t params_dram =
25+
umfOsMemoryProviderParamsDefault();
26+
27+
umf_result = umfMemoryProviderCreate(umfOsMemoryProviderOps(), &params_dram,
28+
&provider_dram);
29+
if (umf_result != UMF_RESULT_SUCCESS) {
30+
fprintf(stderr, "Creation of the OS memory provider failed");
31+
return NULL;
32+
}
33+
34+
// Create a DRAM memory pool
35+
umf_result = umfPoolCreate(umfJemallocPoolOps(), provider_dram, NULL,
36+
UMF_POOL_CREATE_FLAG_OWN_PROVIDER, &pool_dram);
37+
if (umf_result != UMF_RESULT_SUCCESS) {
38+
fprintf(stderr, "Failed to create a DRAM memory pool!\n");
39+
umfMemoryProviderDestroy(provider_dram);
40+
return NULL;
41+
}
42+
43+
return pool_dram;
44+
}
45+
46+
static umf_memory_pool_handle_t create_fsdax_pool(const char *path) {
47+
umf_memory_provider_handle_t provider_fsdax = NULL;
48+
umf_memory_pool_handle_t pool_fsdax;
49+
umf_result_t umf_result;
50+
51+
umf_file_memory_provider_params_t params_fsdax =
52+
umfFileMemoryProviderParamsDefault(path);
53+
// FSDAX requires mapping the UMF_MEM_MAP_SYNC flag
54+
params_fsdax.visibility = UMF_MEM_MAP_SYNC;
55+
56+
umf_result = umfMemoryProviderCreate(umfFileMemoryProviderOps(),
57+
&params_fsdax, &provider_fsdax);
58+
if (umf_result != UMF_RESULT_SUCCESS) {
59+
fprintf(stderr, "Failed to create the FSDAX file provider");
60+
return NULL;
61+
}
62+
63+
// Create an FSDAX memory pool
64+
//
65+
// The file memory provider does not support the free operation
66+
// (`umfMemoryProviderFree()` always returns `UMF_RESULT_ERROR_NOT_SUPPORTED`),
67+
// so it should be used with a pool manager that will take over
68+
// the managing of the provided memory - for example the jemalloc pool
69+
// with the `disable_provider_free` parameter set to true.
70+
umf_jemalloc_pool_params_t pool_params;
71+
pool_params.disable_provider_free = true;
72+
73+
// Create an FSDAX memory pool
74+
umf_result =
75+
umfPoolCreate(umfJemallocPoolOps(), provider_fsdax, &pool_params,
76+
UMF_POOL_CREATE_FLAG_OWN_PROVIDER, &pool_fsdax);
77+
if (umf_result != UMF_RESULT_SUCCESS) {
78+
fprintf(stderr, "Failed to create an FSDAX memory pool!\n");
79+
umfMemoryProviderDestroy(provider_fsdax);
80+
return NULL;
81+
}
82+
83+
return pool_fsdax;
84+
}
85+
86+
int main(void) {
87+
int ret = -1;
88+
89+
// This example requires:
90+
// - the FSDAX device to be mounted in the OS (e.g. /mnt/pmem1) and
91+
// - the UMF_TESTS_FSDAX_PATH environment variable to contain
92+
// a path to a file on this FSDAX device.
93+
char *path = getenv("UMF_TESTS_FSDAX_PATH");
94+
if (path == NULL || path[0] == 0) {
95+
fprintf(
96+
stderr,
97+
"Warning: UMF_TESTS_FSDAX_PATH is not set, skipping testing ...\n");
98+
return 0;
99+
}
100+
101+
umf_memory_pool_handle_t dram_pool = create_dram_pool();
102+
if (dram_pool == NULL) {
103+
fprintf(stderr, "Failed to create a DRAM memory pool!\n");
104+
return -1;
105+
}
106+
107+
fprintf(stderr, "Created a DRAM memory pool\n");
108+
109+
umf_memory_pool_handle_t fsdax_pool = create_fsdax_pool(path);
110+
if (fsdax_pool == NULL) {
111+
fprintf(stderr, "Failed to create an FSDAX memory pool!\n");
112+
goto err_destroy_dram_pool;
113+
}
114+
115+
fprintf(stderr, "Created an FSDAX memory pool\n");
116+
117+
size_t size = 2 * 1024 * 1024; // == 2 MB
118+
119+
// Allocate from the DRAM memory pool
120+
char *dram_buf = umfPoolCalloc(dram_pool, 1, size);
121+
if (dram_buf == NULL) {
122+
fprintf(stderr,
123+
"Failed to allocate memory from the DRAM memory pool!\n");
124+
goto err_destroy_pools;
125+
}
126+
127+
fprintf(stderr, "Allocated memory from the DRAM memory pool\n");
128+
129+
// Allocate from the FSDAX memory pool
130+
char *fsdax_buf = umfPoolCalloc(fsdax_pool, 1, size);
131+
if (fsdax_buf == NULL) {
132+
fprintf(stderr,
133+
"Failed to allocate memory from the FSDAX memory pool!\n");
134+
goto err_free_dram;
135+
}
136+
137+
fprintf(stderr, "Allocated memory from the FSDAX memory pool\n");
138+
139+
// Use the allocation from DRAM
140+
dram_buf[0] = '.';
141+
142+
// Use the allocation from FSDAX
143+
fsdax_buf[0] = '.';
144+
145+
// success
146+
ret = 0;
147+
148+
// The file memory provider does not support the free() operation,
149+
// so we do not need to call: umfPoolFree(fsdax_pool, fsdax_buf);
150+
151+
err_free_dram:
152+
fprintf(stderr, "Freeing the allocation from the DRAM memory pool ...\n");
153+
umfPoolFree(dram_pool, dram_buf);
154+
155+
err_destroy_pools:
156+
fprintf(stderr, "Destroying the FSDAX memory pool ...\n");
157+
umfPoolDestroy(fsdax_pool);
158+
159+
err_destroy_dram_pool:
160+
fprintf(stderr, "Destroying the DRAM memory pool ...\n");
161+
umfPoolDestroy(dram_pool);
162+
163+
return ret;
164+
}

test/CMakeLists.txt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ if(LINUX
543543
)
544544
endif()
545545

546-
if(LINUX AND UMF_POOL_SCALABLE_ENABLED)
546+
if(UMF_POOL_SCALABLE_ENABLED)
547547
set(EXAMPLES ${EXAMPLES} ipc_ipcapi)
548548
else()
549549
message(
@@ -552,14 +552,27 @@ if(LINUX
552552
)
553553
endif()
554554

555+
if(UMF_POOL_JEMALLOC_ENABLED)
556+
set(EXAMPLES ${EXAMPLES} dram_and_fsdax)
557+
else()
558+
message(
559+
STATUS
560+
"The dram_and_fsdax example is supported on Linux only and requires UMF_BUILD_LIBUMF_POOL_JEMALLOC to be turned ON - skipping"
561+
)
562+
endif()
563+
555564
if(EXAMPLES AND NOT UMF_DISABLE_HWLOC)
565+
set(STANDALONE_CMAKE_OPTIONS
566+
"-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
567+
)
556568
add_test(
557569
NAME umf-standalone_examples
558570
COMMAND
559571
${UMF_CMAKE_SOURCE_DIR}/test/test_examples.sh
560572
${UMF_CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}
561573
${CMAKE_CURRENT_BINARY_DIR}/umf_standalone_examples/install-dir
562-
"${CMAKE_INSTALL_PREFIX}" ${EXAMPLES}
574+
"${CMAKE_INSTALL_PREFIX}" "${STANDALONE_CMAKE_OPTIONS}"
575+
${EXAMPLES}
563576
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
564577
endif()
565578
endif()

0 commit comments

Comments
 (0)