Skip to content

Commit 0f7fa15

Browse files
committed
Stack the same values in the tracker
Signed-off-by: Lukasz Dorau <[email protected]>
1 parent 7e68cc8 commit 0f7fa15

File tree

1 file changed

+104
-27
lines changed

1 file changed

+104
-27
lines changed

src/provider/provider_tracking.c

Lines changed: 104 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -37,68 +37,143 @@ struct umf_memory_tracker_t {
3737
typedef struct tracker_alloc_info_t {
3838
umf_memory_pool_handle_t pool;
3939
size_t size;
40+
// list of previous entries with the same address (LIFO)
41+
struct tracker_alloc_info_t *prev;
4042
} tracker_alloc_info_t;
4143

42-
static umf_result_t umfMemoryTrackerAdd(umf_memory_tracker_handle_t hTracker,
43-
umf_memory_pool_handle_t pool,
44-
const void *ptr, size_t size) {
44+
static umf_result_t
45+
umfMemoryTrackerAddValue(umf_memory_tracker_handle_t hTracker, const void *ptr,
46+
tracker_alloc_info_t *new_value) {
4547
assert(ptr);
48+
assert(new_value);
4649

47-
tracker_alloc_info_t *value = umf_ba_alloc(hTracker->alloc_info_allocator);
48-
if (value == NULL) {
49-
LOG_ERR("failed to allocate tracker value, ptr=%p, size=%zu", ptr,
50-
size);
51-
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
52-
}
53-
54-
value->pool = pool;
55-
value->size = size;
56-
57-
int ret =
58-
critnib_insert(hTracker->alloc_segments_map, (uintptr_t)ptr, value, 0);
50+
umf_result_t umf_result = UMF_RESULT_ERROR_UNKNOWN;
5951

52+
int ret = critnib_insert(hTracker->alloc_segments_map, (uintptr_t)ptr,
53+
new_value, 0);
6054
if (ret == 0) {
6155
LOG_DEBUG(
62-
"memory region is added, tracker=%p, ptr=%p, pool=%p, size=%zu",
63-
(void *)hTracker, ptr, (void *)pool, size);
56+
"memory region added to the tracker=%p, ptr=%p, pool=%p, size=%zu",
57+
(void *)hTracker, ptr, (void *)new_value->pool, new_value->size);
6458
return UMF_RESULT_SUCCESS;
6559
}
6660

67-
LOG_ERR("failed to insert tracker value, ret=%d, ptr=%p, pool=%p, size=%zu",
68-
ret, ptr, (void *)pool, size);
61+
// failed to insert to the tracker a new value
6962

70-
umf_ba_free(hTracker->alloc_info_allocator, value);
63+
if (ret != EEXIST) {
64+
if (ret == ENOMEM) {
65+
umf_result = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
66+
}
67+
goto err_message;
68+
}
69+
70+
// there already is an entry with the same address in the tracker
71+
72+
ret = utils_mutex_lock(&hTracker->splitMergeMutex);
73+
if (ret) {
74+
goto err_message;
75+
}
76+
77+
tracker_alloc_info_t *prev_value = (tracker_alloc_info_t *)critnib_get(
78+
hTracker->alloc_segments_map, (uintptr_t)ptr);
79+
if (!prev_value) {
80+
LOG_ERR("the previous entry not found in the tracker");
81+
goto err_unlock;
82+
}
83+
if (new_value->pool == prev_value->pool) {
84+
LOG_ERR("cannot add the next entry with the same address for the same "
85+
"pool");
86+
goto err_unlock;
87+
}
88+
89+
new_value->prev = prev_value;
90+
91+
ret = critnib_insert(hTracker->alloc_segments_map, (uintptr_t)ptr,
92+
new_value, 1); // update existing entry
93+
if (ret) {
94+
goto err_unlock;
95+
}
96+
97+
utils_mutex_unlock(&hTracker->splitMergeMutex);
98+
99+
LOG_DEBUG(
100+
"memory region added to the tracker=%p, ptr=%p, pool=%p, size=%zu",
101+
(void *)hTracker, ptr, (void *)new_value->pool, new_value->size);
71102

72-
if (ret == ENOMEM) {
103+
return UMF_RESULT_SUCCESS;
104+
105+
err_unlock:
106+
utils_mutex_unlock(&hTracker->splitMergeMutex);
107+
108+
err_message:
109+
LOG_ERR("failed to insert a new value to the tracker, ret=%d, ptr=%p, "
110+
"pool=%p, size=%zu",
111+
ret, ptr, (void *)new_value->pool, new_value->size);
112+
113+
return umf_result;
114+
}
115+
116+
static umf_result_t umfMemoryTrackerAdd(umf_memory_tracker_handle_t hTracker,
117+
umf_memory_pool_handle_t pool,
118+
const void *ptr, size_t size) {
119+
assert(ptr);
120+
121+
tracker_alloc_info_t *new_value =
122+
umf_ba_alloc(hTracker->alloc_info_allocator);
123+
if (new_value == NULL) {
124+
LOG_ERR("failed to allocate a tracker value, ptr=%p, size=%zu", ptr,
125+
size);
73126
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
74127
}
75128

76-
return UMF_RESULT_ERROR_UNKNOWN;
129+
new_value->pool = pool;
130+
new_value->size = size;
131+
new_value->prev = NULL;
132+
133+
umf_result_t umf_result =
134+
umfMemoryTrackerAddValue(hTracker, ptr, new_value);
135+
if (umf_result != UMF_RESULT_SUCCESS) {
136+
umf_ba_free(hTracker->alloc_info_allocator, new_value);
137+
return umf_result;
138+
}
139+
140+
return UMF_RESULT_SUCCESS;
77141
}
78142

79143
static umf_result_t umfMemoryTrackerRemove(umf_memory_tracker_handle_t hTracker,
80144
const void *ptr) {
81145
assert(ptr);
82146

147+
umf_result_t umf_result = UMF_RESULT_SUCCESS;
148+
83149
// TODO: there is no support for removing partial ranges (or multiple entries
84150
// in a single remove call) yet.
85151
// Every umfMemoryTrackerAdd(..., ptr, ...) should have a corresponding
86152
// umfMemoryTrackerRemove call with the same ptr value.
87153

88-
void *value = critnib_remove(hTracker->alloc_segments_map, (uintptr_t)ptr);
154+
tracker_alloc_info_t *value =
155+
critnib_remove(hTracker->alloc_segments_map, (uintptr_t)ptr);
89156
if (!value) {
90157
LOG_ERR("pointer %p not found in the alloc_segments_map", ptr);
91158
return UMF_RESULT_ERROR_UNKNOWN;
92159
}
93160

94-
tracker_alloc_info_t *v = value;
95-
96161
LOG_DEBUG("memory region removed: tracker=%p, ptr=%p, size=%zu",
97-
(void *)hTracker, ptr, v->size);
162+
(void *)hTracker, ptr, value->size);
163+
164+
if (value->prev) {
165+
tracker_alloc_info_t *prev_value = value->prev;
166+
umf_result = umfMemoryTrackerAddValue(hTracker, ptr, prev_value);
167+
if (umf_result != UMF_RESULT_SUCCESS) {
168+
LOG_ERR("failed to add the previous entry to the tracker, ptr = "
169+
"%p, size = %zu, umf_result = %d",
170+
ptr, prev_value->size, umf_result);
171+
}
172+
}
98173

99174
umf_ba_free(hTracker->alloc_info_allocator, value);
100175

101-
return UMF_RESULT_SUCCESS;
176+
return umf_result;
102177
}
103178

104179
umf_memory_pool_handle_t umfMemoryTrackerGetPool(const void *ptr) {
@@ -247,6 +322,7 @@ static umf_result_t trackingAllocationSplit(void *hProvider, void *ptr,
247322
goto err;
248323
}
249324

325+
splitValue->prev = value->prev;
250326
int cret =
251327
critnib_insert(provider->hTracker->alloc_segments_map, (uintptr_t)ptr,
252328
(void *)splitValue, 1 /* update */);
@@ -322,6 +398,7 @@ static umf_result_t trackingAllocationMerge(void *hProvider, void *lowPtr,
322398

323399
// We'll have a duplicate entry for the range [highPtr, highValue->size] but this is fine,
324400
// the value is the same anyway and we forbid removing that range concurrently
401+
mergedValue->prev = lowValue->prev;
325402
int cret =
326403
critnib_insert(provider->hTracker->alloc_segments_map,
327404
(uintptr_t)lowPtr, (void *)mergedValue, 1 /* update */);

0 commit comments

Comments
 (0)