Create a cached string_builder in the thread local context.
This commit is contained in:
parent
8ebdcb27a8
commit
14eb817631
@ -1,7 +1,7 @@
|
|||||||
// Treat library files as a single-file (single translation unit) header
|
// Treat library files as a single-file (single translation unit) header
|
||||||
#include "lib_main.cpp"
|
#include "lib_main.cpp"
|
||||||
|
|
||||||
#define BASE_RUN_TESTS 0
|
#define BASE_RUN_TESTS BUILD_DEBUG
|
||||||
#define BUILD_EXPLORER_APP_WIN32 1
|
#define BUILD_EXPLORER_APP_WIN32 1
|
||||||
#define BUILD_CUSTOM_GUI 0
|
#define BUILD_CUSTOM_GUI 0
|
||||||
|
|
||||||
|
|||||||
@ -209,6 +209,7 @@ template <typename T> void init_range (T* ptr, s64 start_offset, s64 end_offset)
|
|||||||
|
|
||||||
template <typename T> void array_poison_range (ArenaArray<T>& array, s64 start, s64 count) {
|
template <typename T> void array_poison_range (ArenaArray<T>& array, s64 start, s64 count) {
|
||||||
#if BUILD_DEBUG
|
#if BUILD_DEBUG
|
||||||
|
if (count == 0) return;
|
||||||
Assert(start >= 0 && start < array.count);
|
Assert(start >= 0 && start < array.count);
|
||||||
Assert(start + count <= array.count);
|
Assert(start + count <= array.count);
|
||||||
// Check that these ranges make sense
|
// Check that these ranges make sense
|
||||||
|
|||||||
@ -342,6 +342,7 @@ force_inline s64 Next_Power_Of_Two(s64 v) {
|
|||||||
#define temp() allocator(thread_context()->temp)
|
#define temp() allocator(thread_context()->temp)
|
||||||
#define context_allocator() thread_context()->allocator
|
#define context_allocator() thread_context()->allocator
|
||||||
#define context_logger() &thread_context()->logger
|
#define context_logger() &thread_context()->logger
|
||||||
|
#define context_builder() thread_context()->string_builder
|
||||||
|
|
||||||
// CHECK THAT THESE ARE CORRECT!
|
// CHECK THAT THESE ARE CORRECT!
|
||||||
constexpr f32 TAU = 6.283185f;
|
constexpr f32 TAU = 6.283185f;
|
||||||
|
|||||||
@ -22,13 +22,14 @@ internal void Bootstrap_Main_Thread_Context () {
|
|||||||
ExpandableArena* arena_ex = bootstrap_expandable_arena(Arena_Reserve::Size_64M);
|
ExpandableArena* arena_ex = bootstrap_expandable_arena(Arena_Reserve::Size_64M);
|
||||||
|
|
||||||
thread_local_context = New<Thread_Context>(allocator(arena_ex));
|
thread_local_context = New<Thread_Context>(allocator(arena_ex));
|
||||||
thread_local_context->temp = bootstrap_expandable_arena(Arena_Reserve::Size_2M);
|
thread_local_context->temp = bootstrap_expandable_arena(Arena_Reserve::Size_2M);
|
||||||
thread_local_context->arena = arena_ex;
|
thread_local_context->arena = arena_ex;
|
||||||
thread_local_context->allocator = allocator(arena_ex);
|
thread_local_context->allocator = allocator(arena_ex);
|
||||||
thread_local_context->thread_idx = 0;
|
thread_local_context->thread_idx = 0;
|
||||||
thread_local_context->thread_name = "Main Thread";
|
thread_local_context->thread_name = "Main Thread";
|
||||||
thread_local_context->log_builder = new_string_builder(Arena_Reserve::Size_64M);
|
thread_local_context->log_builder = new_string_builder(Arena_Reserve::Size_64M);
|
||||||
thread_local_context->error_arena = bootstrap_arena(Arena_Reserve::Size_64M);
|
thread_local_context->string_builder = new_string_builder(Arena_Reserve::Size_2M);
|
||||||
|
thread_local_context->error_arena = bootstrap_arena(Arena_Reserve::Size_64M);
|
||||||
|
|
||||||
default_logger_initialize();
|
default_logger_initialize();
|
||||||
thread_local_context->logger = {default_logger_proc, &default_logger};
|
thread_local_context->logger = {default_logger_proc, &default_logger};
|
||||||
|
|||||||
@ -24,7 +24,8 @@ struct Thread_Context {
|
|||||||
// u16 _padding0;
|
// u16 _padding0;
|
||||||
u16 default_allocator_alignment = 16;
|
u16 default_allocator_alignment = 16;
|
||||||
Logger logger = {nullptr, nullptr};
|
Logger logger = {nullptr, nullptr};
|
||||||
String_Builder* log_builder;
|
String_Builder* log_builder; // String builder used by log() and log_error_internal()
|
||||||
|
String_Builder* string_builder; // Secondary builder just for convenience!
|
||||||
Stack_Trace_Node* stack_trace; // use `list(stack_trace)` in watch window of raddbg to view as array!
|
Stack_Trace_Node* stack_trace; // use `list(stack_trace)` in watch window of raddbg to view as array!
|
||||||
|
|
||||||
Array<Thread*> child_threads; // maybe should be linked-list?
|
Array<Thread*> child_threads; // maybe should be linked-list?
|
||||||
@ -127,7 +128,8 @@ struct Push_Stack_Trace {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// #TODO: precede with something like: os_write_string_unsynchronized("Fatal Error!\n\nStack trace:", true);
|
// #TODO: precede with something like: os_write_string_unsynchronized("Fatal Error!\n\nStack trace:", true);
|
||||||
string generate_stack_trace (Thread_Context* context) { // #no_context
|
string generate_stack_trace (Thread_Context* context) {
|
||||||
|
// #no_context - we want this to work even if context is utterly broken.
|
||||||
String_Builder* sb = new_string_builder(Arena_Reserve::Size_64K);
|
String_Builder* sb = new_string_builder(Arena_Reserve::Size_64K);
|
||||||
|
|
||||||
Stack_Trace_Node* node = context->stack_trace;
|
Stack_Trace_Node* node = context->stack_trace;
|
||||||
@ -143,7 +145,12 @@ string generate_stack_trace (Thread_Context* context) { // #no_context
|
|||||||
append(sb, "\n");
|
append(sb, "\n");
|
||||||
|
|
||||||
push_allocator(default_allocator());
|
push_allocator(default_allocator());
|
||||||
return builder_to_string(sb);
|
|
||||||
|
string stack_trace_copy = builder_to_string(sb);
|
||||||
|
|
||||||
|
free_string_builder(sb);
|
||||||
|
|
||||||
|
return stack_trace_copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't want to use context logger here!
|
// We don't want to use context logger here!
|
||||||
|
|||||||
@ -282,7 +282,7 @@ internal force_inline void reset_string_builder (String_Builder* sb, bool keep_m
|
|||||||
force_inline string builder_to_string (String_Builder* sb) {
|
force_inline string builder_to_string (String_Builder* sb) {
|
||||||
string final_string = copy_string(to_string(to_view(*sb)));
|
string final_string = copy_string(to_string(to_view(*sb)));
|
||||||
|
|
||||||
free_string_builder(sb);
|
// reset_string_builder(sb, false); // maybe this shouldn't be here! Too magical...
|
||||||
|
|
||||||
return final_string;
|
return final_string;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,14 @@
|
|||||||
// #string_builder
|
// #string_builder
|
||||||
// #limitations This won't be as fast as Jon's String_Builder in jai because we're backing it with an
|
// #limitations This won't be as fast as Jon's String_Builder in jai because we're backing it with an
|
||||||
// Arena, which requires a variable number of cycles depending on if our process has
|
// Arena, which calls VirtualAlloc, which is much slower than just using stack space to start.
|
||||||
// memory available already. It also has a max capacity depending on what Arena_Reserve we choose.
|
// It also has a max capacity depending on what Arena_Reserve we choose.
|
||||||
// That being said, the implementation is much simpler.
|
// That being said, the implementation is much simpler, and we can keep it around for a bit.
|
||||||
|
// We can make it a lot faster by always having a string builder available in the thread_context,
|
||||||
|
// and just fetching that when we need it.
|
||||||
|
|
||||||
typedef ArenaArray<u8> String_Builder; // struct String_Builder
|
typedef ArenaArray<u8> String_Builder; // struct String_Builder
|
||||||
|
|
||||||
|
|
||||||
force_inline String_Builder* new_string_builder (Arena_Reserve new_reserve=Arena_Reserve::Size_64K);
|
force_inline String_Builder* new_string_builder (Arena_Reserve new_reserve=Arena_Reserve::Size_64K);
|
||||||
force_inline void append (String_Builder* sb, string s);
|
force_inline void append (String_Builder* sb, string s);
|
||||||
void append (String_Builder* sb, ArrayView<string> strings);
|
void append (String_Builder* sb, ArrayView<string> strings);
|
||||||
@ -18,3 +22,5 @@ internal force_inline void reset_string_builder (String_Builder* sb, bool keep_m
|
|||||||
// #rename copy_string_and_free_builder
|
// #rename copy_string_and_free_builder
|
||||||
force_inline string builder_to_string (String_Builder* sb); // returns copy and frees string_builder
|
force_inline string builder_to_string (String_Builder* sb); // returns copy and frees string_builder
|
||||||
internal force_inline void free_string_builder (String_Builder* sb);
|
internal force_inline void free_string_builder (String_Builder* sb);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,9 @@ void run_post_setup_tests() {
|
|||||||
// String builder example:
|
// String builder example:
|
||||||
// OK. I can work with this.
|
// OK. I can work with this.
|
||||||
|
|
||||||
auto sb = new_string_builder(Arena_Reserve::Size_64K);
|
String_Builder* sb = context_builder();
|
||||||
|
reset_string_builder(sb, true);
|
||||||
|
|
||||||
append(sb, "string_literal_example");
|
append(sb, "string_literal_example");
|
||||||
append(sb, " ");
|
append(sb, " ");
|
||||||
print_to_builder(sb, "There are %d cats in the %s", 64, "house.\n");
|
print_to_builder(sb, "There are %d cats in the %s", 64, "house.\n");
|
||||||
@ -47,9 +49,9 @@ void run_post_setup_tests() {
|
|||||||
// push_allocator(allocator(thread_context()->arena));
|
// push_allocator(allocator(thread_context()->arena));
|
||||||
push_allocator(default_allocator());
|
push_allocator(default_allocator());
|
||||||
string file_path = "D:/Work/OpenBCI/ToolZ/prototyping-gui-main/modules/native-proto-lib/native-sdk-prototyping/src/SignalProcessing.cpp";
|
string file_path = "D:/Work/OpenBCI/ToolZ/prototyping-gui-main/modules/native-proto-lib/native-sdk-prototyping/src/SignalProcessing.cpp";
|
||||||
ArrayView<u8> file_data = read_entire_file(file_path, true);
|
ArrayView<u8> file_data = read_entire_file(file_path, true, true);
|
||||||
log("file_data: \n");
|
log("file_data: \n");
|
||||||
log("%s\n", file_data.data);
|
log("%s\n", file_data.data); // #note this is not null-terminated
|
||||||
}
|
}
|
||||||
{ // Test hashing:
|
{ // Test hashing:
|
||||||
u64 start = 0x512585;
|
u64 start = 0x512585;
|
||||||
|
|||||||
@ -84,8 +84,8 @@ string get_full_path (string drive_label, Dense_FS* dfs, s32 first_parent_index,
|
|||||||
|
|
||||||
array_add(path_list_reverse, drive_letter_with_colon);
|
array_add(path_list_reverse, drive_letter_with_colon);
|
||||||
|
|
||||||
// reset_string_builder(sb, true);
|
String_Builder* sb = context_builder();
|
||||||
String_Builder* sb = new_string_builder();
|
reset_string_builder(sb, true);
|
||||||
|
|
||||||
for (s64 i = path_list_reverse.count-1; i >= 0; i -= 1) {
|
for (s64 i = path_list_reverse.count-1; i >= 0; i -= 1) {
|
||||||
append(sb, path_list_reverse[i]);
|
append(sb, path_list_reverse[i]);
|
||||||
|
|||||||
@ -296,15 +296,16 @@ internal bool thread_init (Thread* thread, Thread_Proc proc, string thread_name)
|
|||||||
|
|
||||||
// #NOTE: we don't assign thread_local_context until we hit the #thread_entry_point
|
// #NOTE: we don't assign thread_local_context until we hit the #thread_entry_point
|
||||||
thread->context = New<Thread_Context>();
|
thread->context = New<Thread_Context>();
|
||||||
thread->context->temp = bootstrap_expandable_arena(Arena_Reserve::Size_2M);
|
thread->context->temp = bootstrap_expandable_arena(Arena_Reserve::Size_2M);
|
||||||
thread->context->arena = arena_ex;
|
thread->context->arena = arena_ex;
|
||||||
thread->context->allocator = allocator(arena_ex);
|
thread->context->allocator = allocator(arena_ex);
|
||||||
thread->context->thread_idx = (s32)this_thread_index;
|
thread->context->thread_idx = (s32)this_thread_index;
|
||||||
// #NOTE: This will disappear once the thread is de-initted. If we want this string, copy it!
|
// #NOTE: This will disappear once the thread is de-initted. If we want this string, copy it!
|
||||||
thread->context->thread_name = copy_string(thread_name);
|
thread->context->thread_name = copy_string(thread_name);
|
||||||
thread->context->log_builder = new_string_builder(Arena_Reserve::Size_64M);
|
thread->context->log_builder = new_string_builder(Arena_Reserve::Size_64M);
|
||||||
thread->context->error_arena = bootstrap_arena(Arena_Reserve::Size_64M);
|
thread->context->string_builder = new_string_builder(Arena_Reserve::Size_2M);
|
||||||
thread->context->logger = {default_logger_proc, &default_logger};
|
thread->context->error_arena = bootstrap_arena(Arena_Reserve::Size_64M);
|
||||||
|
thread->context->logger = {default_logger_proc, &default_logger};
|
||||||
|
|
||||||
thread->context->parent_thread_context = thread_context();
|
thread->context->parent_thread_context = thread_context();
|
||||||
|
|
||||||
@ -557,7 +558,7 @@ internal bool file_set_position (File file, s64 position) {
|
|||||||
return (bool)SetFilePointerEx(file.handle, position_li, nullptr, FILE_BEGIN);
|
return (bool)SetFilePointerEx(file.handle, position_li, nullptr, FILE_BEGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ArrayView<u8> read_entire_file (File file) {
|
ArrayView<u8> read_entire_file (File file, bool add_null_terminator) {
|
||||||
ArrayView<u8> file_data;
|
ArrayView<u8> file_data;
|
||||||
|
|
||||||
bool result = file_length(file, &file_data.count);
|
bool result = file_length(file, &file_data.count);
|
||||||
@ -565,7 +566,13 @@ internal ArrayView<u8> read_entire_file (File file) {
|
|||||||
result = file_set_position(file, 0);
|
result = file_set_position(file, 0);
|
||||||
if (!result) return {};
|
if (!result) return {};
|
||||||
|
|
||||||
file_data.data = NewArray<u8>(file_data.count, false);
|
s64 total_file_size = file_data.count;
|
||||||
|
|
||||||
|
if (add_null_terminator) {
|
||||||
|
total_file_size += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_data.data = NewArray<u8>(total_file_size, false);
|
||||||
if (file_data.data == nullptr) return {};
|
if (file_data.data == nullptr) return {};
|
||||||
|
|
||||||
s64 bytes_read = 0;
|
s64 bytes_read = 0;
|
||||||
@ -575,17 +582,21 @@ internal ArrayView<u8> read_entire_file (File file) {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (add_null_terminator) {
|
||||||
|
file_data[total_file_size-1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Assert(bytes_read == file_data.count);
|
Assert(bytes_read == file_data.count);
|
||||||
file_data.count = bytes_read;
|
file_data.count = bytes_read;
|
||||||
|
|
||||||
return file_data;
|
return file_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ArrayView<u8> read_entire_file (string file_path, bool log_errors) {
|
internal ArrayView<u8> read_entire_file (string file_path, bool add_null_terminator, bool log_errors) {
|
||||||
File f = file_open(file_path, false, false, log_errors);
|
File f = file_open(file_path, false, false, log_errors);
|
||||||
if (!file_is_valid(f)) return {};
|
if (!file_is_valid(f)) return {};
|
||||||
|
|
||||||
ArrayView<u8> file_data = read_entire_file(f);
|
ArrayView<u8> file_data = read_entire_file(f, add_null_terminator);
|
||||||
|
|
||||||
file_close(&f);
|
file_close(&f);
|
||||||
|
|
||||||
@ -1416,7 +1427,7 @@ bool Deserialize_ST_File_Enumeration (string file_path) {
|
|||||||
push_allocator(temp());
|
push_allocator(temp());
|
||||||
auto_release_temp();
|
auto_release_temp();
|
||||||
|
|
||||||
Deserializer deserializer = read_entire_file(file_path, true);
|
Deserializer deserializer = read_entire_file(file_path, false, true);
|
||||||
if (deserializer.count == 0) return false;
|
if (deserializer.count == 0) return false;
|
||||||
auto d = &deserializer;
|
auto d = &deserializer;
|
||||||
|
|
||||||
|
|||||||
@ -41,8 +41,8 @@ internal bool file_length (File file, s64* length);
|
|||||||
internal bool file_length (string file_path, s64* length);
|
internal bool file_length (string file_path, s64* length);
|
||||||
internal s64 file_current_position (File file);
|
internal s64 file_current_position (File file);
|
||||||
internal bool file_set_position (File file, s64 position);
|
internal bool file_set_position (File file, s64 position);
|
||||||
internal ArrayView<u8> read_entire_file (File file);
|
internal ArrayView<u8> read_entire_file (File file, bool add_null_terminator);
|
||||||
internal ArrayView<u8> read_entire_file (string file_path, bool log_errors=false);
|
internal ArrayView<u8> read_entire_file (string file_path, bool add_null_terminator=false, bool log_errors=false);
|
||||||
|
|
||||||
// use to_byte_view to convert ArrayView<non-u8> to ArrayView<u8>
|
// use to_byte_view to convert ArrayView<non-u8> to ArrayView<u8>
|
||||||
internal bool file_write (File* file, void* data, s64 length);
|
internal bool file_write (File* file, void* data, s64 length);
|
||||||
|
|||||||
@ -105,7 +105,9 @@ string directory_get_full_path (Thread_Group* group, Parent_Index pid, string di
|
|||||||
}
|
}
|
||||||
|
|
||||||
// go in reverse order and add together string
|
// go in reverse order and add together string
|
||||||
String_Builder* sb = new_string_builder(Arena_Reserve::Size_64K);
|
String_Builder* sb = context_builder();
|
||||||
|
reset_string_builder(sb, true);
|
||||||
|
|
||||||
for (s64 i = paths.count-1; i >= 0; i -= 1) {
|
for (s64 i = paths.count-1; i >= 0; i -= 1) {
|
||||||
append(sb, paths[i]);
|
append(sb, paths[i]);
|
||||||
append(sb, "\\");
|
append(sb, "\\");
|
||||||
|
|||||||
@ -457,7 +457,7 @@ bool Deserialize_Win32_Drives (string file_path) {
|
|||||||
push_allocator(temp());
|
push_allocator(temp());
|
||||||
auto_release_temp();
|
auto_release_temp();
|
||||||
|
|
||||||
Deserializer deserializer = read_entire_file(file_path, true);
|
Deserializer deserializer = read_entire_file(file_path, false, true);
|
||||||
if (deserializer.count == 0) return false;
|
if (deserializer.count == 0) return false;
|
||||||
auto d = &deserializer;
|
auto d = &deserializer;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user