Optimizing search, buggy BlockArena on emscripten, cleanup MergeSort, address sanitizer, compile web on linux
This commit is contained in:
@@ -268,7 +268,7 @@ void AddBlock(BlockArena *arena, size_t size = MiB(1)) {
|
||||
if (arena->allocator.proc == NULL) {
|
||||
arena->allocator = GetSystemAllocator();
|
||||
}
|
||||
BlockArenaNode *new_block = (BlockArenaNode *)AllocSize(arena->allocator, block_size + sizeof(BlockArenaNode) + 16);
|
||||
BlockArenaNode *new_block = (BlockArenaNode *)AllocSize(arena->allocator, block_size + sizeof(BlockArenaNode));
|
||||
Assert(GetAlignOffset((size_t)new_block->start, DEFAULT_ALIGNMENT) == 0);
|
||||
arena->start = new_block->start;
|
||||
new_block->end = arena->end = new_block->start + block_size;
|
||||
@@ -294,9 +294,7 @@ API void Release(BlockArena *arena) {
|
||||
next = it->next;
|
||||
Dealloc(arena->allocator, it);
|
||||
}
|
||||
bool safe = arena->when_unwinding_make_sure_to_keep_last_block_alive;
|
||||
MemoryZero(arena, sizeof(BlockArena));
|
||||
arena->when_unwinding_make_sure_to_keep_last_block_alive = safe;
|
||||
}
|
||||
|
||||
API void Unwind(BlockArena *arena, U8 *pos) {
|
||||
@@ -307,16 +305,11 @@ API void Unwind(BlockArena *arena, U8 *pos) {
|
||||
contains = true;
|
||||
break;
|
||||
} else {
|
||||
bool keep = arena->when_unwinding_make_sure_to_keep_last_block_alive && arena->blocks->next == NULL;
|
||||
if (keep) {
|
||||
pos = arena->blocks->start;
|
||||
} else {
|
||||
arena->blocks = arena->blocks->next;
|
||||
Dealloc(arena->allocator, it);
|
||||
}
|
||||
arena->blocks = arena->blocks->next;
|
||||
Dealloc(arena->allocator, it);
|
||||
}
|
||||
}
|
||||
Assert(contains || pos == NULL || (arena->when_unwinding_make_sure_to_keep_last_block_alive && pos == arena->blocks->start));
|
||||
Assert(contains || pos == NULL);
|
||||
arena->start = pos;
|
||||
arena->end = arena->blocks ? arena->blocks->end : NULL;
|
||||
}
|
||||
@@ -332,8 +325,11 @@ API void *BlockArenaAllocatorProc(void *object, int kind, void *p, size_t size)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if OS_WASM
|
||||
API void InitScratch() {
|
||||
}
|
||||
#else
|
||||
thread_local VirtualArena ScratchArenas[4];
|
||||
|
||||
API void InitScratch() {
|
||||
for (int i = 0; i < 4; i += 1) {
|
||||
InitArena(&ScratchArenas[i]);
|
||||
@@ -362,6 +358,7 @@ API VirtualArena *GetScratchEx(VirtualArena **conflicts, int conflict_count) {
|
||||
Assert(unoccupied);
|
||||
return unoccupied;
|
||||
}
|
||||
#endif
|
||||
|
||||
void RunArenaTest() {
|
||||
Allocator memory_tracking_allocator = GetTrackingAllocator();
|
||||
@@ -380,7 +377,6 @@ void RunArenaTest() {
|
||||
|
||||
{
|
||||
BlockArena arena = {};
|
||||
U8 *start = arena.start;
|
||||
arena.allocator = memory_tracking_allocator;
|
||||
int *vals = (int *)PushSize(&arena, sizeof(int) * 32);
|
||||
for (int i = 0; i < 32; i += 1) vals[i] = i;
|
||||
@@ -402,7 +398,7 @@ void RunArenaTest() {
|
||||
|
||||
U8 *p = arena.start;
|
||||
U8 *a = (U8 *)PushSize(&arena, KiB(32));
|
||||
U8 *b = (U8 *)PushSize(&arena, KiB(1000));
|
||||
PushSize(&arena, KiB(1000));
|
||||
Assert(arena.blocks);
|
||||
Assert(arena.blocks->next);
|
||||
Assert(arena.blocks->next->next == NULL);
|
||||
@@ -418,7 +414,7 @@ void RunArenaTest() {
|
||||
{
|
||||
BlockArena arena = {};
|
||||
arena.allocator = memory_tracking_allocator;
|
||||
U8 *a = (U8 *)PushSize(&arena, KiB(2000));
|
||||
PushSize(&arena, KiB(2000));
|
||||
Assert((size_t)(arena.blocks[0].end - arena.blocks[0].start) == KiB(2000));
|
||||
Release(&arena);
|
||||
Assert(MemoryTrackingRecord.len == 0);
|
||||
@@ -427,15 +423,14 @@ void RunArenaTest() {
|
||||
{
|
||||
BlockArena arena = {};
|
||||
arena.allocator = memory_tracking_allocator;
|
||||
arena.when_unwinding_make_sure_to_keep_last_block_alive = true;
|
||||
PushSize(&arena, KiB(2000));
|
||||
Unwind(&arena, 0);
|
||||
Assert(MemoryTrackingRecord.len == 1);
|
||||
Assert(MemoryTrackingRecord.len == 0);
|
||||
PushSize(&arena, MiB(1));
|
||||
PushSize(&arena, MiB(3));
|
||||
Assert(MemoryTrackingRecord.len == 2);
|
||||
Unwind(&arena, 0);
|
||||
Assert(MemoryTrackingRecord.len == 1);
|
||||
Assert(MemoryTrackingRecord.len == 0);
|
||||
Release(&arena);
|
||||
Assert(MemoryTrackingRecord.len == 0);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,6 @@ struct BlockArena {
|
||||
U8 *end;
|
||||
BlockArenaNode *blocks;
|
||||
Allocator allocator;
|
||||
bool when_unwinding_make_sure_to_keep_last_block_alive;
|
||||
|
||||
operator Allocator() { return {BlockArenaAllocatorProc, this}; }
|
||||
};
|
||||
@@ -96,9 +95,24 @@ API void Release(VirtualArena *arena);
|
||||
|
||||
///////////////////////////////
|
||||
// Scratch
|
||||
#if OS_WASM
|
||||
struct Scratch {
|
||||
BlockArena arena = {};
|
||||
Scratch() {}
|
||||
Scratch(BlockArena *conflict) {}
|
||||
Scratch(BlockArena *c1, BlockArena *c2) {}
|
||||
Scratch(Allocator conflict) {}
|
||||
Scratch(Allocator c1, Allocator c2) {}
|
||||
~Scratch() { Release(&arena); }
|
||||
operator BlockArena *() { return &arena; }
|
||||
operator Allocator() { return arena; }
|
||||
private: // @Note: Disable copy constructors, cause its error prone
|
||||
Scratch(Scratch &arena);
|
||||
Scratch(Scratch &arena, Scratch &a2);
|
||||
};
|
||||
#else
|
||||
extern thread_local VirtualArena ScratchArenas[4];
|
||||
API VirtualArena *GetScratchEx(VirtualArena **conflicts, int conflict_count);
|
||||
|
||||
struct Scratch {
|
||||
VirtualArena *arena;
|
||||
U64 p;
|
||||
@@ -131,6 +145,7 @@ struct Scratch {
|
||||
Scratch(Scratch &arena);
|
||||
Scratch(Scratch &arena, Scratch &a2);
|
||||
};
|
||||
#endif
|
||||
|
||||
const int PAGE_SIZE = 4096;
|
||||
const int DEFAULT_ALIGNMENT = sizeof(void *);
|
||||
|
||||
@@ -408,6 +408,7 @@ API bool IsValid(Process *process) {
|
||||
int res = poll(&p, 1, 0);
|
||||
if (res > 0) {
|
||||
pid_t result = waitpid(plat->pid, &status, 0);
|
||||
Assert(result != -1);
|
||||
process->exit_code = WEXITSTATUS(status);
|
||||
return false;
|
||||
}
|
||||
@@ -1104,9 +1105,9 @@ API void Advance(FileIter *it) {
|
||||
|
||||
const char *dir_char_ending = it->is_directory ? "/" : "";
|
||||
const char *separator = it->path.data[it->path.len - 1] == '/' ? "" : "/";
|
||||
it->relative_path = Format(it->allocator, "%.*s%s%s%s", FmtString(it->path), separator, file->d_name, dir_char_ending);
|
||||
it->relative_path = Format(it->allocator, "%S%s%s%s", it->path, separator, file->d_name, dir_char_ending);
|
||||
it->absolute_path = GetAbsolutePath(it->allocator, it->relative_path);
|
||||
if (it->is_directory) it->absolute_path = Format(it->allocator, "%.*s/", FmtString(it->absolute_path));
|
||||
if (it->is_directory) it->absolute_path = Format(it->allocator, "%S/", it->absolute_path);
|
||||
it->is_valid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user