Skip to content

Commit 403f428

Browse files
committed
Track block usage in low bit of block size
1 parent 7a46bca commit 403f428

File tree

1 file changed

+43
-20
lines changed

1 file changed

+43
-20
lines changed

src/libponyrt/mem/pool.c

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#define POOL_ALIGN_INDEX (POOL_ALIGN_BITS - POOL_MIN_BITS)
2525
#define POOL_ALIGN_MASK (POOL_ALIGN - 1)
2626

27+
#define BLOCK_USED 1
28+
2729
/// When we mmap, pull at least this many bytes.
2830
#ifdef PLATFORM_IS_ILP32
2931
# define POOL_MMAP (16 * 1024 * 1024) // 16 MB
@@ -79,7 +81,6 @@ typedef struct pool_block_t
7981
};
8082
size_t size;
8183
PONY_ATOMIC(bool) acquired;
82-
bool used;
8384

8485
#if defined(_MSC_VER)
8586
pool_block_t() { }
@@ -427,6 +428,27 @@ bool ponyint_pool_mem_pressure()
427428
return false;
428429
}
429430

431+
static void set_block_used(pool_block_t* block)
432+
{
433+
block->size = (block->size | BLOCK_USED);
434+
}
435+
436+
static bool block_is_used(pool_block_t* block)
437+
{
438+
return (block->size & BLOCK_USED) == BLOCK_USED;
439+
}
440+
441+
static void set_block_size(pool_block_t* block, size_t new_size)
442+
{
443+
// make sure to retain `used` marker
444+
block->size = (new_size | (block->size & BLOCK_USED));
445+
}
446+
447+
static size_t block_size(pool_block_t* block)
448+
{
449+
return block->size & ~BLOCK_USED;
450+
}
451+
430452
static void pool_block_remove(pool_block_t* block)
431453
{
432454
pool_block_t* prev = block->prev;
@@ -448,7 +470,7 @@ static void pool_block_insert(pool_block_t* block)
448470

449471
while(next != NULL)
450472
{
451-
if(block->size <= next->size)
473+
if(block_size(block) <= block_size(next))
452474
break;
453475

454476
prev = next;
@@ -486,7 +508,7 @@ static void pool_block_push(pool_block_t* block)
486508
// Find an insertion position. The list is sorted and stays sorted after an
487509
// insertion.
488510
pool_block_t* prev = &pool_block_global;
489-
while((pos != NULL) && (block->size > pos->size))
511+
while((pos != NULL) && (block_size(block) > block_size(pos)))
490512
{
491513
prev = pos;
492514
pos = atomic_load_explicit(&pos->global, memory_order_acquire);
@@ -562,7 +584,7 @@ static pool_block_t* pool_block_pull( size_t size)
562584
pool_block_t* prev = &pool_block_global;
563585

564586
// Find a big enough block. The list is sorted.
565-
while((block != NULL) && (size > block->size))
587+
while((block != NULL) && (size > block_size(block)))
566588
{
567589
prev = block;
568590
block = atomic_load_explicit(&block->global, memory_order_acquire);
@@ -629,7 +651,7 @@ static pool_block_t* pool_block_pull( size_t size)
629651
ANNOTATE_HAPPENS_AFTER(&in_pool_block_global);
630652
#endif
631653

632-
pony_assert(size <= block->size);
654+
pony_assert(size <= block_size(block));
633655

634656
#ifdef USE_VALGRIND
635657
ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(&block->global);
@@ -647,23 +669,23 @@ static void* pool_block_get(size_t size)
647669

648670
while(block != NULL)
649671
{
650-
if(block->size > size)
672+
if(block_size(block) > size)
651673
{
652674
// Use size bytes from the end of the block. This allows us to keep the
653675
// block info inside the block instead of using another data structure.
654-
size_t rem = block->size - size;
655-
block->size = rem;
676+
size_t rem = block_size(block) - size;
677+
set_block_size(block, rem);
656678
pool_block_header.total_size -= size;
657679

658-
if(should_track_mem_allocated && (!block->used))
680+
if(should_track_mem_allocated && !block_is_used(block))
659681
track_mem_allocated(size);
660682

661-
if((block->prev != NULL) && (block->prev->size > block->size))
683+
if((block->prev != NULL) && (block_size(block->prev) > block_size(block)))
662684
{
663685
// If we are now smaller than the previous block, move us forward in
664686
// the list.
665687
if(block->next == NULL)
666-
pool_block_header.largest_size = block->prev->size;
688+
pool_block_header.largest_size = block_size(block->prev);
667689

668690
pool_block_remove(block);
669691
pool_block_insert(block);
@@ -672,15 +694,15 @@ static void* pool_block_get(size_t size)
672694
}
673695

674696
return (char*)block + rem;
675-
} else if(block->size == size) {
697+
} else if(block_size(block) == size) {
676698
if(block->next == NULL)
677699
{
678700
pool_block_header.largest_size =
679-
(block->prev == NULL) ? 0 : block->prev->size;
701+
(block->prev == NULL) ? 0 : block_size(block->prev);
680702
}
681703

682704
// count memory being given to the app
683-
if(should_track_mem_allocated && (!block->used))
705+
if(should_track_mem_allocated && !block_is_used(block))
684706
track_mem_allocated(size);
685707

686708
// Remove the block from the list.
@@ -704,14 +726,14 @@ static void* pool_block_get(size_t size)
704726
return NULL;
705727

706728
// count memory being given to the app
707-
if(should_track_mem_allocated && (!block->used))
729+
if(should_track_mem_allocated && !block_is_used(block))
708730
track_mem_allocated(size);
709731

710-
if(size == block->size)
732+
if(size == block_size(block))
711733
return block;
712734

713-
size_t rem = block->size - size;
714-
block->size = rem;
735+
size_t rem = block_size(block) - size;
736+
set_block_size(block, rem);
715737
pool_block_insert(block);
716738
pool_block_header.total_size += rem;
717739

@@ -739,10 +761,10 @@ static void* pool_alloc_pages(size_t size)
739761
pool_block_t* block = (pool_block_t*)ponyint_virt_alloc(POOL_MMAP);
740762
size_t rem = POOL_MMAP - size;
741763

764+
pony_assert((rem & BLOCK_USED) == 0);
742765
block->size = rem;
743766
block->next = NULL;
744767
block->prev = NULL;
745-
block->used = false;
746768
pool_block_insert(block);
747769
pool_block_header.total_size += rem;
748770
if(pool_block_header.largest_size < rem)
@@ -758,11 +780,12 @@ static void pool_free_pages(void* p, size_t size)
758780
// TODO: ???
759781
}
760782

783+
pony_assert((size & BLOCK_USED) == 0);
761784
pool_block_t* block = (pool_block_t*)p;
762785
block->prev = NULL;
763786
block->next = NULL;
764787
block->size = size;
765-
block->used = true;
788+
set_block_used(block);
766789

767790
pool_block_insert(block);
768791
pool_block_header.total_size += size;

0 commit comments

Comments
 (0)