Skip to content

Commit 026fc8f

Browse files
committed
Add trackerShrinkEntry() and trackerGrowEntry()
Add trackerShrinkEntry() that shrinks (or removes) an entry in the tracker and returns the totalSize of the original entry. Add trackerGrowEntry() that grows (or adds) an entry in the tracker to its original size. Signed-off-by: Lukasz Dorau <[email protected]>
1 parent dd1348c commit 026fc8f

File tree

3 files changed

+147
-0
lines changed

3 files changed

+147
-0
lines changed

src/provider/provider_fixed_memory.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "coarse.h"
2222
#include "libumf.h"
2323
#include "memory_pool_internal.h"
24+
#include "provider_tracking.h"
2425
#include "utils_common.h"
2526
#include "utils_concurrency.h"
2627
#include "utils_log.h"
@@ -114,6 +115,15 @@ static umf_result_t fixed_initialize(void *params, void **provider) {
114115
LOG_ERR("cannot get the tracking provider of the pool %p", pool);
115116
return ret;
116117
}
118+
119+
ret = trackerShrinkEntry(trackingProvider, in_params->ptr,
120+
in_params->size, &ptr_orig_size);
121+
if (ret != UMF_RESULT_SUCCESS) {
122+
LOG_ERR(
123+
"cannot shrink the allocation %p in the tracker to size %zu",
124+
in_params->ptr, in_params->size);
125+
return ret;
126+
}
117127
}
118128

119129
fixed_memory_provider_t *fixed_provider =
@@ -173,6 +183,20 @@ static umf_result_t fixed_initialize(void *params, void **provider) {
173183
static void fixed_finalize(void *provider) {
174184
fixed_memory_provider_t *fixed_provider = provider;
175185
coarse_delete(fixed_provider->coarse);
186+
187+
if (fixed_provider->trackingProvider &&
188+
(fixed_provider->ptr_orig_size >= fixed_provider->size)) {
189+
umf_result_t ret = trackerGrowEntry(
190+
fixed_provider->trackingProvider, fixed_provider->base,
191+
fixed_provider->size, fixed_provider->ptr_orig_size);
192+
if (ret != UMF_RESULT_SUCCESS) {
193+
LOG_ERR("cannot grow the allocation %p in the tracker (from size "
194+
"%zu to size %zu)",
195+
fixed_provider->base, fixed_provider->size,
196+
fixed_provider->ptr_orig_size);
197+
}
198+
}
199+
176200
umf_ba_global_free(fixed_provider);
177201
}
178202

src/provider/provider_tracking.c

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,61 @@ static umf_result_t trackingAllocationSplit(void *hProvider, void *ptr,
267267
return ret;
268268
}
269269

270+
// shrink (or remove) an entry in the tracker and return the totalSize of the original entry
271+
umf_result_t trackerShrinkEntry(void *hProvider, void *ptr, size_t shrinkSize,
272+
size_t *totalSize) {
273+
umf_result_t ret = UMF_RESULT_ERROR_UNKNOWN;
274+
umf_tracking_memory_provider_t *provider =
275+
(umf_tracking_memory_provider_t *)hProvider;
276+
277+
int r = utils_mutex_lock(&provider->hTracker->splitMergeMutex);
278+
if (r) {
279+
return UMF_RESULT_ERROR_UNKNOWN;
280+
}
281+
282+
tracker_alloc_info_t *value = (tracker_alloc_info_t *)critnib_get(
283+
provider->hTracker->alloc_segments_map, (uintptr_t)ptr);
284+
if (!value) {
285+
LOG_ERR("region for shrinking is not found in the tracker");
286+
ret = UMF_RESULT_ERROR_INVALID_ARGUMENT;
287+
goto err;
288+
}
289+
if (shrinkSize > value->size) {
290+
LOG_ERR("requested size %zu to shrink exceeds the tracked size %zu",
291+
shrinkSize, value->size);
292+
ret = UMF_RESULT_ERROR_INVALID_ARGUMENT;
293+
goto err;
294+
}
295+
296+
if (shrinkSize < value->size) {
297+
void *highPtr = (void *)(((uintptr_t)ptr) + shrinkSize);
298+
size_t secondSize = value->size - shrinkSize;
299+
ret = umfMemoryTrackerAdd(provider->hTracker, provider->pool, highPtr,
300+
secondSize);
301+
if (ret != UMF_RESULT_SUCCESS) {
302+
LOG_ERR("failed to add the new shrunk region to the tracker, ptr = "
303+
"%p, size = %zu, ret = %d",
304+
highPtr, secondSize, ret);
305+
goto err;
306+
}
307+
}
308+
309+
*totalSize = value->size;
310+
311+
void *erasedValue =
312+
critnib_remove(provider->hTracker->alloc_segments_map, (uintptr_t)ptr);
313+
assert(erasedValue == value);
314+
umf_ba_free(provider->hTracker->alloc_info_allocator, erasedValue);
315+
316+
utils_mutex_unlock(&provider->hTracker->splitMergeMutex);
317+
318+
return UMF_RESULT_SUCCESS;
319+
320+
err:
321+
utils_mutex_unlock(&provider->hTracker->splitMergeMutex);
322+
return ret;
323+
}
324+
270325
static umf_result_t trackingAllocationMerge(void *hProvider, void *lowPtr,
271326
void *highPtr, size_t totalSize) {
272327
umf_result_t ret = UMF_RESULT_ERROR_UNKNOWN;
@@ -353,6 +408,68 @@ static umf_result_t trackingAllocationMerge(void *hProvider, void *lowPtr,
353408
return ret;
354409
}
355410

411+
// grow (or add) an entry in the tracker to its original size
412+
umf_result_t trackerGrowEntry(void *hProvider, void *ptr, size_t growSize,
413+
size_t origSize) {
414+
umf_result_t ret = UMF_RESULT_ERROR_UNKNOWN;
415+
umf_tracking_memory_provider_t *provider =
416+
(umf_tracking_memory_provider_t *)hProvider;
417+
418+
if (growSize > origSize) {
419+
LOG_ERR("Invalid grow size %zu (larger than the original size %zu)",
420+
growSize, origSize);
421+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
422+
}
423+
424+
int r = utils_mutex_lock(&provider->hTracker->splitMergeMutex);
425+
if (r) {
426+
return UMF_RESULT_ERROR_UNKNOWN;
427+
}
428+
429+
void *highPtr = (void *)(((uintptr_t)ptr) + growSize);
430+
tracker_alloc_info_t *highValue = NULL;
431+
432+
if (growSize < origSize) {
433+
highValue = (tracker_alloc_info_t *)critnib_get(
434+
provider->hTracker->alloc_segments_map, (uintptr_t)highPtr);
435+
if (!highValue) {
436+
LOG_ERR("cannot find the tracker entry to grow %p", highPtr);
437+
ret = UMF_RESULT_ERROR_INVALID_ARGUMENT;
438+
goto err;
439+
}
440+
if (growSize + highValue->size != origSize) {
441+
LOG_ERR("Grow size plus the current size does not equal the "
442+
"original size");
443+
ret = UMF_RESULT_ERROR_INVALID_ARGUMENT;
444+
goto err;
445+
}
446+
}
447+
448+
ret =
449+
umfMemoryTrackerAdd(provider->hTracker, provider->pool, ptr, origSize);
450+
if (ret != UMF_RESULT_SUCCESS) {
451+
LOG_ERR("failed to add the new grown region to the tracker, ptr = %p, "
452+
"size = %zu, ret = %d",
453+
ptr, origSize, ret);
454+
goto err;
455+
}
456+
457+
if (growSize < origSize) {
458+
void *erasedhighValue = critnib_remove(
459+
provider->hTracker->alloc_segments_map, (uintptr_t)highPtr);
460+
assert(erasedhighValue == highValue);
461+
umf_ba_free(provider->hTracker->alloc_info_allocator, erasedhighValue);
462+
}
463+
464+
utils_mutex_unlock(&provider->hTracker->splitMergeMutex);
465+
466+
return UMF_RESULT_SUCCESS;
467+
468+
err:
469+
utils_mutex_unlock(&provider->hTracker->splitMergeMutex);
470+
return ret;
471+
}
472+
356473
static umf_result_t trackingFree(void *hProvider, void *ptr, size_t size) {
357474
umf_result_t ret;
358475
umf_result_t ret_remove = UMF_RESULT_ERROR_UNKNOWN;

src/provider/provider_tracking.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ void umfTrackingMemoryProviderGetUpstreamProvider(
5555
umf_memory_provider_handle_t hTrackingProvider,
5656
umf_memory_provider_handle_t *hUpstream);
5757

58+
umf_result_t trackerShrinkEntry(void *hProvider, void *ptr, size_t shrinkSize,
59+
size_t *totalSize);
60+
61+
umf_result_t trackerGrowEntry(void *hProvider, void *ptr, size_t growSize,
62+
size_t origSize);
63+
5864
#ifdef __cplusplus
5965
}
6066
#endif

0 commit comments

Comments
 (0)