@@ -37,68 +37,138 @@ struct umf_memory_tracker_t {
37
37
typedef struct tracker_alloc_info_t {
38
38
umf_memory_pool_handle_t pool ;
39
39
size_t size ;
40
+ // list of previous entries with the same address (LIFO)
41
+ struct tracker_alloc_info_t * prev ;
40
42
} tracker_alloc_info_t ;
41
43
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 ) {
45
47
assert (ptr );
48
+ assert (new_value );
46
49
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 ;
59
51
52
+ int ret = critnib_insert (hTracker -> alloc_segments_map , (uintptr_t )ptr ,
53
+ new_value , 0 );
60
54
if (ret == 0 ) {
61
55
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 );
64
58
return UMF_RESULT_SUCCESS ;
65
59
}
66
60
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
69
62
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 region not found in the tracker" );
81
+ goto err_unlock ;
82
+ }
83
+
84
+ new_value -> prev = prev_value ;
85
+
86
+ ret = critnib_insert (hTracker -> alloc_segments_map , (uintptr_t )ptr ,
87
+ new_value , 1 ); // update existing entry
88
+ if (ret ) {
89
+ goto err_unlock ;
90
+ }
91
+
92
+ utils_mutex_unlock (& hTracker -> splitMergeMutex );
93
+
94
+ LOG_DEBUG (
95
+ "memory region added to the tracker=%p, ptr=%p, pool=%p, size=%zu" ,
96
+ (void * )hTracker , ptr , (void * )new_value -> pool , new_value -> size );
71
97
72
- if (ret == ENOMEM ) {
98
+ return UMF_RESULT_SUCCESS ;
99
+
100
+ err_unlock :
101
+ utils_mutex_unlock (& hTracker -> splitMergeMutex );
102
+
103
+ err_message :
104
+ LOG_ERR ("failed to insert a new value to the tracker, ret=%d, ptr=%p, "
105
+ "pool=%p, size=%zu" ,
106
+ ret , ptr , (void * )new_value -> pool , new_value -> size );
107
+
108
+ return umf_result ;
109
+ }
110
+
111
+ static umf_result_t umfMemoryTrackerAdd (umf_memory_tracker_handle_t hTracker ,
112
+ umf_memory_pool_handle_t pool ,
113
+ const void * ptr , size_t size ) {
114
+ assert (ptr );
115
+
116
+ tracker_alloc_info_t * new_value =
117
+ umf_ba_alloc (hTracker -> alloc_info_allocator );
118
+ if (new_value == NULL ) {
119
+ LOG_ERR ("failed to allocate a tracker value, ptr=%p, size=%zu" , ptr ,
120
+ size );
73
121
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY ;
74
122
}
75
123
76
- return UMF_RESULT_ERROR_UNKNOWN ;
124
+ new_value -> pool = pool ;
125
+ new_value -> size = size ;
126
+ new_value -> prev = NULL ;
127
+
128
+ umf_result_t umf_result =
129
+ umfMemoryTrackerAddValue (hTracker , ptr , new_value );
130
+ if (umf_result != UMF_RESULT_SUCCESS ) {
131
+ umf_ba_free (hTracker -> alloc_info_allocator , new_value );
132
+ return umf_result ;
133
+ }
134
+
135
+ return UMF_RESULT_SUCCESS ;
77
136
}
78
137
79
138
static umf_result_t umfMemoryTrackerRemove (umf_memory_tracker_handle_t hTracker ,
80
139
const void * ptr ) {
81
140
assert (ptr );
82
141
142
+ umf_result_t umf_result = UMF_RESULT_SUCCESS ;
143
+
83
144
// TODO: there is no support for removing partial ranges (or multiple entries
84
145
// in a single remove call) yet.
85
146
// Every umfMemoryTrackerAdd(..., ptr, ...) should have a corresponding
86
147
// umfMemoryTrackerRemove call with the same ptr value.
87
148
88
- void * value = critnib_remove (hTracker -> alloc_segments_map , (uintptr_t )ptr );
149
+ tracker_alloc_info_t * value =
150
+ critnib_remove (hTracker -> alloc_segments_map , (uintptr_t )ptr );
89
151
if (!value ) {
90
152
LOG_ERR ("pointer %p not found in the alloc_segments_map" , ptr );
91
153
return UMF_RESULT_ERROR_UNKNOWN ;
92
154
}
93
155
94
- tracker_alloc_info_t * v = value ;
95
-
96
156
LOG_DEBUG ("memory region removed: tracker=%p, ptr=%p, size=%zu" ,
97
- (void * )hTracker , ptr , v -> size );
157
+ (void * )hTracker , ptr , value -> size );
158
+
159
+ if (value -> prev ) {
160
+ tracker_alloc_info_t * prev_value = value -> prev ;
161
+ umf_result = umfMemoryTrackerAddValue (hTracker , ptr , prev_value );
162
+ if (umf_result != UMF_RESULT_SUCCESS ) {
163
+ LOG_ERR ("failed to add the previous region to the tracker, ptr = "
164
+ "%p, size = %zu, umf_result = %d" ,
165
+ ptr , prev_value -> size , umf_result );
166
+ }
167
+ }
98
168
99
169
umf_ba_free (hTracker -> alloc_info_allocator , value );
100
170
101
- return UMF_RESULT_SUCCESS ;
171
+ return umf_result ;
102
172
}
103
173
104
174
umf_memory_pool_handle_t umfMemoryTrackerGetPool (const void * ptr ) {
0 commit comments