@@ -267,6 +267,61 @@ 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_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
+
270
325
static umf_result_t trackingAllocationMerge (void * hProvider , void * lowPtr ,
271
326
void * highPtr , size_t totalSize ) {
272
327
umf_result_t ret = UMF_RESULT_ERROR_UNKNOWN ;
@@ -353,6 +408,68 @@ static umf_result_t trackingAllocationMerge(void *hProvider, void *lowPtr,
353
408
return ret ;
354
409
}
355
410
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
+
356
473
static umf_result_t trackingFree (void * hProvider , void * ptr , size_t size ) {
357
474
umf_result_t ret ;
358
475
umf_result_t ret_remove = UMF_RESULT_ERROR_UNKNOWN ;
0 commit comments