@@ -267,6 +267,58 @@ 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_SUCCESS ;
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+ err :
317+ utils_mutex_unlock (& provider -> hTracker -> splitMergeMutex );
318+
319+ return ret ;
320+ }
321+
270322static umf_result_t trackingAllocationMerge (void * hProvider , void * lowPtr ,
271323 void * highPtr , size_t totalSize ) {
272324 umf_result_t ret = UMF_RESULT_ERROR_UNKNOWN ;
@@ -353,6 +405,65 @@ static umf_result_t trackingAllocationMerge(void *hProvider, void *lowPtr,
353405 return ret ;
354406}
355407
408+ // grow (or add) an entry in the tracker to its original size
409+ umf_result_t trackerGrowEntry (void * hProvider , void * ptr , size_t growSize ,
410+ size_t origSize ) {
411+ umf_result_t ret = UMF_RESULT_SUCCESS ;
412+ umf_tracking_memory_provider_t * provider =
413+ (umf_tracking_memory_provider_t * )hProvider ;
414+
415+ if (growSize > origSize ) {
416+ LOG_ERR ("Invalid grow size %zu (larger than the original size %zu)" ,
417+ growSize , origSize );
418+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
419+ }
420+
421+ int r = utils_mutex_lock (& provider -> hTracker -> splitMergeMutex );
422+ if (r ) {
423+ return UMF_RESULT_ERROR_UNKNOWN ;
424+ }
425+
426+ void * highPtr = (void * )(((uintptr_t )ptr ) + growSize );
427+ tracker_alloc_info_t * highValue = NULL ;
428+
429+ if (growSize < origSize ) {
430+ highValue = (tracker_alloc_info_t * )critnib_get (
431+ provider -> hTracker -> alloc_segments_map , (uintptr_t )highPtr );
432+ if (!highValue ) {
433+ LOG_ERR ("cannot find the tracker entry to grow %p" , highPtr );
434+ ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
435+ goto err ;
436+ }
437+ if (growSize + highValue -> size != origSize ) {
438+ LOG_ERR ("Grow size plus the current size does not equal the "
439+ "original size" );
440+ ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
441+ goto err ;
442+ }
443+ }
444+
445+ ret =
446+ umfMemoryTrackerAdd (provider -> hTracker , provider -> pool , ptr , origSize );
447+ if (ret != UMF_RESULT_SUCCESS ) {
448+ LOG_ERR ("failed to add the new grown region to the tracker, ptr = %p, "
449+ "size = %zu, ret = %d" ,
450+ ptr , origSize , ret );
451+ goto err ;
452+ }
453+
454+ if (growSize < origSize ) {
455+ void * erasedhighValue = critnib_remove (
456+ provider -> hTracker -> alloc_segments_map , (uintptr_t )highPtr );
457+ assert (erasedhighValue == highValue );
458+ umf_ba_free (provider -> hTracker -> alloc_info_allocator , erasedhighValue );
459+ }
460+
461+ err :
462+ utils_mutex_unlock (& provider -> hTracker -> splitMergeMutex );
463+
464+ return ret ;
465+ }
466+
356467static umf_result_t trackingFree (void * hProvider , void * ptr , size_t size ) {
357468 umf_result_t ret ;
358469 umf_result_t ret_remove = UMF_RESULT_ERROR_UNKNOWN ;
0 commit comments