Skip to content

Merge stable v1.0.x into main #1485

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Aug 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pr_push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,6 @@ jobs:
uses: ./.github/workflows/reusable_compatibility.yml
strategy:
matrix:
tag: ["v1.0.0"]
tag: ["v1.0.1"]
with:
tag: ${{matrix.tag}}
13 changes: 9 additions & 4 deletions .github/workflows/reusable_compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ on:
tag:
description: Check backward compatibility with this tag
type: string
default: "v1.0.0"
# While we're still compatible with v1.0.0, we implemented a fix in v1.0.1
# to verify if the split operation is supported (in jemalloc pool).
# Without bumping the tag we'd have to omit some tests.
default: "v1.0.1"

permissions:
contents: read
Expand Down Expand Up @@ -99,7 +102,7 @@ jobs:
UMF_LOG: level:warning;flush:debug;output:stderr;pid:no
LD_LIBRARY_PATH: ${{github.workspace}}/latest_version/build/lib/
run: |
ctest --verbose -E test_memoryProvider
ctest --verbose -E "test_memoryProvider"
test/test_memoryProvider --gtest_filter="-*Trace"

# Browse all folders in the examples directory, build them using the
Expand Down Expand Up @@ -226,7 +229,9 @@ jobs:
UMF_LOG: level:warning;flush:debug;output:stderr;pid:no
run: |
cp ${{github.workspace}}/latest_version/build/bin/Debug/umf.dll ${{github.workspace}}/tag_version/build/bin/Debug/umf.dll
ctest -C Debug --verbose -E test_memoryProvider
ctest -C Debug --verbose -E "test_memoryProvider"
$env:Path = "${{github.workspace}}/tag_version/build/bin/Debug;${{env.VCPKG_BIN_PATH}};$env:Path"
test/Debug/test_memoryProvider.exe --gtest_filter="-*Trace"

# Browse all folders in the examples directory, build them using the
# latest UMF version, and run them, excluding those in the exclude list.
Expand Down Expand Up @@ -368,7 +373,7 @@ jobs:
UMF_LOG: level:warning;flush:debug;output:stderr;pid:no
LD_LIBRARY_PATH: ${{github.workspace}}/latest_version/build/lib/
run: |
ctest --verbose -E test_memoryProvider
ctest --verbose -E "test_memoryProvider"
test/test_memoryProvider --gtest_filter="-*Trace"

# Browse all folders in the examples directory, build them using the
Expand Down
9 changes: 8 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,14 @@ else()
DEPENDS ${jemalloc_targ_SOURCE_DIR}/configure)

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

add_custom_command(
Expand Down
9 changes: 9 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
Fri Aug 08 2025 Łukasz Stolarczuk <[email protected]>

* Version 1.0.1

This patch release contains following changes:
- make topology_init faster (#1469)
- verify if the provider supports the split operation (#1465)
- fix build failure when building for jemalloc with ninja (#1474)

Mon Jul 21 2025 Łukasz Stolarczuk <[email protected]>

* Version 1.0.0
Expand Down
6 changes: 5 additions & 1 deletion src/libumf.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ umf_result_t umfInit(void) {
if (TRACKER) {
LOG_DEBUG("UMF library initialized");
}

#if !defined(UMF_NO_HWLOC)
// some benchmarks uses multiple forks, and topology initialization is very slow
// so if we initialize topology before the first fork, we can get significant performance gain.
umfGetTopologyReduced();
#endif
return UMF_RESULT_SUCCESS;
}

Expand Down
2 changes: 1 addition & 1 deletion src/memspaces/memspace_host_all.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ static umf_result_t umfMemspaceHostAllCreate(umf_memspace_handle_t *hMemspace) {

umf_result_t umf_ret = UMF_RESULT_SUCCESS;

hwloc_topology_t topology = umfGetTopology();
hwloc_topology_t topology = umfGetTopologyReduced();
if (!topology) {
// TODO: What would be an approrpiate err?
return UMF_RESULT_ERROR_UNKNOWN;
Expand Down
2 changes: 1 addition & 1 deletion src/memtargets/memtarget_numa.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ static umf_result_t numa_get_capacity(void *memTarget, size_t *capacity) {
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}

hwloc_topology_t topology = umfGetTopology();
hwloc_topology_t topology = umfGetTopologyReduced();
if (!topology) {
return UMF_RESULT_ERROR_NOT_SUPPORTED;
}
Expand Down
47 changes: 45 additions & 2 deletions src/pool/pool_jemalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <string.h>

#include "base_alloc_global.h"
#include "memory_provider_internal.h"
#include "provider_tracking.h"
#include "utils_common.h"
#include "utils_concurrency.h"
#include "utils_log.h"
Expand Down Expand Up @@ -283,8 +285,15 @@ static bool arena_extent_split(extent_hooks_t *extent_hooks, void *addr,

jemalloc_memory_pool_t *pool = get_pool_by_arena_index(arena_ind);
assert(pool);
return umfMemoryProviderAllocationSplit(pool->provider, addr, size,
size_a) != UMF_RESULT_SUCCESS;

umf_result_t ret =
umfMemoryProviderAllocationSplit(pool->provider, addr, size, size_a);
if (ret != UMF_RESULT_SUCCESS) {
LOG_ERR("memory provider failed to split a memory region, while "
"jemalloc requires that");
}

return ret != UMF_RESULT_SUCCESS;
}

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

// Verify if the memory provider supports the split() operation,
// because jemalloc pool requires that.
static umf_result_t verify_split(umf_memory_provider_handle_t provider) {
// Retrieve the upstream memory provider
umf_memory_provider_handle_t upstream_provider = NULL;
umfTrackingMemoryProviderGetUpstreamProvider(
umfMemoryProviderGetPriv(provider), &upstream_provider);

size_t page_size = 0;
umf_result_t ret =
umfMemoryProviderGetMinPageSize(upstream_provider, NULL, &page_size);
if (ret != UMF_RESULT_SUCCESS) {
return ret;
}

size_t size = 2 * page_size; // use double the page size for the split test
if (UMF_RESULT_ERROR_NOT_SUPPORTED ==
umfMemoryProviderAllocationSplit(upstream_provider, (void *)size, size,
page_size)) {
LOG_ERR("memory provider does not support the split operation, while "
"jemalloc pool requires that");
return UMF_RESULT_ERROR_NOT_SUPPORTED;
}

return UMF_RESULT_SUCCESS;
}

static umf_result_t op_initialize(umf_memory_provider_handle_t provider,
const void *params, void **out_pool) {
assert(provider);
assert(out_pool);

// Verify if the memory provider supports the split() operation,
// because jemalloc pool requires that.
umf_result_t ret = verify_split(provider);
if (ret != UMF_RESULT_SUCCESS) {
return ret;
}

extent_hooks_t *pHooks = &arena_extent_hooks;
size_t unsigned_size = sizeof(unsigned);
int n_arenas_set_from_params = 0;
Expand Down
19 changes: 5 additions & 14 deletions src/provider/provider_os_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "ctl/ctl_internal.h"
#include "libumf.h"
#include "provider_os_memory_internal.h"
#include "topology.h"
#include "utils_assert.h"
#include "utils_common.h"
#include "utils_concurrency.h"
Expand Down Expand Up @@ -561,27 +562,19 @@ static umf_result_t os_initialize(const void *params, void **provider) {
snprintf(os_provider->name, sizeof(os_provider->name), "%s",
in_params->name);

int r = hwloc_topology_init(&os_provider->topo);
if (r) {
LOG_ERR("HWLOC topology init failed");
ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
goto err_free_os_provider;
}

r = hwloc_topology_load(os_provider->topo);
if (r) {
os_provider->topo = umfGetTopologyReduced();
if (!os_provider->topo) {
os_store_last_native_error(UMF_OS_RESULT_ERROR_TOPO_DISCOVERY_FAILED,
0);
LOG_ERR("HWLOC topology discovery failed");
ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
goto err_destroy_hwloc_topology;
}

os_provider->fd_offset_map = critnib_new(NULL, NULL);
if (!os_provider->fd_offset_map) {
LOG_ERR("creating file descriptor offset map failed");
ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
goto err_destroy_hwloc_topology;
goto err_free_os_provider;
}

ret = translate_params(in_params, os_provider);
Expand Down Expand Up @@ -624,8 +617,6 @@ static umf_result_t os_initialize(const void *params, void **provider) {
free_bitmaps(os_provider);
err_destroy_critnib:
critnib_delete(os_provider->fd_offset_map);
err_destroy_hwloc_topology:
hwloc_topology_destroy(os_provider->topo);
err_free_os_provider:
umf_ba_global_free(os_provider);
return ret;
Expand All @@ -649,7 +640,7 @@ static umf_result_t os_finalize(void *provider) {
if (os_provider->nodeset_str_buf) {
umf_ba_global_free(os_provider->nodeset_str_buf);
}
hwloc_topology_destroy(os_provider->topo);

umf_ba_global_free(os_provider);
return UMF_RESULT_SUCCESS;
}
Expand Down
49 changes: 42 additions & 7 deletions src/topology.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Copyright (C) 2024 Intel Corporation
* Copyright (C) 2024-2025 Intel Corporation
*
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Expand All @@ -13,7 +13,9 @@
#include "utils_log.h"

static hwloc_topology_t topology = NULL;
static hwloc_topology_t topology_reduced = NULL;
static UTIL_ONCE_FLAG topology_initialized = UTIL_ONCE_FLAG_INIT;
static UTIL_ONCE_FLAG topology_reduced_initialized = UTIL_ONCE_FLAG_INIT;

void umfDestroyTopology(void) {
if (topology) {
Expand All @@ -24,22 +26,55 @@ void umfDestroyTopology(void) {
memcpy(&topology_initialized, &is_initialized,
sizeof(topology_initialized));
}
if (topology_reduced) {
hwloc_topology_destroy(topology_reduced);

// portable version of "topology_initialized = UTIL_ONCE_FLAG_INIT;"
static UTIL_ONCE_FLAG is_initialized = UTIL_ONCE_FLAG_INIT;
memcpy(&topology_reduced_initialized, &is_initialized,
sizeof(topology_reduced_initialized));
}
}

static void umfCreateTopology(void) {
if (hwloc_topology_init(&topology)) {
static void umfCreateTopologyHelper(bool reduced,
hwloc_topology_t *topology_ptr) {
if (hwloc_topology_init(topology_ptr)) {
LOG_ERR("Failed to initialize topology");
topology = NULL;
*topology_ptr = NULL;
return;
}

if (hwloc_topology_load(topology)) {
if (reduced) {
// Set the topology to only include NUMA nodes and memory
// to improve performance of the topology load on large systems
if (hwloc_topology_set_all_types_filter(*topology_ptr,
HWLOC_TYPE_FILTER_KEEP_NONE)) {
LOG_ERR("Failed to set topology filter");
hwloc_topology_destroy(*topology_ptr);
*topology_ptr = NULL;
return;
}
}
if (hwloc_topology_load(*topology_ptr)) {
LOG_ERR("Failed to initialize topology");
hwloc_topology_destroy(topology);
topology = NULL;
hwloc_topology_destroy(*topology_ptr);
*topology_ptr = NULL;
}
}

static void umfCreateTopology(void) {
umfCreateTopologyHelper(false, &topology);
}

static void umfCreateTopologyReduced(void) {
umfCreateTopologyHelper(true, &topology_reduced);
}

hwloc_topology_t umfGetTopologyReduced(void) {
utils_init_once(&topology_reduced_initialized, umfCreateTopologyReduced);
return topology_reduced;
}

hwloc_topology_t umfGetTopology(void) {
utils_init_once(&topology_initialized, umfCreateTopology);
return topology;
Expand Down
3 changes: 2 additions & 1 deletion src/topology.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
*
* Copyright (C) 2024 Intel Corporation
* Copyright (C) 2024-2025 Intel Corporation
*
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Expand All @@ -17,6 +17,7 @@ extern "C" {
#endif

hwloc_topology_t umfGetTopology(void);
hwloc_topology_t umfGetTopologyReduced(void);
void umfDestroyTopology(void);

#ifdef __cplusplus
Expand Down
Loading
Loading