@@ -458,6 +458,108 @@ static bool arena_grow(tlsf_t *t, size_t size)
458
458
return true;
459
459
}
460
460
461
+ static size_t arena_append_pool (tlsf_t * t , void * mem , size_t size )
462
+ {
463
+ if (!t -> size || !mem || size < 2 * BLOCK_OVERHEAD )
464
+ return 0 ;
465
+
466
+ /* Align memory block boundaries */
467
+ char * start = align_ptr ((char * ) mem , ALIGN_SIZE );
468
+ char * end = (char * ) mem + size ;
469
+ size_t aligned_size = (size_t ) (end - start ) & ~(ALIGN_SIZE - 1 );
470
+
471
+ if (aligned_size < 2 * BLOCK_OVERHEAD )
472
+ return 0 ;
473
+
474
+ /* Get current pool information */
475
+ void * current_pool_start =
476
+ tlsf_resize (t , t -> size ); /* Ensure current pool is available */
477
+ if (!current_pool_start )
478
+ return 0 ;
479
+
480
+ char * current_pool_end = (char * ) current_pool_start + t -> size ;
481
+
482
+ /* Only support coalescing if the new memory is immediately adjacent to the
483
+ * current pool
484
+ */
485
+ if (start != current_pool_end )
486
+ return 0 ;
487
+
488
+ /* Update the pool size first to include the new memory */
489
+ size_t old_size = t -> size ;
490
+ size_t new_total_size = t -> size + aligned_size ;
491
+
492
+ /* Try to resize the pool to include the new memory */
493
+ void * resized_pool = tlsf_resize (t , new_total_size );
494
+ if (!resized_pool )
495
+ return 0 ;
496
+
497
+ /* Update our pool size */
498
+ t -> size = new_total_size ;
499
+
500
+ /* Find the current sentinel block */
501
+ tlsf_block_t * old_sentinel =
502
+ to_block ((char * ) resized_pool + old_size - 2 * BLOCK_OVERHEAD );
503
+ check_sentinel (old_sentinel );
504
+
505
+ /* Check if the block before the sentinel is free */
506
+ tlsf_block_t * last_block = NULL ;
507
+ if (block_is_prev_free (old_sentinel )) {
508
+ last_block = block_prev (old_sentinel );
509
+ ASSERT (last_block && block_is_free (last_block ),
510
+ "last block should be free" );
511
+ /* Remove the last free block from lists since we'll recreate it */
512
+ block_remove (t , last_block );
513
+ }
514
+
515
+ /* Calculate the new free block size */
516
+ size_t new_free_size =
517
+ aligned_size + BLOCK_OVERHEAD ; /* Include old sentinel space */
518
+ tlsf_block_t * new_free_block ;
519
+
520
+ if (last_block ) {
521
+ /* Merge with the existing free block */
522
+ new_free_size += block_size (last_block ) + BLOCK_OVERHEAD ;
523
+ new_free_block = last_block ;
524
+ } else {
525
+ /* Convert the old sentinel into the start of the new free block */
526
+ new_free_block = old_sentinel ;
527
+ }
528
+
529
+ /* Set up the new free block header */
530
+ new_free_block -> header = new_free_size | BLOCK_BIT_FREE ;
531
+
532
+ /* Set up proper linking for the new free block */
533
+ if (!last_block && old_size > 2 * BLOCK_OVERHEAD ) {
534
+ /* There's a previous block, find it by scanning backwards */
535
+ char * scan_start = (char * ) old_sentinel - BLOCK_OVERHEAD ;
536
+ char * pool_start = (char * ) resized_pool ;
537
+
538
+ /* Simple backward scan to find the previous block */
539
+ for (char * scan_ptr = scan_start ; scan_ptr >= pool_start ;
540
+ scan_ptr -= ALIGN_SIZE ) {
541
+ tlsf_block_t * candidate = to_block (scan_ptr - BLOCK_OVERHEAD );
542
+ if ((char * ) candidate >= pool_start &&
543
+ (char * ) candidate + BLOCK_OVERHEAD + block_size (candidate ) ==
544
+ (char * ) old_sentinel ) {
545
+ new_free_block -> prev = candidate ;
546
+ block_set_prev_free (new_free_block , block_is_free (candidate ));
547
+ break ;
548
+ }
549
+ }
550
+ }
551
+
552
+ /* Insert the new free block into the appropriate list */
553
+ block_insert (t , new_free_block );
554
+
555
+ /* Create a new sentinel at the end */
556
+ tlsf_block_t * new_sentinel = block_link_next (new_free_block );
557
+ new_sentinel -> header = BLOCK_BIT_PREV_FREE ;
558
+ check_sentinel (new_sentinel );
559
+
560
+ return aligned_size ;
561
+ }
562
+
461
563
static void arena_shrink (tlsf_t * t , tlsf_block_t * block )
462
564
{
463
565
check_sentinel (block_next (block ));
@@ -594,6 +696,14 @@ void *tlsf_realloc(tlsf_t *t, void *mem, size_t size)
594
696
return mem ;
595
697
}
596
698
699
+ size_t tlsf_append_pool (tlsf_t * t , void * mem , size_t size )
700
+ {
701
+ if (UNLIKELY (!t || !mem || !size ))
702
+ return 0 ;
703
+
704
+ return arena_append_pool (t , mem , size );
705
+ }
706
+
597
707
#ifdef TLSF_ENABLE_CHECK
598
708
#include <stdio.h>
599
709
#include <stdlib.h>
0 commit comments