Skip to content

Commit

Permalink
Stack 8 trackers
Browse files Browse the repository at this point in the history
Signed-off-by: Lukasz Dorau <[email protected]>
  • Loading branch information
ldorau committed Feb 26, 2025
1 parent 4141a2e commit eda9986
Showing 1 changed file with 91 additions and 22 deletions.
113 changes: 91 additions & 22 deletions src/provider/provider_tracking.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,78 @@
*
*/

#include "provider_tracking.h"
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <umf/memory_pool.h>
#include <umf/memory_provider.h>
#include <umf/memory_provider_ops.h>

#include "base_alloc_global.h"
#include "critnib.h"
#include "ipc_cache.h"
#include "ipc_internal.h"
#include "provider_tracking.h"
#include "utils_common.h"
#include "utils_concurrency.h"
#include "utils_log.h"

#include <umf/memory_pool.h>
#include <umf/memory_provider.h>
#include <umf/memory_provider_ops.h>

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEVELS_OF_TRACKERS 8

uint64_t IPC_HANDLE_ID = 0;

struct umf_memory_tracker_t {
umf_ba_pool_t *alloc_info_allocator;
critnib *alloc_segments_map;
critnib *alloc_segments_map[MAX_LEVELS_OF_TRACKERS];
utils_mutex_t splitMergeMutex;
};

typedef struct tracker_alloc_info_t {
umf_memory_pool_handle_t pool;
size_t size;
size_t n_overlapped;
} tracker_alloc_info_t;

static umf_result_t umfMemoryTrackerAdd(umf_memory_tracker_handle_t hTracker,
umf_memory_pool_handle_t pool,
const void *ptr, size_t size) {
assert(ptr);

tracker_alloc_info_t *prev_value = NULL;
tracker_alloc_info_t *rvalue = NULL;
uintptr_t prev_key = 0;
uintptr_t rkey = 0;
int level = 0;
int found = 0;

do {
found =
critnib_find(hTracker->alloc_segments_map[level], (uintptr_t)ptr,
FIND_LE, (void *)&rkey, (void **)&rvalue);
if (found && (uintptr_t)ptr < rkey + rvalue->size) {
if (level == MAX_LEVELS_OF_TRACKERS - 1) {
LOG_ERR("tracker level is too high, ptr=%p, size=%zu", ptr,
size);
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}
prev_key = rkey;
prev_value = rvalue;
level++;
}
} while (found && (uintptr_t)ptr < rkey + rvalue->size);

if (prev_value && ((uintptr_t)ptr + size >= prev_key + prev_value->size)) {
LOG_ERR(
"cannot insert to the tracker value (ptr=%p, size=%zu, pool=%p) "
"that exceeds the parent value (ptr=%p, size=%zu, pool=%p)",
ptr, size, (void *)pool, (void *)prev_key, prev_value->size,
(void *)prev_value->pool);
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}

tracker_alloc_info_t *value = umf_ba_alloc(hTracker->alloc_info_allocator);
if (value == NULL) {
LOG_ERR("failed to allocate tracker value, ptr=%p, size=%zu", ptr,
Expand All @@ -53,11 +88,15 @@ static umf_result_t umfMemoryTrackerAdd(umf_memory_tracker_handle_t hTracker,

value->pool = pool;
value->size = size;
value->n_overlapped = 0;

int ret =
critnib_insert(hTracker->alloc_segments_map, (uintptr_t)ptr, value, 0);

int ret = critnib_insert(hTracker->alloc_segments_map[level],
(uintptr_t)ptr, value, 0);
if (ret == 0) {
if (prev_value) {
prev_value->n_overlapped++;
}

LOG_DEBUG(
"memory region is added, tracker=%p, ptr=%p, pool=%p, size=%zu",
(void *)hTracker, ptr, (void *)pool, size);
Expand Down Expand Up @@ -85,16 +124,32 @@ static umf_result_t umfMemoryTrackerRemove(umf_memory_tracker_handle_t hTracker,
// Every umfMemoryTrackerAdd(..., ptr, ...) should have a corresponding
// umfMemoryTrackerRemove call with the same ptr value.

void *value = critnib_remove(hTracker->alloc_segments_map, (uintptr_t)ptr);
int level = 0;
tracker_alloc_info_t *value;
tracker_alloc_info_t *prev_value = NULL;
do {
value = (tracker_alloc_info_t *)critnib_get(
hTracker->alloc_segments_map[level], (uintptr_t)ptr);
if (value && value->n_overlapped) {
prev_value = value;
level++;
}
} while (value && value->n_overlapped);

if (!value) {
LOG_ERR("pointer %p not found in the alloc_segments_map", ptr);
return UMF_RESULT_ERROR_UNKNOWN;
}

tracker_alloc_info_t *v = value;
value = critnib_remove(hTracker->alloc_segments_map[level], (uintptr_t)ptr);
assert(value);

if (prev_value) {
prev_value->n_overlapped--;
}

LOG_DEBUG("memory region removed: tracker=%p, ptr=%p, size=%zu",
(void *)hTracker, ptr, v->size);
(void *)hTracker, ptr, value->size);

umf_ba_free(hTracker->alloc_info_allocator, value);

Expand Down Expand Up @@ -124,7 +179,7 @@ umf_result_t umfMemoryTrackerGetAllocInfo(const void *ptr,
return UMF_RESULT_ERROR_NOT_SUPPORTED;
}

if (TRACKER->alloc_segments_map == NULL) {
if (TRACKER->alloc_segments_map[0] == NULL) {
LOG_ERR("tracker's alloc_segments_map does not exist");
return UMF_RESULT_ERROR_NOT_SUPPORTED;
}
Expand Down Expand Up @@ -811,6 +866,8 @@ umf_memory_tracker_handle_t umfMemoryTrackerCreate(void) {
return NULL;
}

memset(handle, 0, sizeof(struct umf_memory_tracker_t));

umf_ba_pool_t *alloc_info_allocator =
umf_ba_create(sizeof(struct tracker_alloc_info_t));
if (!alloc_info_allocator) {
Expand All @@ -824,9 +881,12 @@ umf_memory_tracker_handle_t umfMemoryTrackerCreate(void) {
goto err_destroy_alloc_info_allocator;
}

handle->alloc_segments_map = critnib_new();
if (!handle->alloc_segments_map) {
goto err_destroy_mutex;
int i;
for (i = 0; i < MAX_LEVELS_OF_TRACKERS; i++) {
handle->alloc_segments_map[i] = critnib_new();
if (!handle->alloc_segments_map[i]) {
goto err_destroy_mutex;
}
}

LOG_DEBUG("tracker created, handle=%p, alloc_segments_map=%p",
Expand All @@ -835,6 +895,11 @@ umf_memory_tracker_handle_t umfMemoryTrackerCreate(void) {
return handle;

err_destroy_mutex:
for (int j = i; i >= 0; j--) {
if (handle->alloc_segments_map[j]) {
critnib_delete(handle->alloc_segments_map[j]);
}
}
utils_mutex_destroy_not_free(&handle->splitMergeMutex);
err_destroy_alloc_info_allocator:
umf_ba_destroy(alloc_info_allocator);
Expand Down Expand Up @@ -862,7 +927,11 @@ void umfMemoryTrackerDestroy(umf_memory_tracker_handle_t handle) {
// We have to zero all inner pointers,
// because the tracker handle can be copied
// and used in many places.
critnib_delete(handle->alloc_segments_map);
for (int i = 0; i < MAX_LEVELS_OF_TRACKERS; i++) {
if (handle->alloc_segments_map[i]) {
critnib_delete(handle->alloc_segments_map[i]);
}
}
handle->alloc_segments_map = NULL;
utils_mutex_destroy_not_free(&handle->splitMergeMutex);
umf_ba_destroy(handle->alloc_info_allocator);
Expand Down

0 comments on commit eda9986

Please sign in to comment.