@@ -37,68 +37,138 @@ struct umf_memory_tracker_t {
3737typedef 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 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 );
7197
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 );
73121 return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY ;
74122 }
75123
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 ;
77136}
78137
79138static umf_result_t umfMemoryTrackerRemove (umf_memory_tracker_handle_t hTracker ,
80139 const void * ptr ) {
81140 assert (ptr );
82141
142+ umf_result_t umf_result = UMF_RESULT_SUCCESS ;
143+
83144 // TODO: there is no support for removing partial ranges (or multiple entries
84145 // in a single remove call) yet.
85146 // Every umfMemoryTrackerAdd(..., ptr, ...) should have a corresponding
86147 // umfMemoryTrackerRemove call with the same ptr value.
87148
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 );
89151 if (!value ) {
90152 LOG_ERR ("pointer %p not found in the alloc_segments_map" , ptr );
91153 return UMF_RESULT_ERROR_UNKNOWN ;
92154 }
93155
94- tracker_alloc_info_t * v = value ;
95-
96156 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+ }
98168
99169 umf_ba_free (hTracker -> alloc_info_allocator , value );
100170
101- return UMF_RESULT_SUCCESS ;
171+ return umf_result ;
102172}
103173
104174umf_memory_pool_handle_t umfMemoryTrackerGetPool (const void * ptr ) {
0 commit comments