@@ -267,6 +267,58 @@ static umf_result_t trackingAllocationSplit(void *hProvider, void *ptr,
267
267
return ret ;
268
268
}
269
269
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
+
270
322
static umf_result_t trackingAllocationMerge (void * hProvider , void * lowPtr ,
271
323
void * highPtr , size_t totalSize ) {
272
324
umf_result_t ret = UMF_RESULT_ERROR_UNKNOWN ;
@@ -353,6 +405,65 @@ static umf_result_t trackingAllocationMerge(void *hProvider, void *lowPtr,
353
405
return ret ;
354
406
}
355
407
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
+
356
467
static umf_result_t trackingFree (void * hProvider , void * ptr , size_t size ) {
357
468
umf_result_t ret ;
358
469
umf_result_t ret_remove = UMF_RESULT_ERROR_UNKNOWN ;
0 commit comments