|
17 | 17 | #include <assert.h>
|
18 | 18 | #include <stdlib.h>
|
19 | 19 |
|
| 20 | +#include "base_alloc_global.h" |
| 21 | +#include "memory_pool_internal.h" |
| 22 | +#include "memory_provider_internal.h" |
| 23 | +#include "provider_tracking.h" |
| 24 | + |
| 25 | +static umf_result_t umfPoolCreateInternal(const umf_memory_pool_ops_t *ops, |
| 26 | + umf_memory_provider_handle_t provider, |
| 27 | + void *params, |
| 28 | + umf_pool_create_flags_t flags, |
| 29 | + umf_memory_pool_handle_t *hPool) { |
| 30 | + if (!ops || !provider || !hPool) { |
| 31 | + return UMF_RESULT_ERROR_INVALID_ARGUMENT; |
| 32 | + } |
| 33 | + |
| 34 | + umf_result_t ret = UMF_RESULT_SUCCESS; |
| 35 | + umf_memory_pool_handle_t pool = |
| 36 | + umf_ba_global_alloc(sizeof(umf_memory_pool_t)); |
| 37 | + if (!pool) { |
| 38 | + return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY; |
| 39 | + } |
| 40 | + |
| 41 | + assert(ops->version == UMF_VERSION_CURRENT); |
| 42 | + |
| 43 | + if (!(flags & UMF_POOL_CREATE_FLAG_DISABLE_TRACKING)) { |
| 44 | + // wrap provider with memory tracking provider |
| 45 | + ret = umfTrackingMemoryProviderCreate(provider, pool, &pool->provider); |
| 46 | + if (ret != UMF_RESULT_SUCCESS) { |
| 47 | + goto err_provider_create; |
| 48 | + } |
| 49 | + } else { |
| 50 | + pool->provider = provider; |
| 51 | + } |
| 52 | + |
| 53 | + pool->flags = flags; |
| 54 | + pool->ops = *ops; |
| 55 | + |
| 56 | + ret = ops->initialize(pool->provider, params, &pool->pool_priv); |
| 57 | + if (ret != UMF_RESULT_SUCCESS) { |
| 58 | + goto err_pool_init; |
| 59 | + } |
| 60 | + |
| 61 | + *hPool = pool; |
| 62 | + return UMF_RESULT_SUCCESS; |
| 63 | + |
| 64 | +err_pool_init: |
| 65 | + if (!(flags & UMF_POOL_CREATE_FLAG_DISABLE_TRACKING)) { |
| 66 | + umfMemoryProviderDestroy(pool->provider); |
| 67 | + } |
| 68 | +err_provider_create: |
| 69 | + umf_ba_global_free(pool); |
| 70 | + return ret; |
| 71 | +} |
| 72 | + |
| 73 | +void umfPoolDestroy(umf_memory_pool_handle_t hPool) { |
| 74 | + hPool->ops.finalize(hPool->pool_priv); |
| 75 | + if (hPool->flags & UMF_POOL_CREATE_FLAG_OWN_PROVIDER) { |
| 76 | + // Destroy associated memory provider. |
| 77 | + umf_memory_provider_handle_t hProvider = NULL; |
| 78 | + umfPoolGetMemoryProvider(hPool, &hProvider); |
| 79 | + umfMemoryProviderDestroy(hProvider); |
| 80 | + } |
| 81 | + |
| 82 | + if (!(hPool->flags & UMF_POOL_CREATE_FLAG_DISABLE_TRACKING)) { |
| 83 | + // Destroy tracking provider. |
| 84 | + umfMemoryProviderDestroy(hPool->provider); |
| 85 | + } |
| 86 | + // TODO: this free keeps memory in base allocator, so it can lead to OOM in some scenarios (it should be optimized) |
| 87 | + umf_ba_global_free(hPool); |
| 88 | +} |
| 89 | + |
| 90 | +umf_result_t umfFree(void *ptr) { |
| 91 | +#ifndef UMF_ENABLE_POOL_TRACKING |
| 92 | + return UMF_RESULT_ERROR_NOT_SUPPORTED; |
| 93 | +#endif |
| 94 | + |
| 95 | + umf_memory_pool_handle_t hPool = umfPoolByPtr(ptr); |
| 96 | + if (hPool) { |
| 97 | + return umfPoolFree(hPool, ptr); |
| 98 | + } |
| 99 | + return UMF_RESULT_SUCCESS; |
| 100 | +} |
| 101 | + |
| 102 | +umf_memory_pool_handle_t umfPoolByPtr(const void *ptr) { |
| 103 | + return umfMemoryTrackerGetPool(ptr); |
| 104 | +} |
| 105 | + |
| 106 | +umf_result_t umfPoolGetMemoryProvider(umf_memory_pool_handle_t hPool, |
| 107 | + umf_memory_provider_handle_t *hProvider) { |
| 108 | + if (!hProvider) { |
| 109 | + return UMF_RESULT_ERROR_INVALID_ARGUMENT; |
| 110 | + } |
| 111 | + |
| 112 | + if (hPool->flags & UMF_POOL_CREATE_FLAG_DISABLE_TRACKING) { |
| 113 | + *hProvider = hPool->provider; |
| 114 | + } else { |
| 115 | + umfTrackingMemoryProviderGetUpstreamProvider( |
| 116 | + umfMemoryProviderGetPriv(hPool->provider), hProvider); |
| 117 | + } |
| 118 | + |
| 119 | + return UMF_RESULT_SUCCESS; |
| 120 | +} |
| 121 | + |
20 | 122 | umf_result_t umfPoolCreate(const umf_memory_pool_ops_t *ops,
|
21 | 123 | umf_memory_provider_handle_t provider, void *params,
|
22 | 124 | umf_pool_create_flags_t flags,
|
23 | 125 | umf_memory_pool_handle_t *hPool) {
|
24 | 126 | libumfInit();
|
25 |
| - umf_result_t ret = umfPoolCreateInternal(ops, provider, params, hPool); |
| 127 | + |
| 128 | +#ifndef UMF_ENABLE_POOL_TRACKING |
| 129 | + // if tracking is not enabled during compilation, disable it for each pool here as well |
| 130 | + flags |= UMF_POOL_CREATE_FLAG_DISABLE_TRACKING; |
| 131 | +#endif |
| 132 | + |
| 133 | + umf_result_t ret = |
| 134 | + umfPoolCreateInternal(ops, provider, params, flags, hPool); |
26 | 135 | if (ret != UMF_RESULT_SUCCESS) {
|
27 | 136 | return ret;
|
28 | 137 | }
|
29 | 138 | assert(*hPool != NULL);
|
30 |
| - (*hPool)->own_provider = (flags & UMF_POOL_CREATE_FLAG_OWN_PROVIDER); |
31 | 139 |
|
32 | 140 | return UMF_RESULT_SUCCESS;
|
33 | 141 | }
|
|
0 commit comments