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