diff --git a/src/arena.c b/src/arena.c index bc7a8296..685b40ee 100644 --- a/src/arena.c +++ b/src/arena.c @@ -6,49 +6,53 @@ #include "gstat.h" /* Arbitrary block size */ -#define HEADER_BLOCK_SIZE 4096 -#define DATA_BLOCK_SIZE 4096 +#define HEADER_SIZE 64 +#define BLOCK_SIZE 4096 /* NOTE: Application will exit if arena fails to reserve or commit initial * memory. */ struct arena *arena_alloc(u64 reserve) { __prof; + reserve += HEADER_SIZE; + /* Round up to nearest block size */ - u64 block_remainder = reserve % DATA_BLOCK_SIZE; + u64 block_remainder = reserve % BLOCK_SIZE; if (block_remainder > 0) { - reserve += DATA_BLOCK_SIZE - block_remainder; + reserve += BLOCK_SIZE - block_remainder; } - u8 *reserve_base = sys_memory_reserve(reserve + HEADER_BLOCK_SIZE); + u8 *reserve_base = sys_memory_reserve(reserve + HEADER_SIZE); if (!reserve_base) { /* Hard fail on memory reserve failure for now */ sys_panic(LIT("Failed to reserve memory")); } u64 reserved = reserve; - gstat_add(GSTAT_MEMORY_RESERVED, reserve + HEADER_BLOCK_SIZE); + gstat_add(GSTAT_MEMORY_RESERVED, reserve + HEADER_SIZE); - /* Commit header block */ - u8 *base = sys_memory_commit(reserve_base, HEADER_BLOCK_SIZE + DATA_BLOCK_SIZE); + /* Commit initial block */ + u8 *base = sys_memory_commit(reserve_base, BLOCK_SIZE); if (!base) { /* Hard fail on commit failure */ sys_panic(LIT("Failed to commit initial memory block: System may be out of memory")); } - base += HEADER_BLOCK_SIZE; - ASAN_POISON(base - HEADER_BLOCK_SIZE, HEADER_BLOCK_SIZE - sizeof(struct arena)); - ASAN_POISON(base, DATA_BLOCK_SIZE); + ASAN_POISON(base + sizeof(struct arena), BLOCK_SIZE - sizeof(struct arena)); ASSERT(((u64)base & 0xFFF) == 0); /* Base should be 4k aligned */ - CT_ASSERT(sizeof(struct arena) <= HEADER_BLOCK_SIZE); /* First block must fit arena */ - gstat_add(GSTAT_MEMORY_COMMITTED, HEADER_BLOCK_SIZE + DATA_BLOCK_SIZE); - __profalloc(reserve_base, HEADER_BLOCK_SIZE + DATA_BLOCK_SIZE); + CT_ASSERT(HEADER_SIZE <= BLOCK_SIZE); /* Header must fit in first block */ + CT_ASSERT(sizeof(struct arena) <= HEADER_SIZE); /* Arena struct must fit in header */ + gstat_add(GSTAT_MEMORY_COMMITTED, BLOCK_SIZE); + __profalloc(reserve_base, BLOCK_SIZE); /* Create arena struct at end of header block */ - struct arena *arena = (struct arena *)(base - sizeof(struct arena)); + struct arena *arena = (struct arena *)base; MEMZERO_STRUCT(arena); + base += HEADER_SIZE; + u64 committed = BLOCK_SIZE - HEADER_SIZE; + gstat_add(GSTAT_NUM_ARENAS, 1); - arena->committed = DATA_BLOCK_SIZE; + arena->committed = committed; arena->reserve_base = reserve_base; arena->base = base; arena->reserved = reserved; @@ -57,7 +61,7 @@ struct arena *arena_alloc(u64 reserve) void arena_release(struct arena *arena) { - ASAN_UNPOISON(arena->reserve_, arena->committed + HEADER_BLOCK_SIZE); + ASAN_UNPOISON(arena->reserve_, arena->committed + HEADER_SIZE); __prof; __proffree(arena->reserve_base); gstat_sub(GSTAT_MEMORY_COMMITTED, arena->committed); @@ -83,8 +87,8 @@ void *arena_push_bytes_no_zero(struct arena *arena, u64 size, u64 align) if (new_pos > arena->committed) { __profscope(_arena_push_bytes_COMMIT); /* Commit new block(s) */ - u64 blocks_needed = (new_pos - arena->committed + DATA_BLOCK_SIZE - 1) / DATA_BLOCK_SIZE; - u64 commit_bytes = blocks_needed * DATA_BLOCK_SIZE; + u64 blocks_needed = (new_pos - arena->committed + BLOCK_SIZE - 1) / BLOCK_SIZE; + u64 commit_bytes = blocks_needed * BLOCK_SIZE; u64 new_capacity = arena->committed + commit_bytes; if (new_capacity > arena->reserved) { /* Hard fail if we overflow reserved memory for now */ @@ -98,7 +102,7 @@ void *arena_push_bytes_no_zero(struct arena *arena, u64 size, u64 align) arena->committed += commit_bytes; gstat_add(GSTAT_MEMORY_COMMITTED, commit_bytes); __proffree(arena->reserve_base); - __profalloc(arena->reserve_base, arena->committed + commit_bytes + HEADER_BLOCK_SIZE); + __profalloc(arena->reserve_base, arena->committed + commit_bytes + HEADER_SIZE); ASAN_POISON(commit_address, commit_bytes); } start = arena->base + aligned_start_pos; @@ -126,7 +130,7 @@ void arena_decommit_unused_blocks(struct arena *arena) { #if 0 ASSERT(!arena->readonly); - u64 next_block_pos = DATA_BLOCK_SIZE * ((arena->pos + (DATA_BLOCK_SIZE - 1)) / DATA_BLOCK_SIZE); + u64 next_block_pos = BLOCK_SIZE * ((arena->pos + (BLOCK_SIZE - 1)) / BLOCK_SIZE); if (arena->committed > next_block_pos) { u8 *decommit_start = arena->base + next_block_pos; u64 decommit_size = (arena->base + arena->committed) - decommit_start; @@ -146,12 +150,12 @@ void arena_set_readonly(struct arena *arena) #if RTC arena->readonly = true; #endif - sys_memory_set_committed_readonly(arena->reserve_base, arena->committed + HEADER_BLOCK_SIZE); + sys_memory_set_committed_readonly(arena->reserve_base, arena->committed + HEADER_SIZE); } void arena_set_readwrite(struct arena *arena) { - sys_memory_set_committed_readwrite(arena->reserve_base, arena->committed + HEADER_BLOCK_SIZE); + sys_memory_set_committed_readwrite(arena->reserve_base, arena->committed + HEADER_SIZE); #if RTC arena->readonly = false; #endif diff --git a/src/host.c b/src/host.c index 3f6fa679..43259fa1 100644 --- a/src/host.c +++ b/src/host.c @@ -1067,7 +1067,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(host_receiver_thread_entry_point, arg) struct arena *read_buff_arena = arena_alloc(read_buff_size); struct string read_buff = ZI; read_buff.len = read_buff_size; - read_buff.text = arena_push_array_no_zero(read_buff_arena, u8, KILOBYTE(64)); + read_buff.text = arena_push_array_no_zero(read_buff_arena, u8, read_buff_size); struct host *host = (struct host *)arg;