Skip to content

Commit b725362

Browse files
authored
Merge pull request #315 from igchor/uma_memory_tracking_provider
[uma] memory tracking provider
2 parents 4f48ed8 + 9b9258e commit b725362

File tree

14 files changed

+661
-91
lines changed

14 files changed

+661
-91
lines changed

source/common/uma_helpers.hpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <uma/memory_provider.h>
1515
#include <uma/memory_provider_ops.h>
1616

17+
#include <functional>
1718
#include <memory>
1819
#include <stdexcept>
1920
#include <tuple>
@@ -22,9 +23,11 @@
2223
namespace uma {
2324

2425
using pool_unique_handle_t =
25-
std::unique_ptr<uma_memory_pool_t, decltype(&umaPoolDestroy)>;
26+
std::unique_ptr<uma_memory_pool_t,
27+
std::function<void(uma_memory_pool_handle_t)>>;
2628
using provider_unique_handle_t =
27-
std::unique_ptr<uma_memory_provider_t, decltype(&umaMemoryProviderDestroy)>;
29+
std::unique_ptr<uma_memory_provider_t,
30+
std::function<void(uma_memory_provider_handle_t)>>;
2831

2932
/// @brief creates UMA memory provider based on given T type.
3033
/// T should implement all functions defined by
@@ -45,7 +48,7 @@ auto memoryProviderMakeUnique(Args &&...args) {
4548
auto provider = new T;
4649
*obj = provider;
4750
return std::apply(&T::initialize,
48-
std::tuple_cat(std::make_tuple(*provider), *tuple));
51+
std::tuple_cat(std::make_tuple(provider), *tuple));
4952
};
5053
ops.finalize = [](void *obj) { delete reinterpret_cast<T *>(obj); };
5154
ops.alloc = [](void *obj, auto... args) {
@@ -74,25 +77,34 @@ auto memoryProviderMakeUnique(Args &&...args) {
7477
/// replaced by dtor). All arguments passed to this function are
7578
/// forwarded to T::initialize(). All functions of T
7679
/// should be noexcept.
77-
template <typename T, typename... Args> auto poolMakeUnique(Args &&...args) {
80+
template <typename T, typename... Args>
81+
auto poolMakeUnique(uma_memory_provider_handle_t *providers,
82+
size_t numProviders, Args &&...args) {
7883
uma_memory_pool_ops_t ops;
7984
auto argsTuple = std::make_tuple(std::forward<Args>(args)...);
80-
static_assert(
81-
noexcept(std::declval<T>().initialize(std::forward<Args>(args)...)));
85+
static_assert(noexcept(std::declval<T>().initialize(
86+
providers, numProviders, std::forward<Args>(args)...)));
8287

8388
ops.version = UMA_VERSION_CURRENT;
84-
ops.initialize = [](void *params, void **obj) {
89+
ops.initialize = [](uma_memory_provider_handle_t *providers,
90+
size_t numProviders, void *params, void **obj) {
8591
auto *tuple = reinterpret_cast<decltype(argsTuple) *>(params);
8692
auto pool = new T;
8793
*obj = pool;
88-
return std::apply(&T::initialize,
89-
std::tuple_cat(std::make_tuple(*pool), *tuple));
94+
return std::apply(
95+
&T::initialize,
96+
std::tuple_cat(std::make_tuple(pool, providers, numProviders),
97+
*tuple));
9098
};
9199
ops.finalize = [](void *obj) { delete reinterpret_cast<T *>(obj); };
92100
ops.malloc = [](void *obj, auto... args) {
93101
static_assert(noexcept(reinterpret_cast<T *>(obj)->malloc(args...)));
94102
return reinterpret_cast<T *>(obj)->malloc(args...);
95103
};
104+
ops.calloc = [](void *obj, auto... args) {
105+
static_assert(noexcept(reinterpret_cast<T *>(obj)->calloc(args...)));
106+
return reinterpret_cast<T *>(obj)->calloc(args...);
107+
};
96108
ops.aligned_malloc = [](void *obj, auto... args) {
97109
static_assert(
98110
noexcept(reinterpret_cast<T *>(obj)->aligned_malloc(args...)));
@@ -118,7 +130,7 @@ template <typename T, typename... Args> auto poolMakeUnique(Args &&...args) {
118130
};
119131

120132
uma_memory_pool_handle_t hPool = nullptr;
121-
auto ret = umaPoolCreate(&ops, &argsTuple, &hPool);
133+
auto ret = umaPoolCreate(&ops, providers, numProviders, &argsTuple, &hPool);
122134
return std::pair<uma_result_t, pool_unique_handle_t>{
123135
ret, pool_unique_handle_t(hPool, &umaPoolDestroy)};
124136
}

source/common/unified_memory_allocation/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
set(UMA_SOURCES
55
src/memory_pool.c
66
src/memory_provider.c
7+
src/memory_tracker.cpp
78
)
89

910
if(UMA_BUILD_SHARED_LIBRARY)

source/common/unified_memory_allocation/include/uma/memory_pool.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,27 @@
1010
#define UMA_MEMORY_POOL_H 1
1111

1212
#include <uma/base.h>
13-
#include <uma/memory_pool_ops.h>
13+
#include <uma/memory_provider.h>
1414

1515
#ifdef __cplusplus
1616
extern "C" {
1717
#endif
1818

1919
typedef struct uma_memory_pool_t *uma_memory_pool_handle_t;
2020

21+
struct uma_memory_pool_ops_t;
22+
2123
///
2224
/// \brief Creates new memory pool
2325
/// \param ops instance of uma_memory_pool_ops_t
26+
/// \param providers array of memory providers that will be used for coarse-grain allocations. Should contain at least one memory provider.
27+
/// \param numProvider number of elements in the providers array
2428
/// \param params pointer to pool-specific parameters
2529
/// \return UMA_RESULT_SUCCESS on success or appropriate error code on failure
2630
///
27-
enum uma_result_t umaPoolCreate(struct uma_memory_pool_ops_t *ops, void *params,
31+
enum uma_result_t umaPoolCreate(struct uma_memory_pool_ops_t *ops,
32+
uma_memory_provider_handle_t *providers,
33+
size_t numProviders, void *params,
2834
uma_memory_pool_handle_t *hPool);
2935

3036
///
@@ -87,6 +93,12 @@ size_t umaPoolMallocUsableSize(uma_memory_pool_handle_t hPool, void *ptr);
8793
///
8894
void umaPoolFree(uma_memory_pool_handle_t hPool, void *ptr);
8995

96+
///
97+
/// \brief Frees the memory space pointed by ptr if it belongs to UMA pool, does nothing otherwise
98+
/// \param ptr pointer to the allocated memory
99+
///
100+
void umaFree(void *ptr);
101+
90102
///
91103
/// \brief Retrieve string representation of the underlying pool specific
92104
/// result reported by the last API that returned
@@ -111,6 +123,12 @@ void umaPoolFree(uma_memory_pool_handle_t hPool, void *ptr);
111123
enum uma_result_t umaPoolGetLastResult(uma_memory_pool_handle_t hPool,
112124
const char **ppMessage);
113125

126+
///
127+
/// \brief Retrieve memory pool associated with a given ptr.
128+
/// \param ptr pointer to memory belonging to a memory pool
129+
/// \return handle to a memory pool that contains ptr or NULL if pointer does not belong to any UMA pool
130+
uma_memory_pool_handle_t umaPoolByPtr(const void *ptr);
131+
114132
#ifdef __cplusplus
115133
}
116134
#endif

source/common/unified_memory_allocation/include/uma/memory_pool_ops.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
extern "C" {
1616
#endif
1717

18-
/// This structure comprises function pointers used by corresponding umaPool*
18+
/// \brief This structure comprises function pointers used by corresponding umaPool*
1919
/// calls. Each memory pool implementation should initialize all function
2020
/// pointers.
2121
struct uma_memory_pool_ops_t {
@@ -25,11 +25,15 @@ struct uma_memory_pool_ops_t {
2525

2626
///
2727
/// \brief Intializes memory pool
28+
/// \param providers array of memory providers that will be used for coarse-grain allocations. Should contain at least one memory provider.
29+
/// \param numProvider number of elements in the providers array
2830
/// \param params pool-specific params
2931
/// \param pool returns pointer to the pool
3032
/// \return UMA_RESULT_SUCCESS on success or appropriate error code on
3133
/// failure
32-
enum uma_result_t (*initialize)(void *params, void **pool);
34+
enum uma_result_t (*initialize)(uma_memory_provider_handle_t *providers,
35+
size_t numProviders, void *params,
36+
void **pool);
3337

3438
///
3539
/// \brief Finalizes memory pool

source/common/unified_memory_allocation/include/uma/memory_provider.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void umaMemoryProviderDestroy(uma_memory_provider_handle_t hProvider);
4141
/// \param hProvider handle to the memory provider
4242
/// \param size number of bytes to allocate
4343
/// \param alignment alignment of the allocation
44-
/// \param ptr returns pointer to the allocated memory
44+
/// \param ptr will be updated with pointer to the allocated memory
4545
/// \return UMA_RESULT_SUCCESS on success or appropriate error code on failure
4646
///
4747
enum uma_result_t umaMemoryProviderAlloc(uma_memory_provider_handle_t hProvider,

source/common/unified_memory_allocation/src/memory_pool.c

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,43 +6,91 @@
66
*
77
*/
88

9+
#include "memory_tracker.h"
910
#include <uma/memory_pool.h>
11+
#include <uma/memory_pool_ops.h>
1012

1113
#include <assert.h>
1214
#include <stdlib.h>
1315

1416
struct uma_memory_pool_t {
15-
struct uma_memory_pool_ops_t ops;
1617
void *pool_priv;
18+
struct uma_memory_pool_ops_t ops;
19+
20+
// Holds array of memory providers. All providers are wrapped
21+
// by memory tracking providers (owned and released by UMA).
22+
uma_memory_provider_handle_t *providers;
23+
24+
size_t numProviders;
1725
};
1826

19-
enum uma_result_t umaPoolCreate(struct uma_memory_pool_ops_t *ops, void *params,
27+
static void
28+
destroyMemoryProviderWrappers(uma_memory_provider_handle_t *providers,
29+
size_t numProviders) {
30+
for (size_t i = 0; i < numProviders; i++) {
31+
umaMemoryProviderDestroy(providers[i]);
32+
}
33+
34+
free(providers);
35+
}
36+
37+
enum uma_result_t umaPoolCreate(struct uma_memory_pool_ops_t *ops,
38+
uma_memory_provider_handle_t *providers,
39+
size_t numProviders, void *params,
2040
uma_memory_pool_handle_t *hPool) {
41+
if (!numProviders || !providers) {
42+
return UMA_RESULT_ERROR_INVALID_ARGUMENT;
43+
}
44+
45+
enum uma_result_t ret = UMA_RESULT_SUCCESS;
2146
uma_memory_pool_handle_t pool = malloc(sizeof(struct uma_memory_pool_t));
2247
if (!pool) {
2348
return UMA_RESULT_ERROR_OUT_OF_HOST_MEMORY;
2449
}
2550

2651
assert(ops->version == UMA_VERSION_CURRENT);
2752

28-
pool->ops = *ops;
53+
pool->providers =
54+
calloc(numProviders, sizeof(uma_memory_provider_handle_t));
55+
if (!pool->providers) {
56+
ret = UMA_RESULT_ERROR_OUT_OF_HOST_MEMORY;
57+
goto err_providers_alloc;
58+
}
2959

30-
void *pool_priv;
31-
enum uma_result_t ret = ops->initialize(params, &pool_priv);
32-
if (ret != UMA_RESULT_SUCCESS) {
33-
free(pool);
34-
return ret;
60+
size_t providerInd = 0;
61+
pool->numProviders = numProviders;
62+
63+
// Wrap each provider with memory tracking provider.
64+
for (providerInd = 0; providerInd < numProviders; providerInd++) {
65+
ret = umaTrackingMemoryProviderCreate(providers[providerInd], pool,
66+
&pool->providers[providerInd]);
67+
if (ret != UMA_RESULT_SUCCESS) {
68+
goto err_providers_init;
69+
}
3570
}
3671

37-
pool->pool_priv = pool_priv;
72+
pool->ops = *ops;
73+
ret = ops->initialize(pool->providers, pool->numProviders, params,
74+
&pool->pool_priv);
75+
if (ret != UMA_RESULT_SUCCESS) {
76+
goto err_pool_init;
77+
}
3878

3979
*hPool = pool;
40-
4180
return UMA_RESULT_SUCCESS;
81+
82+
err_pool_init:
83+
err_providers_init:
84+
destroyMemoryProviderWrappers(pool->providers, providerInd);
85+
err_providers_alloc:
86+
free(pool);
87+
88+
return ret;
4289
}
4390

4491
void umaPoolDestroy(uma_memory_pool_handle_t hPool) {
4592
hPool->ops.finalize(hPool->pool_priv);
93+
destroyMemoryProviderWrappers(hPool->providers, hPool->numProviders);
4694
free(hPool);
4795
}
4896

@@ -71,7 +119,18 @@ void umaPoolFree(uma_memory_pool_handle_t hPool, void *ptr) {
71119
hPool->ops.free(hPool->pool_priv, ptr);
72120
}
73121

122+
void umaFree(void *ptr) {
123+
uma_memory_pool_handle_t hPool = umaPoolByPtr(ptr);
124+
if (hPool) {
125+
umaPoolFree(hPool, ptr);
126+
}
127+
}
128+
74129
enum uma_result_t umaPoolGetLastResult(uma_memory_pool_handle_t hPool,
75130
const char **ppMessage) {
76131
return hPool->ops.get_last_result(hPool->pool_priv, ppMessage);
77132
}
133+
134+
uma_memory_pool_handle_t umaPoolByPtr(const void *ptr) {
135+
return umaMemoryTrackerGetPool(umaMemoryTrackerGet(), ptr);
136+
}

0 commit comments

Comments
 (0)