store arena struct in first block
This commit is contained in:
parent
cfd8fb5f21
commit
17a8284e6c
50
src/arena.c
50
src/arena.c
@ -6,49 +6,53 @@
|
|||||||
#include "gstat.h"
|
#include "gstat.h"
|
||||||
|
|
||||||
/* Arbitrary block size */
|
/* Arbitrary block size */
|
||||||
#define HEADER_BLOCK_SIZE 4096
|
#define HEADER_SIZE 64
|
||||||
#define DATA_BLOCK_SIZE 4096
|
#define BLOCK_SIZE 4096
|
||||||
|
|
||||||
/* NOTE: Application will exit if arena fails to reserve or commit initial
|
/* NOTE: Application will exit if arena fails to reserve or commit initial
|
||||||
* memory. */
|
* memory. */
|
||||||
struct arena *arena_alloc(u64 reserve)
|
struct arena *arena_alloc(u64 reserve)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
|
reserve += HEADER_SIZE;
|
||||||
|
|
||||||
/* Round up to nearest block size */
|
/* Round up to nearest block size */
|
||||||
u64 block_remainder = reserve % DATA_BLOCK_SIZE;
|
u64 block_remainder = reserve % BLOCK_SIZE;
|
||||||
if (block_remainder > 0) {
|
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) {
|
if (!reserve_base) {
|
||||||
/* Hard fail on memory reserve failure for now */
|
/* Hard fail on memory reserve failure for now */
|
||||||
sys_panic(LIT("Failed to reserve memory"));
|
sys_panic(LIT("Failed to reserve memory"));
|
||||||
}
|
}
|
||||||
u64 reserved = reserve;
|
u64 reserved = reserve;
|
||||||
gstat_add(GSTAT_MEMORY_RESERVED, reserve + HEADER_BLOCK_SIZE);
|
gstat_add(GSTAT_MEMORY_RESERVED, reserve + HEADER_SIZE);
|
||||||
|
|
||||||
/* Commit header block */
|
/* Commit initial block */
|
||||||
u8 *base = sys_memory_commit(reserve_base, HEADER_BLOCK_SIZE + DATA_BLOCK_SIZE);
|
u8 *base = sys_memory_commit(reserve_base, BLOCK_SIZE);
|
||||||
if (!base) {
|
if (!base) {
|
||||||
/* Hard fail on commit failure */
|
/* Hard fail on commit failure */
|
||||||
sys_panic(LIT("Failed to commit initial memory block: System may be out of memory"));
|
sys_panic(LIT("Failed to commit initial memory block: System may be out of memory"));
|
||||||
}
|
}
|
||||||
base += HEADER_BLOCK_SIZE;
|
ASAN_POISON(base + sizeof(struct arena), BLOCK_SIZE - sizeof(struct arena));
|
||||||
ASAN_POISON(base - HEADER_BLOCK_SIZE, HEADER_BLOCK_SIZE - sizeof(struct arena));
|
|
||||||
ASAN_POISON(base, DATA_BLOCK_SIZE);
|
|
||||||
|
|
||||||
ASSERT(((u64)base & 0xFFF) == 0); /* Base should be 4k aligned */
|
ASSERT(((u64)base & 0xFFF) == 0); /* Base should be 4k aligned */
|
||||||
CT_ASSERT(sizeof(struct arena) <= HEADER_BLOCK_SIZE); /* First block must fit arena */
|
CT_ASSERT(HEADER_SIZE <= BLOCK_SIZE); /* Header must fit in first block */
|
||||||
gstat_add(GSTAT_MEMORY_COMMITTED, HEADER_BLOCK_SIZE + DATA_BLOCK_SIZE);
|
CT_ASSERT(sizeof(struct arena) <= HEADER_SIZE); /* Arena struct must fit in header */
|
||||||
__profalloc(reserve_base, HEADER_BLOCK_SIZE + DATA_BLOCK_SIZE);
|
gstat_add(GSTAT_MEMORY_COMMITTED, BLOCK_SIZE);
|
||||||
|
__profalloc(reserve_base, BLOCK_SIZE);
|
||||||
|
|
||||||
/* Create arena struct at end of header block */
|
/* 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);
|
MEMZERO_STRUCT(arena);
|
||||||
|
|
||||||
|
base += HEADER_SIZE;
|
||||||
|
u64 committed = BLOCK_SIZE - HEADER_SIZE;
|
||||||
|
|
||||||
gstat_add(GSTAT_NUM_ARENAS, 1);
|
gstat_add(GSTAT_NUM_ARENAS, 1);
|
||||||
arena->committed = DATA_BLOCK_SIZE;
|
arena->committed = committed;
|
||||||
arena->reserve_base = reserve_base;
|
arena->reserve_base = reserve_base;
|
||||||
arena->base = base;
|
arena->base = base;
|
||||||
arena->reserved = reserved;
|
arena->reserved = reserved;
|
||||||
@ -57,7 +61,7 @@ struct arena *arena_alloc(u64 reserve)
|
|||||||
|
|
||||||
void arena_release(struct arena *arena)
|
void arena_release(struct arena *arena)
|
||||||
{
|
{
|
||||||
ASAN_UNPOISON(arena->reserve_, arena->committed + HEADER_BLOCK_SIZE);
|
ASAN_UNPOISON(arena->reserve_, arena->committed + HEADER_SIZE);
|
||||||
__prof;
|
__prof;
|
||||||
__proffree(arena->reserve_base);
|
__proffree(arena->reserve_base);
|
||||||
gstat_sub(GSTAT_MEMORY_COMMITTED, arena->committed);
|
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) {
|
if (new_pos > arena->committed) {
|
||||||
__profscope(_arena_push_bytes_COMMIT);
|
__profscope(_arena_push_bytes_COMMIT);
|
||||||
/* Commit new block(s) */
|
/* Commit new block(s) */
|
||||||
u64 blocks_needed = (new_pos - arena->committed + DATA_BLOCK_SIZE - 1) / DATA_BLOCK_SIZE;
|
u64 blocks_needed = (new_pos - arena->committed + BLOCK_SIZE - 1) / BLOCK_SIZE;
|
||||||
u64 commit_bytes = blocks_needed * DATA_BLOCK_SIZE;
|
u64 commit_bytes = blocks_needed * BLOCK_SIZE;
|
||||||
u64 new_capacity = arena->committed + commit_bytes;
|
u64 new_capacity = arena->committed + commit_bytes;
|
||||||
if (new_capacity > arena->reserved) {
|
if (new_capacity > arena->reserved) {
|
||||||
/* Hard fail if we overflow reserved memory for now */
|
/* 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;
|
arena->committed += commit_bytes;
|
||||||
gstat_add(GSTAT_MEMORY_COMMITTED, commit_bytes);
|
gstat_add(GSTAT_MEMORY_COMMITTED, commit_bytes);
|
||||||
__proffree(arena->reserve_base);
|
__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);
|
ASAN_POISON(commit_address, commit_bytes);
|
||||||
}
|
}
|
||||||
start = arena->base + aligned_start_pos;
|
start = arena->base + aligned_start_pos;
|
||||||
@ -126,7 +130,7 @@ void arena_decommit_unused_blocks(struct arena *arena)
|
|||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
ASSERT(!arena->readonly);
|
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) {
|
if (arena->committed > next_block_pos) {
|
||||||
u8 *decommit_start = arena->base + next_block_pos;
|
u8 *decommit_start = arena->base + next_block_pos;
|
||||||
u64 decommit_size = (arena->base + arena->committed) - decommit_start;
|
u64 decommit_size = (arena->base + arena->committed) - decommit_start;
|
||||||
@ -146,12 +150,12 @@ void arena_set_readonly(struct arena *arena)
|
|||||||
#if RTC
|
#if RTC
|
||||||
arena->readonly = true;
|
arena->readonly = true;
|
||||||
#endif
|
#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)
|
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
|
#if RTC
|
||||||
arena->readonly = false;
|
arena->readonly = false;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -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 arena *read_buff_arena = arena_alloc(read_buff_size);
|
||||||
struct string read_buff = ZI;
|
struct string read_buff = ZI;
|
||||||
read_buff.len = read_buff_size;
|
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;
|
struct host *host = (struct host *)arg;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user