diff --git a/cpp_lib.todo b/cpp_lib.todo index b3fe687..827977b 100644 --- a/cpp_lib.todo +++ b/cpp_lib.todo @@ -1,23 +1,26 @@ [#TODO] - [ ] Context should include links to other living thread data (+ save dead threads in debug mode) - [ ] GetUnixTimestamp for timing and rdtsc for timing. - [ ] Thread primitives (Mutex, Semaphore, etc.) - [ ] Thread Creation / Deletion [ ] Base layer and OS abstraction for Windows. (Ryan's Win32 platform layer is ~2k lines of code.) - - just implement the stuff we need + • ryan uses os_thread_launch (CreateThread) /join (WaitForSingleObject+CloseHandle)/detach (CloseHandle ?? what type?) + See: base_threads + just implement the stuff we need for: + He launches a bunch of async threads from `main_thread_base_entry_point` + • Creating / destroying threads. + • rdtsc for timing + • Thread primitives (Mutex, Semaphore, etc.) + • Thread Creation / Deletion + [ ] CreateWindow and other Windows-specific features for handling messaging. + [ ] Context should include links to other living thread data (+ save dead threads in debug mode) + [ ] push_scratch() macro. (basically an auto_release_temp) - [ ] CreateWindow + [ ] Start removing irrelevant header files (for unity build system) + [ ] ... Mouse / Keyboard inputs [*] This is the order I want to follow, because I need them in thread context. - Entry point(s) `Entry_Point_Main.cpp` -> We can have a lib_init() instead of a clear entry point for now. -> Switch from library to application once I add an entry point -> See how rjf abstracts his entry points for each platform with TCTX. - [ ] 1. setup thread-local storage via thread_static (see raddbg, base_core.h, - C_LINKAGE thread_static TCTX *tctx_thread_local; - >> Must be assigned at entry point (arena_alloc()) - >> TCTX defined in base_thread_context.h - > See Base_Thread.h + [Design Stuff] [ ] "Primary Thread" <- Main entry point thread [ ] "Secondary Thread" <- does all the heavy lifting for the first thread and synchronizes with the first. @@ -27,12 +30,17 @@ [ ] Does calling SetProcessWorkingSetSize(.., -1, -1) cause the program to crash? Why tho. [ ] Maybe we just shouldn't do this? [ ] *our* program memory usage can be calculated by Stack Size + allocations from GPAllocator + allocations from arena. + [ ] I want to be able to create new Windows (instances) of the program that can communicate with one another. + I want one program to be the "Main" and always in-tray, and the others to be "child instances" [TODO - Low priority] [ ] Fix implementation so all source is just in .cpp files (including templates), and auto-generate forward declares like Vjekoslav does. [ ] Implement Secure Arenas (with VirtualLock, wiping memory with RtlSecureZeroMemory) [ ] Way to serialize and deserialize settings in Text (I think using binary is a mistake here?). -[Project Ideas] +[Project Ideas] - order of operations: + [ ] Pushbullet replacement should make it easy to understand how data can be securely moved over the internet via a central server. + [ ] Signal replacement [ ](Graphics): How do I create a basic overlay that shows the time, date, cpu/gpu temps, frequency, memory usage all the time and responds to global hotkey to show more info + [Documentation Notes] Main inspirations for this codebase: (1) jonathan blow & jai compiler project diff --git a/lib/Base/Allocator.cpp b/lib/Base/Allocator.cpp index bc1f1b3..947d320 100644 --- a/lib/Base/Allocator.cpp +++ b/lib/Base/Allocator.cpp @@ -7,6 +7,7 @@ void* internal_alloc (s64 size) { return result; } +// #NOTE: internal_realloc does NOT copy anything! It just hands you new memory to work with! void* internal_realloc (void* memory, s64 size, s64 old_size) { Allocator allocator = get_context_allocator(); void* result = allocator.proc(Allocator_Mode::RESIZE, size, old_size, memory, allocator.data); diff --git a/lib/Base/Allocator.h b/lib/Base/Allocator.h index b85fed0..c0c4b9b 100644 --- a/lib/Base/Allocator.h +++ b/lib/Base/Allocator.h @@ -76,12 +76,16 @@ template T* NewArray (s64 count, bool initialize=true) { return memory; } -// #TODO: allocator versions of resize and delete -template T* Resize (Allocator allocator, void* memory, s64 size, s64 old_size, bool initialize=true) { +// Likely will rarely be used, if ever. See: internal_realloc +template force_inline T* Resize (Allocator allocator, void* memory, s64 size, s64 old_size, bool initialize=true) { void* result = allocator.proc(Allocator_Mode::RESIZE, size, old_size, memory, allocator.data); return result; } -// template void Delete (Allocator allocator, void* memory) { + +// There's not really any reason for this to be a template +force_inline void Delete (Allocator allocator, void* memory) { + allocator.proc(Allocator_Mode::DEALLOCATE, 0, 0, memory, allocator.data); +} // We use internal functions when we assume the user just wants to use the // current allocator on the context. diff --git a/lib/Base/Arena.cpp b/lib/Base/Arena.cpp index 09c2bc2..88ab3c7 100644 --- a/lib/Base/Arena.cpp +++ b/lib/Base/Arena.cpp @@ -5,6 +5,8 @@ constexpr u16 ARENA_DEFAULT_ALIGNMENT = CPU_REGISTER_WIDTH_BYTES; +// For arrays, use `Array`, which is backed by the general purpose allocator +// or use `ArenaArray` if you need to expand the size to an unknown size. void* arena_allocator_proc (Allocator_Mode mode, s64 requested_size, s64 old_size, void* old_memory, void* allocator_data) { Arena* arena = (Arena*)allocator_data; Assert(arena != nullptr); @@ -14,8 +16,9 @@ void* arena_allocator_proc (Allocator_Mode mode, s64 requested_size, s64 old_siz } break; case Allocator_Mode::RESIZE: { Assert(false); // DO NOT USE RESIZE WITH ARENAS! - // Either use Array, which is backed by the general purpose allocator - // or use ArenaArray if you need to expand the size. + // Or maybeeee... + // Resize should check if current_point matches the end of the old allocation? + // and resize accordingly + pass back same pointer. void* result = arena_alloc(arena, requested_size); s64 size_to_copy = old_size < requested_size ? old_size : requested_size; if (result && size_to_copy) { diff --git a/lib/Base/Arena.h b/lib/Base/Arena.h index f68a888..0ef0601 100644 --- a/lib/Base/Arena.h +++ b/lib/Base/Arena.h @@ -17,7 +17,8 @@ enum class Arena_Reserve: u8 { Size_64M = 2, Size_2G = 3, Size_64G = 4, - Size_2T = 5 + Size_2T = 5, + Size_64T = 6, }; enum class Arena_Flags: u8 { @@ -117,6 +118,8 @@ struct Auto_Reset { } }; +#define auto_release_temp() auto_release(get_temp_allocator()); + #define auto_release(x) \ Auto_Release Concat(_auto_release_guard_, __LINE__)(x) struct Auto_Release { diff --git a/lib/Base/Base_Thread_Context.h b/lib/Base/Base_Thread_Context.h index fd7fa6e..c309df3 100644 --- a/lib/Base/Base_Thread_Context.h +++ b/lib/Base/Base_Thread_Context.h @@ -21,6 +21,7 @@ struct Thread_Context { // #TODO: // Array threads_created; // maybe should be linked-list? // Thread* thread_that_created_me = nullptr; // so we can remove from above array + // Mutex thread_context_mutex; string thread_name; }; @@ -49,6 +50,6 @@ struct Push_Allocator { // Thread-local allocators: PROTOTYPING_API Allocator get_temp_allocator(); PROTOTYPING_API Allocator get_context_allocator(); -PROTOTYPING_API void reset_temp_allocator(); -PROTOTYPING_API void free_temp_allocator(); +// PROTOTYPING_API void reset_temp_allocator(); +// PROTOTYPING_API void free_temp_allocator(); diff --git a/lib/Base/Timing.cpp b/lib/Base/Timing.cpp index 6086d35..9c59971 100644 --- a/lib/Base/Timing.cpp +++ b/lib/Base/Timing.cpp @@ -1,16 +1,24 @@ -#include "Timing.h" - - #if OS_WINDOWS - +constexpr s64 FILETIME_TO_UNIX = 116444736000000000i64; f64 GetUnixTimestamp() { - constexpr s64 FILETIME_TO_UNIX = 116444736000000000i64; FILETIME fileTime; GetSystemTimePreciseAsFileTime(&fileTime); s64 ticks = ((s64)fileTime.dwHighDateTime << (s64)32) | (s64)fileTime.dwLowDateTime; return (ticks - FILETIME_TO_UNIX) / (10.0 * 1000.0 * 1000.0); } - -// #TODO: GetUnixTimestampNanoseconds - +s64 GetUnixTimestampNanoseconds() { + FILETIME fileTime; + GetSystemTimePreciseAsFileTime(&fileTime); + + s64 ticks = ((s64)fileTime.dwHighDateTime << (s64)32) + | (s64)fileTime.dwLowDateTime; // in 100ns ticks + s64 unix_time = (ticks - FILETIME_TO_UNIX); // in 100ns ticks + + s64 unix_time_nanoseconds = unix_time * 100; + + return unix_time_nanoseconds; +} +#endif +#if OS_LINUX + #endif diff --git a/lib/Base/Timing.h b/lib/Base/Timing.h deleted file mode 100644 index 0d43384..0000000 --- a/lib/Base/Timing.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "Base.h" - -f64 GetUnixTimestamp(); diff --git a/src/OS_Win32.cpp b/src/OS_Win32.cpp index 5fa2d4f..9c92525 100644 --- a/src/OS_Win32.cpp +++ b/src/OS_Win32.cpp @@ -146,10 +146,50 @@ internal void Win32_Entry_Point (int argc, WCHAR **argv) { info->working_path = wide_to_utf8(memory, length); Assert(is_valid(info->working_path)); } + // [ ] Get Working directory (info->working_path) // [ ] GetEnvironmentStringsW - + // temp_reset(); printf("Hello there!\n\n"); // See: main_thread_base_entry_point Main_Entry_Point(argc, argv); -} \ No newline at end of file +} + +// OS_Thread stuff + + +// Individual Threads +// os_thread_create +// os_thread_join +// os_thread_detach + +// Thread Group API? + +// mutexes +// internal Mutex mutex_alloc(void) {return os_mutex_alloc();} +// internal void mutex_release(Mutex mutex) {os_mutex_release(mutex);} +// internal void mutex_take(Mutex mutex) {os_mutex_take(mutex);} +// internal void mutex_drop(Mutex mutex) {os_mutex_drop(mutex);} +//- rjf: condition variables + +// internal CondVar cond_var_alloc(void) {return os_cond_var_alloc();} +// internal void cond_var_release(CondVar cv) {os_cond_var_release(cv);} +// internal B32 cond_var_wait(CondVar cv, Mutex mutex, U64 endt_us) {return os_cond_var_wait(cv, mutex, endt_us);} +// internal B32 cond_var_wait_rw(CondVar cv, RWMutex mutex_rw, B32 write_mode, U64 endt_us) {return os_cond_var_wait_rw(cv, mutex_rw, write_mode, endt_us);} +// internal void cond_var_signal(CondVar cv) {os_cond_var_signal(cv);} +// internal void cond_var_broadcast(CondVar cv) {os_cond_var_broadcast(cv);} + +//- rjf: cross-process semaphores + +// internal Semaphore semaphore_alloc(U32 initial_count, U32 max_count, String8 name) {return os_semaphore_alloc(initial_count, max_count, name);} +// internal void semaphore_release(Semaphore semaphore) {os_semaphore_release(semaphore);} +// internal Semaphore semaphore_open(String8 name) {return os_semaphore_open(name);} +// internal void semaphore_close(Semaphore semaphore) {os_semaphore_close(semaphore);} +// internal B32 semaphore_take(Semaphore semaphore, U64 endt_us) {return os_semaphore_take(semaphore, endt_us);} +// internal void semaphore_drop(Semaphore semaphore) {os_semaphore_drop(semaphore);} + +//- rjf: barriers + +// internal Barrier barrier_alloc(U64 count) {return os_barrier_alloc(count);} +// internal void barrier_release(Barrier barrier) {os_barrier_release(barrier);} +// internal void barrier_wait(Barrier barrier) {os_barrier_wait(barrier);}