Skip to content

Commit 4d67d7d

Browse files
Merge branch 'v1.0.x' into 'main'
2 parents cc0565d + f3dfe30 commit 4d67d7d

File tree

12 files changed

+165
-45
lines changed

12 files changed

+165
-45
lines changed

.github/workflows/reusable_compatibility.yml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,17 @@ jobs:
9393
run: |
9494
LD_LIBRARY_PATH=${{github.workspace}}/tag_version/build/lib/ ctest --output-on-failure
9595
96+
# Exclude the test_jemalloc_pool test -
97+
# TODO: add fix for that in v1.0.1
9698
- name: Run "tag" UMF tests with latest UMF libs (warnings enabled)
9799
working-directory: ${{github.workspace}}/tag_version/build
98100
env:
99101
UMF_LOG: level:warning;flush:debug;output:stderr;pid:no
100102
LD_LIBRARY_PATH: ${{github.workspace}}/latest_version/build/lib/
101103
run: |
102-
ctest --verbose -E test_memoryProvider
104+
ctest --verbose -E "test_memoryProvider|test_jemalloc_pool"
103105
test/test_memoryProvider --gtest_filter="-*Trace"
106+
test/test_jemalloc_pool --gtest_filter="-*jemallocPoolName*"
104107
105108
# Browse all folders in the examples directory, build them using the
106109
# latest UMF version, and run them, excluding those in the exclude list.
@@ -220,13 +223,18 @@ jobs:
220223
working-directory: "${{github.workspace}}/tag_version/build"
221224
run: ctest -C Debug --output-on-failure --test-dir test
222225

226+
# Exclude the test_jemalloc_pool test -
227+
# TODO: add fix for that in v1.0.1
223228
- name: Run "tag" UMF tests with latest UMF libs (warnings enabled)
224229
working-directory: ${{github.workspace}}/tag_version/build
225230
env:
226231
UMF_LOG: level:warning;flush:debug;output:stderr;pid:no
227232
run: |
228233
cp ${{github.workspace}}/latest_version/build/bin/Debug/umf.dll ${{github.workspace}}/tag_version/build/bin/Debug/umf.dll
229-
ctest -C Debug --verbose -E test_memoryProvider
234+
ctest -C Debug --verbose -E "test_memoryProvider|test_jemalloc_pool"
235+
$env:Path = "${{github.workspace}}/tag_version/build/bin/Debug;${{env.VCPKG_BIN_PATH}};$env:Path"
236+
test/Debug/test_memoryProvider.exe --gtest_filter="-*Trace"
237+
test/Debug/test_jemalloc_pool.exe --gtest_filter="-*jemallocPoolName*"
230238
231239
# Browse all folders in the examples directory, build them using the
232240
# latest UMF version, and run them, excluding those in the exclude list.
@@ -362,14 +370,17 @@ jobs:
362370
LD_LIBRARY_PATH=${{github.workspace}}/tag_version/build/lib/
363371
ctest --output-on-failure
364372
373+
# Exclude the test_jemalloc_pool test -
374+
# TODO: add fix for that in v1.0.1
365375
- name: Run "tag" UMF tests with latest UMF libs (warnings enabled)
366376
working-directory: ${{github.workspace}}/tag_version/build
367377
env:
368378
UMF_LOG: level:warning;flush:debug;output:stderr;pid:no
369379
LD_LIBRARY_PATH: ${{github.workspace}}/latest_version/build/lib/
370380
run: |
371-
ctest --verbose -E test_memoryProvider
381+
ctest --verbose -E "test_memoryProvider|test_jemalloc_pool"
372382
test/test_memoryProvider --gtest_filter="-*Trace"
383+
test/test_jemalloc_pool --gtest_filter="-*jemallocPoolName*"
373384
374385
# Browse all folders in the examples directory, build them using the
375386
# latest UMF version, and run them, excluding those in the exclude list.

CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,14 @@ else()
203203
DEPENDS ${jemalloc_targ_SOURCE_DIR}/configure)
204204

205205
if(NOT UMF_QEMU_BUILD)
206-
set(MAKE_ARGUMENTS "-j$(nproc)")
206+
if(CMAKE_GENERATOR STREQUAL "Ninja")
207+
# While CMake is supposed to escape this in the generated build
208+
# files, for some reason, it doesn't do so here. Until it's fixed,
209+
# we just manually escape it for ninja.
210+
set(MAKE_ARGUMENTS "-j$$(nproc)")
211+
else()
212+
set(MAKE_ARGUMENTS "-j$(nproc)")
213+
endif()
207214
endif()
208215

209216
add_custom_command(

ChangeLog

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
Fri Aug 08 2025 Łukasz Stolarczuk <[email protected]>
2+
3+
* Version 1.0.1
4+
5+
This patch release contains following changes:
6+
- make topology_init faster (#1469)
7+
- verify if the provider supports the split operation (#1465)
8+
- fix build failure when building for jemalloc with ninja (#1474)
9+
110
Mon Jul 21 2025 Łukasz Stolarczuk <[email protected]>
211

312
* Version 1.0.0

src/libumf.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,11 @@ umf_result_t umfInit(void) {
9191
if (TRACKER) {
9292
LOG_DEBUG("UMF library initialized");
9393
}
94-
94+
#if !defined(UMF_NO_HWLOC)
95+
// some benchmarks uses multiple forks, and topology initialization is very slow
96+
// so if we initialize topology before the first fork, we can get significant performance gain.
97+
umfGetTopologyReduced();
98+
#endif
9599
return UMF_RESULT_SUCCESS;
96100
}
97101

src/memspaces/memspace_host_all.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static umf_result_t umfMemspaceHostAllCreate(umf_memspace_handle_t *hMemspace) {
3535

3636
umf_result_t umf_ret = UMF_RESULT_SUCCESS;
3737

38-
hwloc_topology_t topology = umfGetTopology();
38+
hwloc_topology_t topology = umfGetTopologyReduced();
3939
if (!topology) {
4040
// TODO: What would be an approrpiate err?
4141
return UMF_RESULT_ERROR_UNKNOWN;

src/memtargets/memtarget_numa.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ static umf_result_t numa_get_capacity(void *memTarget, size_t *capacity) {
218218
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
219219
}
220220

221-
hwloc_topology_t topology = umfGetTopology();
221+
hwloc_topology_t topology = umfGetTopologyReduced();
222222
if (!topology) {
223223
return UMF_RESULT_ERROR_NOT_SUPPORTED;
224224
}

src/pool/pool_jemalloc.c

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <string.h>
1313

1414
#include "base_alloc_global.h"
15+
#include "memory_provider_internal.h"
16+
#include "provider_tracking.h"
1517
#include "utils_common.h"
1618
#include "utils_concurrency.h"
1719
#include "utils_log.h"
@@ -283,8 +285,15 @@ static bool arena_extent_split(extent_hooks_t *extent_hooks, void *addr,
283285

284286
jemalloc_memory_pool_t *pool = get_pool_by_arena_index(arena_ind);
285287
assert(pool);
286-
return umfMemoryProviderAllocationSplit(pool->provider, addr, size,
287-
size_a) != UMF_RESULT_SUCCESS;
288+
289+
umf_result_t ret =
290+
umfMemoryProviderAllocationSplit(pool->provider, addr, size, size_a);
291+
if (ret != UMF_RESULT_SUCCESS) {
292+
LOG_ERR("memory provider failed to split a memory region, while "
293+
"jemalloc requires that");
294+
}
295+
296+
return ret != UMF_RESULT_SUCCESS;
288297
}
289298

290299
// arena_extent_merge - an extent merge function conforms to the extent_merge_t type and optionally
@@ -435,11 +444,45 @@ static void *op_aligned_alloc(void *pool, size_t size, size_t alignment) {
435444
return ptr;
436445
}
437446

447+
// Verify if the memory provider supports the split() operation,
448+
// because jemalloc pool requires that.
449+
static umf_result_t verify_split(umf_memory_provider_handle_t provider) {
450+
// Retrieve the upstream memory provider
451+
umf_memory_provider_handle_t upstream_provider = NULL;
452+
umfTrackingMemoryProviderGetUpstreamProvider(
453+
umfMemoryProviderGetPriv(provider), &upstream_provider);
454+
455+
size_t page_size = 0;
456+
umf_result_t ret =
457+
umfMemoryProviderGetMinPageSize(upstream_provider, NULL, &page_size);
458+
if (ret != UMF_RESULT_SUCCESS) {
459+
return ret;
460+
}
461+
462+
size_t size = 2 * page_size; // use double the page size for the split test
463+
if (UMF_RESULT_ERROR_NOT_SUPPORTED ==
464+
umfMemoryProviderAllocationSplit(upstream_provider, (void *)size, size,
465+
page_size)) {
466+
LOG_ERR("memory provider does not support the split operation, while "
467+
"jemalloc pool requires that");
468+
return UMF_RESULT_ERROR_NOT_SUPPORTED;
469+
}
470+
471+
return UMF_RESULT_SUCCESS;
472+
}
473+
438474
static umf_result_t op_initialize(umf_memory_provider_handle_t provider,
439475
const void *params, void **out_pool) {
440476
assert(provider);
441477
assert(out_pool);
442478

479+
// Verify if the memory provider supports the split() operation,
480+
// because jemalloc pool requires that.
481+
umf_result_t ret = verify_split(provider);
482+
if (ret != UMF_RESULT_SUCCESS) {
483+
return ret;
484+
}
485+
443486
extent_hooks_t *pHooks = &arena_extent_hooks;
444487
size_t unsigned_size = sizeof(unsigned);
445488
int n_arenas_set_from_params = 0;

src/provider/provider_os_memory.c

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "ctl/ctl_internal.h"
2525
#include "libumf.h"
2626
#include "provider_os_memory_internal.h"
27+
#include "topology.h"
2728
#include "utils_assert.h"
2829
#include "utils_common.h"
2930
#include "utils_concurrency.h"
@@ -561,27 +562,19 @@ static umf_result_t os_initialize(const void *params, void **provider) {
561562
snprintf(os_provider->name, sizeof(os_provider->name), "%s",
562563
in_params->name);
563564

564-
int r = hwloc_topology_init(&os_provider->topo);
565-
if (r) {
566-
LOG_ERR("HWLOC topology init failed");
567-
ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
568-
goto err_free_os_provider;
569-
}
570-
571-
r = hwloc_topology_load(os_provider->topo);
572-
if (r) {
565+
os_provider->topo = umfGetTopologyReduced();
566+
if (!os_provider->topo) {
573567
os_store_last_native_error(UMF_OS_RESULT_ERROR_TOPO_DISCOVERY_FAILED,
574568
0);
575569
LOG_ERR("HWLOC topology discovery failed");
576570
ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
577-
goto err_destroy_hwloc_topology;
578571
}
579572

580573
os_provider->fd_offset_map = critnib_new(NULL, NULL);
581574
if (!os_provider->fd_offset_map) {
582575
LOG_ERR("creating file descriptor offset map failed");
583576
ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
584-
goto err_destroy_hwloc_topology;
577+
goto err_free_os_provider;
585578
}
586579

587580
ret = translate_params(in_params, os_provider);
@@ -624,8 +617,6 @@ static umf_result_t os_initialize(const void *params, void **provider) {
624617
free_bitmaps(os_provider);
625618
err_destroy_critnib:
626619
critnib_delete(os_provider->fd_offset_map);
627-
err_destroy_hwloc_topology:
628-
hwloc_topology_destroy(os_provider->topo);
629620
err_free_os_provider:
630621
umf_ba_global_free(os_provider);
631622
return ret;
@@ -649,7 +640,7 @@ static umf_result_t os_finalize(void *provider) {
649640
if (os_provider->nodeset_str_buf) {
650641
umf_ba_global_free(os_provider->nodeset_str_buf);
651642
}
652-
hwloc_topology_destroy(os_provider->topo);
643+
653644
umf_ba_global_free(os_provider);
654645
return UMF_RESULT_SUCCESS;
655646
}

src/topology.c

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
*
3-
* Copyright (C) 2024 Intel Corporation
3+
* Copyright (C) 2024-2025 Intel Corporation
44
*
55
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
66
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -13,7 +13,9 @@
1313
#include "utils_log.h"
1414

1515
static hwloc_topology_t topology = NULL;
16+
static hwloc_topology_t topology_reduced = NULL;
1617
static UTIL_ONCE_FLAG topology_initialized = UTIL_ONCE_FLAG_INIT;
18+
static UTIL_ONCE_FLAG topology_reduced_initialized = UTIL_ONCE_FLAG_INIT;
1719

1820
void umfDestroyTopology(void) {
1921
if (topology) {
@@ -24,22 +26,55 @@ void umfDestroyTopology(void) {
2426
memcpy(&topology_initialized, &is_initialized,
2527
sizeof(topology_initialized));
2628
}
29+
if (topology_reduced) {
30+
hwloc_topology_destroy(topology_reduced);
31+
32+
// portable version of "topology_initialized = UTIL_ONCE_FLAG_INIT;"
33+
static UTIL_ONCE_FLAG is_initialized = UTIL_ONCE_FLAG_INIT;
34+
memcpy(&topology_reduced_initialized, &is_initialized,
35+
sizeof(topology_reduced_initialized));
36+
}
2737
}
2838

29-
static void umfCreateTopology(void) {
30-
if (hwloc_topology_init(&topology)) {
39+
static void umfCreateTopologyHelper(bool reduced,
40+
hwloc_topology_t *topology_ptr) {
41+
if (hwloc_topology_init(topology_ptr)) {
3142
LOG_ERR("Failed to initialize topology");
32-
topology = NULL;
43+
*topology_ptr = NULL;
3344
return;
3445
}
3546

36-
if (hwloc_topology_load(topology)) {
47+
if (reduced) {
48+
// Set the topology to only include NUMA nodes and memory
49+
// to improve performance of the topology load on large systems
50+
if (hwloc_topology_set_all_types_filter(*topology_ptr,
51+
HWLOC_TYPE_FILTER_KEEP_NONE)) {
52+
LOG_ERR("Failed to set topology filter");
53+
hwloc_topology_destroy(*topology_ptr);
54+
*topology_ptr = NULL;
55+
return;
56+
}
57+
}
58+
if (hwloc_topology_load(*topology_ptr)) {
3759
LOG_ERR("Failed to initialize topology");
38-
hwloc_topology_destroy(topology);
39-
topology = NULL;
60+
hwloc_topology_destroy(*topology_ptr);
61+
*topology_ptr = NULL;
4062
}
4163
}
4264

65+
static void umfCreateTopology(void) {
66+
umfCreateTopologyHelper(false, &topology);
67+
}
68+
69+
static void umfCreateTopologyReduced(void) {
70+
umfCreateTopologyHelper(true, &topology_reduced);
71+
}
72+
73+
hwloc_topology_t umfGetTopologyReduced(void) {
74+
utils_init_once(&topology_reduced_initialized, umfCreateTopologyReduced);
75+
return topology_reduced;
76+
}
77+
4378
hwloc_topology_t umfGetTopology(void) {
4479
utils_init_once(&topology_initialized, umfCreateTopology);
4580
return topology;

src/topology.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
*
3-
* Copyright (C) 2024 Intel Corporation
3+
* Copyright (C) 2024-2025 Intel Corporation
44
*
55
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
66
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -17,6 +17,7 @@ extern "C" {
1717
#endif
1818

1919
hwloc_topology_t umfGetTopology(void);
20+
hwloc_topology_t umfGetTopologyReduced(void);
2021
void umfDestroyTopology(void);
2122

2223
#ifdef __cplusplus

0 commit comments

Comments
 (0)