diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..882d147 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/base"] + path = src/base + url = https://github.com/Tenari/base.git diff --git a/README.md b/README.md new file mode 100644 index 0000000..e777f85 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ + +git clone --recurse-submodules https://github.com/Tenari/TUI-App-Template.git + +This repo depends on my base layer. + +see [here](https://git-scm.com/book/en/v2/Git-Tools-Submodules) for submodules usage details diff --git a/src/base b/src/base new file mode 160000 index 0000000..4208566 --- /dev/null +++ b/src/base @@ -0,0 +1 @@ +Subproject commit 42085666e99cd016f1720f1016289f8ced28424f diff --git a/src/base/all.h b/src/base/all.h deleted file mode 100644 index d8f73b0..0000000 --- a/src/base/all.h +++ /dev/null @@ -1,691 +0,0 @@ -// good base layer overview https://www.youtube.com/watch?v=bUOOaXf9qIM -#ifndef BASE_ALL_H -#define BASE_ALL_H - -///// Context Cracking -// Development Settings -#if !defined(ENABLE_ASSERT) -# define ENABLE_ASSERT 1 -#endif -#if !defined(ENABLE_SANITIZER) -# define ENABLE_SANITIZER 0 -#endif -#if !defined(ENABLE_MANUAL_PROFILE) -# define ENABLE_MANUAL_PROFILE 0 -#endif -#if !defined(ENABLE_AUTO_PROFILE) -# define ENABLE_AUTO_PROFILE 0 -#endif - -#if defined(ENABLE_ANY_PROFILE) -# error user should not configure ENABLE_ANY_PROFILE -#endif - -#if ENABLE_MANUAL_PROFILE || ENABLE_AUTO_PROFILE -# define ENABLE_ANY_PROFILE 1 -#else -# define ENABLE_ANY_PROFILE 0 -#endif - -// Untangle Compiler, OS & Architecture -#if defined(__clang__) -# define COMPILER_CLANG 1 - -# if defined(_WIN32) -# define OS_WINDOWS 1 -# elif defined(__gnu_linux__) -# define OS_LINUX 1 -# elif defined(__APPLE__) && defined(__MACH__) -# define OS_MAC 1 -# else -# error missing OS detection -# endif - -# if defined(__amd64__) -# define ARCH_X64 1 -// TODO verify this works on clang -# elif defined(__i386__) -# define ARCH_X86 1 -// TODO verify this works on clang -# elif defined(__arm__) -# define ARCH_ARM 1 -// TODO verify this works on clang -# elif defined(__aarch64__) -# define ARCH_ARM64 1 -# else -# error missing ARCH detection -# endif - -#elif defined(_MSC_VER) -# define COMPILER_CL 1 - -# if defined(_WIN32) -# define OS_WINDOWS 1 -# else -# error missing OS detection -# endif - -# if defined(_M_AMD64) -# define ARCH_X64 1 -# elif defined(_M_I86) -# define ARCH_X86 1 -# elif defined(_M_ARM) -# define ARCH_ARM 1 -// TODO ARM64? -# else -# error missing ARCH detection -# endif - -#elif defined(__GNUC__) -# define COMPILER_GCC 1 - -# if defined(_WIN32) -# define OS_WINDOWS 1 -# elif defined(__gnu_linux__) -# define OS_LINUX 1 -# elif defined(__APPLE__) && defined(__MACH__) -# define OS_MAC 1 -# else -# error missing OS detection -# endif - -# if defined(__amd64__) -# define ARCH_X64 1 -# elif defined(__i386__) -# define ARCH_X86 1 -# elif defined(__arm__) -# define ARCH_ARM 1 -# elif defined(__aarch64__) -# define ARCH_ARM64 1 -# else -# error missing ARCH detection -# endif - -#else -# error no context cracking for this compiler -#endif - -#if !defined(COMPILER_CL) -# define COMPILER_CL 0 -#endif -#if !defined(COMPILER_CLANG) -# define COMPILER_CLANG 0 -#endif -#if !defined(COMPILER_GCC) -# define COMPILER_GCC 0 -#endif -#if !defined(OS_WINDOWS) -# define OS_WINDOWS 0 -#endif -#if !defined(OS_LINUX) -# define OS_LINUX 0 -#endif -#if !defined(OS_MAC) -# define OS_MAC 0 -#endif -#if !defined(ARCH_X64) -# define ARCH_X64 0 -#endif -#if !defined(ARCH_X86) -# define ARCH_X86 0 -#endif -#if !defined(ARCH_ARM) -# define ARCH_ARM 0 -#endif -#if !defined(ARCH_ARM64) -# define ARCH_ARM64 0 -#endif - -// Language -#if defined(__cplusplus) -# define LANG_CXX 1 -#else -# define LANG_C 1 -#endif - -#if !defined(LANG_CXX) -# define LANG_CXX 0 -#endif -#if !defined(LANG_C) -# define LANG_C 0 -#endif - -// Profiler -#if !defined(PROFILER_SPALL) -# define PROFILER_SPALL 0 -#endif - -// Determine Intrinsics Mode -#if OS_WINDOWS -# if COMPILER_CL || COMPILER_CLANG -# define INTRINSICS_MICROSOFT 1 -# endif -#endif - -#if !defined(INTRINSICS_MICROSOFT) -# define INTRINSICS_MICROSOFT 0 -#endif - -// Setup Pointer Size Macro -#if ARCH_X64 || ARCH_ARM64 -# define ARCH_ADDRSIZE 64 -#else -# define ARCH_ADDRSIZE 32 -#endif - -///// MACROS -#define global static -#define internal static -#define fn static - -#define arrayLen(a) (sizeof(a)/sizeof(*(a))) - -#define intFromPtr(p) (U64)((U8*)p - (U8*)0) -#define ptrFromInt(n) (void*)((U8*)0 + (n)) - -#define stmnt(S) do{ S }while(0) - -#if !defined(assertBreak) -# define assertBreak() (*(volatile int*)0 = 0) -#endif - -#ifndef offsetof -# define offsetof(st, m) ((size_t)&(((st*)0)->m)) -#endif - -#if ENABLE_ASSERT -# define assert(c) stmnt( if (!(c)){ assertBreak(); } ) -#else -# define assert(c) -#endif - -#define ToBool(x) ((x) != 0) - -#define KB(x) ((x) << 10) -#define MB(x) ((x) << 20) -#define GB(x) ((x) << 30) -#define TB(x) ((u64)(x) << 40llu) - -#include -#define MemoryCopy(d,s,z) memmove((d), (s), (z)) -#define MemoryCopyStruct(d,s) MemoryCopy((d),(s), Min(sizeof(*(d)) , sizeof(*(s)))) -#define MemoryZero(d,z) memset((d), 0, (z)) -#define MemoryZeroStruct(d,s) MemoryZero((d),sizeof(s)) -#define Min(a,b) (((a)<(b))?(a):(b)) -#define Max(a,b) (((a)>(b))?(a):(b)) -#define Abs(x) (((x)<0)?((x)*-1):(x)) - -#define SetFlag(flags, bit) ((flags) |= (1ULL << (bit))) -#define ClearFlag(flags, bit) ((flags) &= ~(1ULL << (bit))) -#define ToggleFlag(flags, bit) ((flags) ^= (1ULL << (bit))) -#define CheckFlag(flags, bit) (((flags) >> (bit)) & 1ULL) - -#define QueuePush(f,l,n) (((f)==NULL) ? ((f)=(l)=(n)) : ((l)->next=(n),(l)=(n),(n)->next = NULL)) - -#define DEFAULT_ALIGNMENT sizeof(void*) -#define isPowerOfTwo(x) ((x & (x-1)) == 0) - -#define XYToPos(x, y, w) ((u32)(((u32)(x)) + (((u32)(y)) * (w)))) - -#if COMPILER_MSVC -# define thread_static __declspec(thread) -#elif COMPILER_CLANG || COMPILER_GCC -# define thread_static __thread -#else -# error thread_static not defined for this compiler. -#endif - -// only valid if there's an in-scope variable bool `debug_mode` -#define dbg(fmt, ...) osDebugPrint(debug_mode, fmt, ##__VA_ARGS__) - -///// SYSTEM INCLUDES I always want -#include -#include - -///// TYPES -// integer types -typedef unsigned char u8; -typedef signed char i8; -typedef unsigned short u16; -typedef short i16; -typedef unsigned int u32; -typedef int i32; -typedef unsigned long long u64; -typedef signed long long i64; -typedef char * usize; -typedef char * ptr; -typedef const char* str; - -// Floating point types -typedef float f32; -typedef double f64; - -//typedef long double f80; only returning 8 bytes on my mac for some reason -/* - printf("u8 %d\n", (int)sizeof(u8) * 8); - printf("i8 %d\n", (int)sizeof(i8) * 8); - printf("u16 %d\n", (int)sizeof(u16) * 8); - printf("i16 %d\n", (int)sizeof(i16) * 8); - printf("u32 %d\n", (int)sizeof(u32) * 8); - printf("i32 %d\n", (int)sizeof(i32) * 8); - printf("u64 %d\n", (int)sizeof(u64) * 8); - printf("i64 %d\n", (int)sizeof(i64) * 8); - printf("usize %d\n", (int)sizeof(usize) * 8); - - printf("f32 %d\n", (int)sizeof(f32) * 8); - printf("f64 %d\n", (int)sizeof(f64) * 8); - printf("f80 %d\n", (int)sizeof(f80) * 8); -*/ - -// Boolean types -typedef u8 b8; -typedef u32 b32; -#ifndef bool -# define bool b8 -#endif - -#define true 1 -#define false 0 - -// Structs -typedef struct Arena { - u8* memory; - u64 max; - u64 alloc_position; - u64 commit_position; - b8 static_size; -} Arena; - -typedef struct PtrArray { - u32 length; - u32 capacity; - ptr* items; -} PtrArray; - -typedef struct u8List { - u32 length; - u32 capacity; - u8* items; -} u8List; - -typedef struct String { - u32 length; - u32 capacity; - ptr bytes; -} String; - -typedef struct StringUTF16Const { - u16* string; - u64 size; -} StringUTF16Const; - -typedef enum Utf8Character { - Utf8CharacterAscii, - Utf8CharacterTwoByte, - Utf8CharacterThreeByte, - Utf8CharacterFourByte, - Utf8Character_Count, -} Utf8Character; - -typedef enum FieldType { - FieldTypeU8, - FieldTypeU16, - FieldTypeU32, - FieldTypeFloat, - FieldTypeString, - FieldTypeEnum, - FieldType_Count, -} FieldType; - -typedef struct FieldDescriptor { - str name; - FieldType type; - size_t offset; - int width; // column width for display - str* enum_vals; -} FieldDescriptor; - -typedef struct TableDrawInfo { - u32 x_offset; - u32 y_offset; - u32 rows; - u32 cols; -} TableDrawInfo; - -typedef struct Box { - u32 x; - u32 y; - u32 height; - u32 width; -} Box; - -typedef struct Dim2 { - u16 height; - u16 width; -} Dim2; - -typedef struct Pos2 { - u16 x; - u16 y; -} Pos2; - -typedef struct Pos2u8 { - u8 x; - u8 y; -} Pos2u8; - -typedef union Range1u32 Range1u32; -union Range1u32 -{ - struct - { - u32 min; - u32 max; - }; - u32 v[2]; -}; - -typedef union Range1i32 Range1i32; -union Range1i32 -{ - struct - { - i32 min; - i32 max; - }; - i32 v[2]; -}; - -typedef union Range1u64 Range1u64; -union Range1u64 -{ - struct - { - u64 min; - u64 max; - }; - u64 v[2]; -}; - -typedef union Range1i64 Range1i64; -union Range1i64 -{ - struct - { - i64 min; - i64 max; - }; - i64 v[2]; -}; - -typedef union Range1f32 Range1f32; -union Range1f32 -{ - struct - { - f32 min; - f32 max; - }; - f32 v[2]; -}; - -#if OS_WINDOWS -# define WIN32_LEAN_AND_MEAN -# include -# include -# include -# include -# include -# include -# include - typedef struct { - DWORD input_mode; - DWORD output_mode; - } TermIOs; - // networking shim for windows -#ifndef POLLIN -# define POLLIN 0x0001 -# define POLLPRI 0x0002 -# define POLLOUT 0x0004 -# define POLLERR 0x0008 -# define POLLHUP 0x0010 -# define POLLNVAL 0x0020 - - typedef struct pollfd { - SOCKET fd; - short events; - short revents; - } pollfd_t; -#endif - - typedef int nfds_t; - - int poll(struct pollfd *fds, nfds_t nfds, int timeout); -#else -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - typedef struct termios TermIOs; -#endif - -typedef struct Barrier { - u64 a[1]; -} Barrier; - -typedef struct CondVar { - u64 a[1]; -} CondVar; - -typedef struct Thread { - pthread_t thread; -} Thread; - -typedef struct Mutex { - pthread_mutex_t mutex; -} Mutex; - -typedef struct Cond { - pthread_cond_t cond; -} Cond; - -#define M_SCRATCH_SIZE KB(16) -typedef struct ScratchFreeListNode ScratchFreeListNode; -struct ScratchFreeListNode { - ScratchFreeListNode* next; - u32 index; -}; - -typedef struct ScratchMem { - Arena arena; - u32 index; - u64 pos; -} ScratchMem; - -typedef struct LaneCtx { - u64 lane_idx; - u64 lane_count; - Barrier barrier; - u64 *broadcast_memory; -} LaneCtx; - -typedef struct ThreadContext { - Arena arena; // scratch - u32 max_created; - ScratchFreeListNode* free_list; - LaneCtx lane_ctx; -} ThreadContext; - -///// HARDCODED GLOBALS -global const u64 MAX_u64 = 0xffffffffffffffffull; -global const u32 MAX_u32 = 0xffffffff; -global const u16 MAX_u16 = 0xffff; -global const u8 MAX_u8 = 0xff; -#define EULERS_E (2.71828) -#define PI (3.14159265358979323846) - -///// CUSTOM ENTRY POINT -/* TODO? -fn void mainThreadBaseEntryPoint(i32 argc, char **argv); -fn void asyncThreadEntryPoint(void *params); -fn void supplement_thread_base_entry_point(void (*entry_point)(void *params), void *params); -fn u64 update_tick_idx(void); -fn b32 update(void); -*/ - -///// MATH -fn Range1u64 range1u64Create(u64 min, u64 max); -fn Range1u64 mRangeFromNIdxMCount(u64 n_idx, u64 n_count, u64 m_count); -fn void u32Quicksort(u32 arr[], u32 low, u32 high); -fn void u32ReverseArray(u32 arr[], u32 size); - -///// MEMORY (Arenas) -#define ARENA_MAX GB(1) -// this was an evil bug to figure out -#if defined(OS_MAC) -# define ARENA_COMMIT_SIZE KB(16) -#else -# define ARENA_COMMIT_SIZE KB(8) -#endif - -fn void* arenaAlloc(Arena* arena, u64 size); -fn void* arenaAllocZero(Arena* arena, u64 size); -fn void arenaDealloc(Arena* arena, u64 size); -fn void arenaDeallocTo(Arena* arena, u64 pos); -fn void* arenaRaise(Arena* arena, void* ptr, u64 size); -fn void* arenaAllocArraySized(Arena* arena, u64 elem_size, u64 count); -#define arenaAllocArray(arena, elem_type, count) arenaAllocArraySized(arena, sizeof(elem_type), count) - -fn void arenaInit(Arena* arena); -fn void arenaInitSized(Arena* arena, u64 max); -fn void arenaClear(Arena* arena); -fn void arenaFree(Arena* arena); - -ScratchMem scratchGet(void); -void scratchReset(ScratchMem* scratch); -void scratchReturn(ScratchMem* scratch); - -///// STRINGS -#define ASCII_TAB (9) -#define ASCII_LINE_FEED (10) -#define ASCII_RETURN (13) -#define ASCII_ESCAPE (27) -#define ASCII_DEL (127) -#define ASCII_BACKSPACE (8) - -fn bool stringsEq(String* a, String* b); -fn bool cStringEqString(str a, String* b); -fn Utf8Character classifyUtf8Character(u8 c); -fn bool isUtf8Ascii(u8 c); -fn bool isUtf8TwoByte(u8 c); -fn bool isUtf8ThreeByte(u8 c); -fn bool isUtf8FourByte(u8 c); -fn u8 lowerAscii(u8 c); -fn u8 upperAscii(u8 c); -fn StringUTF16Const str16FromStr8(Arena* a, String string); -fn bool isAlphaUnderscoreSpace(u8 c); -fn bool isSimplePrintable(u8 c); - -///// OS-wrapped apis -void osInit(); -void* osThreadContextGet(); -void osThreadContextSet(void* ctx); -bool osThreadJoin(Thread handle, u64 endt_us); - -fn Barrier osBarrierAlloc(u64 count); -fn void osBarrierRelease(Barrier barrier); -fn void osBarrierWait(Barrier barrier); - -// Memory -fn void* osMemoryReserve(u64 size); -fn void osMemoryCommit(void* memory, u64 size); -fn void osMemoryDecommit(void* memory, u64 size); -fn void osMemoryRelease(void* memory, u64 size); -fn u64 osTimeMicrosecondsNow(); -fn void osSleepMicroseconds(u32 t); - -// Files -fn bool osFileExists(String filename); -fn String osFileRead(Arena* arena, ptr filepath); -fn bool osFileCreate(String filename); -fn bool osFileCreateWrite(String filename, String data); -fn bool osFileWrite(String filename, String data); - -fn void osDebugPrint(bool debug_mode, const char* format, ...); - -// Tui stuff -TermIOs osStartTUI(bool blocking); -fn void osEndTUI(TermIOs old_terminal_attributes); -fn Dim2 osGetTerminalDimensions(); -void osBlitToTerminal(ptr writeable_output_ansi_string, i64 count); -void osReadConsoleInput(u8* buffer, u32 len); - -// network stuff -bool osInitNetwork(); -i32 osLanIPAddress(); - -///// Basic THREAD synchronization apis -Thread spawnThread(void * (*threadFn)(void *), void* thread_arg); -Mutex newMutex(); -Cond newCond(); -void lockMutex(Mutex* m); -void unlockMutex(Mutex* m); -void signalCond(Cond* cond); -void waitForCondSignal(Cond* cond, Mutex* mutex); - -///// Multi-Core by Default ThreadContext stuff -void tctxInit(ThreadContext* ctx); -void tctxFree(ThreadContext* ctx); -fn ThreadContext *tctxSelected(void); - -ScratchMem tctxScratchGet(ThreadContext* ctx); -void tctxScratchReset(ThreadContext* ctx, ScratchMem* scratch); -void tctxScratchReturn(ThreadContext* ctx, ScratchMem* scratch); - -fn LaneCtx tctxSetLaneCtx(LaneCtx lane_ctx); -fn void tctxLaneBarrierWait(void *broadcast_ptr, u64 broadcast_size, u64 broadcast_src_lane_idx); -#define LaneIdx() (tctxSelected()->lane_ctx.lane_idx) -#define LaneCount() (tctxSelected()->lane_ctx.lane_count) -#define LaneFromTaskIdx(idx) ((idx)%LaneCount()) -#define LaneCtx(ctx) tctxSetLaneCtx((ctx)) -#define LaneSync() tctxLaneBarrierWait(0, 0, 0) -#define LaneSyncu64(pointer, src_lane_idx) tctxLaneBarrierWait((pointer), sizeof(*(pointer)), (src_lane_idx)) -#define LaneRange(count) mRangeFromNIdxMCount(LaneIdx(), LaneCount(), (count)) - -///// StringChunk stuff -#ifndef STRING_CHUNK_PAYLOAD_SIZE -#define STRING_CHUNK_PAYLOAD_SIZE (64 - sizeof(StringChunk*)) -#endif - -typedef struct StringChunk { - struct StringChunk *next; // essentially a header, followed by a fixed maximum str bytes -} StringChunk; - -typedef struct StringChunkList { - StringChunk* first; - StringChunk* last; - u64 count; - u64 total_size; -} StringChunkList; - -typedef struct StringArena { - Arena a; - StringChunk* first_free_str_chunk; - Mutex mutex; -} StringArena; - -fn StringChunkList allocStringChunkList(StringArena* a, String string); -fn void releaseStringChunkList(StringArena* a, StringChunkList* list); -fn String stringChunkToString(Arena* a, StringChunkList list); -fn void stringChunkListAppend(StringArena* a, StringChunkList* list, String string); -fn void stringChunkListDeleteLast(StringArena* a, StringChunkList* list); -fn StringChunkList stringChunkListInit(StringArena* a); -fn void stringChunkCopyToBuffer(StringChunkList* list, u8* buffer, u32 len); - -#endif// BASE_ALL_H diff --git a/src/base/entry.c b/src/base/entry.c deleted file mode 100644 index c38c5ef..0000000 --- a/src/base/entry.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "all.h" - -fn void mainThreadBaseEntryPoint(i32 argc, char **argv) { - Thread* async_threads = 0; - u64 lane_broadcast_val = 0; - { - u32 num_main_threads = 1; - u32 num_async_threads = 12;//TODO: os_get_system_info()->logical_processor_count; - u32 num_main_threads_clamped = Min(num_async_threads, num_main_threads); - num_async_threads -= num_main_threads_clamped; - String num_async_threads_string = cmd_line_string(&cmdline, str8_lit("async_thread_count")); - if(num_async_threads_string.size != 0) - { - try_u64_from_str8_c_rules(num_async_threads_string, &num_async_threads); - } - num_async_threads = Max(1, num_async_threads); - Barrier barrier = barrier_alloc(num_async_threads); - LaneCtx *lane_ctxs = push_array(scratch.arena, LaneCtx, num_async_threads); - async_threads_count = num_async_threads; - async_threads = push_array(scratch.arena, Thread, async_threads_count); - for EachIndex(idx, num_async_threads) - { - lane_ctxs[idx].lane_idx = idx; - lane_ctxs[idx].lane_count = async_threads_count; - lane_ctxs[idx].barrier = barrier; - lane_ctxs[idx].broadcast_memory = &lane_broadcast_val; - async_threads[idx] = thread_launch(async_thread_entry_point, &lane_ctxs[idx]); - } - } - - //- rjf: call into entry point - entry_point(&cmdline); - - //- rjf: join async threads - ins_atomic_u32_inc_eval(&global_async_exit); - cond_var_broadcast(async_tick_start_cond_var); - for EachIndex(idx, async_threads_count) - { - thread_join(async_threads[idx], max_U64); - } -} - -fn void asyncThreadEntryPoint(void *params) { -} - diff --git a/src/base/impl.c b/src/base/impl.c deleted file mode 100644 index b2c13fd..0000000 --- a/src/base/impl.c +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef BASE_IMPL_C -#define BASE_IMPL_C - -#include "math.c" -#include "os.c" -#include "memory.c" -#include "serialize.c" -#include "string.c" -#include "tctx.c" -#include "thread.c" -#include "string_chunk.c" - -#endif // BASE_IMPL_C diff --git a/src/base/linux_os.c b/src/base/linux_os.c deleted file mode 100644 index b3f6f4b..0000000 --- a/src/base/linux_os.c +++ /dev/null @@ -1,139 +0,0 @@ -#include -#define _POSIX_C_SOURCE 200809L -#include -#include -#include -#include -#include -#include -#include "all.h" - -global pthread_barrier_t linux_thread_barrier; - -fn Barrier osBarrierAlloc(u64 count) { - pthread_barrier_init(&linux_thread_barrier, NULL, count); - Barrier result = {(u64)&linux_thread_barrier}; - return result; -} - -fn void osBarrierRelease(Barrier barrier) { - pthread_barrier_t* addr = (pthread_barrier_t*)barrier.a[0]; - pthread_barrier_destroy(addr); -} - -fn void osBarrierWait(Barrier barrier) { - pthread_barrier_t* addr = (pthread_barrier_t*)barrier.a[0]; - pthread_barrier_wait(addr); -} - -// Time -fn u64 osTimeMicrosecondsNow() { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return ((u64)ts.tv_sec * 1000000) + ((u64)ts.tv_nsec / 1000000); -} - -#define MICROSECONDS_PER_SECOND 1000000 -#define NANOSECONDS_PER_MICROSECOND 1000 -fn void osSleepMicroseconds(u32 t) { - struct timespec ts = { t / MICROSECONDS_PER_SECOND, (t % MICROSECONDS_PER_SECOND)*NANOSECONDS_PER_MICROSECOND }; - nanosleep(&ts, NULL); -} - -// Files -fn bool osFileExists(String filename) { - bool result = access((str)filename.bytes, F_OK) == 0; - return result; -} - -fn String osFileRead(Arena* arena, ptr filepath) { - struct stat st; - stat(filepath, &st); - String result = { st.st_size, st.st_size, 0 }; - result.bytes = arenaAlloc(arena, st.st_size); - - size_t handle = open(filepath, O_RDWR, S_IRUSR | S_IRGRP | S_IROTH); - read(handle, result.bytes, st.st_size); - close(handle); - - return result; -} - -fn bool osFileCreate(String filename) { - /* - M_Scratch scratch = scratch_get(); - string nt = str_copy(&scratch.arena, filename); - bool result = true; - size_t handle = open((const char*) nt.str, O_RDWR | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH); - if (handle == -1) { - result = false; - } - scratch_return(&scratch); - close(handle); - return true; - */ - bool result = true; - size_t handle = open((str)filename.bytes, O_RDWR | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH); - if (handle == -1) { - result = false; - } - if (close(handle) == -1) { - result = false; - } - return result; -} - -fn bool osFileCreateWrite(String filename, String data) { - /* - M_Scratch scratch = scratch_get(); - string nt = str_copy(&scratch.arena, filename); - b32 result = true; - size_t handle = - open((const char*) nt.str, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IRGRP | S_IROTH); - if (handle == -1) result = false; - write(handle, data.str, data.size); - close(handle); - scratch_return(&scratch); - return result; - */ - bool result = true; - size_t handle = open( - (str)filename.bytes, - O_RDWR | O_CREAT | O_TRUNC, - S_IRUSR | S_IRGRP | S_IROTH - ); - if (handle == -1) result = false; - write(handle, data.bytes, data.length); - close(handle); - return result; -} - -fn bool osFileWrite(String filename, String data) { - /* - M_Scratch scratch = scratch_get(); - string nt = str_copy(&scratch.arena, filename); - b32 result = true; - size_t handle = - open((const char*) nt.str, O_RDWR | O_TRUNC, S_IRUSR | S_IRGRP | S_IROTH); - if (handle == -1) result = false; - write(handle, data.str, data.size); - close(handle); - */ - bool result = true; - size_t handle = open((str) filename.bytes, O_RDWR | O_TRUNC, S_IRUSR | S_IRGRP | S_IROTH); - if (handle == -1) result = false; - write(handle, data.bytes, data.length); - close(handle); - return result; -} - - -// Misc -fn void osDebugPrint(bool debug_mode, const char * format, ... ) { - if (debug_mode) { - va_list args; - va_start(args, format); - vprintf(format, args); - va_end(args); - } -} diff --git a/src/base/mac_os.c b/src/base/mac_os.c deleted file mode 100644 index ede0437..0000000 --- a/src/base/mac_os.c +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "all.h" -#include "pthread_barrier.h" - -global pthread_barrier_t macos_thread_barrier; - -fn Barrier osBarrierAlloc(u64 count) { - pthread_barrier_init(&macos_thread_barrier, NULL, count); - Barrier result = {(u64)&macos_thread_barrier}; - return result; -} - -fn void osBarrierRelease(Barrier barrier) { - pthread_barrier_t* addr = (pthread_barrier_t*)barrier.a[0]; - pthread_barrier_destroy(addr); -} - -fn void osBarrierWait(Barrier barrier) { - pthread_barrier_t* addr = (pthread_barrier_t*)barrier.a[0]; - pthread_barrier_wait(addr); -} - -// Time -fn u64 osTimeMicrosecondsNow() { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC_RAW, &ts); - return ((u64)ts.tv_sec * 1000000) + ((u64)ts.tv_nsec / 1000000); -} - -fn void osSleepMicroseconds(u32 t) { - usleep(t); -} - -// Files -fn bool osFileExists(String filename) { - bool result = access((str)filename.bytes, F_OK) == 0; - return result; -} - -fn String osFileRead(Arena* arena, ptr filepath) { - struct stat st; - stat(filepath, &st); - String result = { st.st_size, st.st_size, 0 }; - result.bytes = arenaAlloc(arena, st.st_size); - - size_t handle = open(filepath, O_RDWR, S_IRUSR | S_IRGRP | S_IROTH); - read(handle, result.bytes, st.st_size); - close(handle); - - return result; -} - -fn bool osFileCreate(String filename) { - /* - M_Scratch scratch = scratch_get(); - string nt = str_copy(&scratch.arena, filename); - bool result = true; - size_t handle = open((const char*) nt.str, O_RDWR | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH); - if (handle == -1) { - result = false; - } - scratch_return(&scratch); - close(handle); - return true; - */ - bool result = true; - size_t handle = open((str)filename.bytes, O_RDWR | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH); - if (handle == -1) { - result = false; - } - if (close(handle) == -1) { - result = false; - } - return result; -} - -fn bool osFileCreateWrite(String filename, String data) { - /* - M_Scratch scratch = scratch_get(); - string nt = str_copy(&scratch.arena, filename); - b32 result = true; - size_t handle = - open((const char*) nt.str, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IRGRP | S_IROTH); - if (handle == -1) result = false; - write(handle, data.str, data.size); - close(handle); - scratch_return(&scratch); - return result; - */ - bool result = true; - size_t handle = open( - (str)filename.bytes, - O_RDWR | O_CREAT | O_TRUNC, - S_IRUSR | S_IRGRP | S_IROTH - ); - if (handle == -1) result = false; - write(handle, data.bytes, data.length); - close(handle); - return result; -} - -fn bool osFileWrite(String filename, String data) { - /* - M_Scratch scratch = scratch_get(); - string nt = str_copy(&scratch.arena, filename); - b32 result = true; - size_t handle = - open((const char*) nt.str, O_RDWR | O_TRUNC, S_IRUSR | S_IRGRP | S_IROTH); - if (handle == -1) result = false; - write(handle, data.str, data.size); - close(handle); - */ - bool result = true; - size_t handle = open((str) filename.bytes, O_RDWR | O_TRUNC, S_IRUSR | S_IRGRP | S_IROTH); - if (handle == -1) result = false; - write(handle, data.bytes, data.length); - close(handle); - return result; -} - - -// Misc -fn void osDebugPrint(bool debug_mode, const char * format, ... ) { - if (debug_mode) { - va_list args; - va_start(args, format); - vprintf(format, args); - va_end(args); - } -} diff --git a/src/base/math.c b/src/base/math.c deleted file mode 100644 index 1035af0..0000000 --- a/src/base/math.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "all.h" - -fn Range1u64 range1u64Create(u64 min, u64 max) { - Range1u64 result = { - .min = min, - .max = max - }; - if (result.min > result.max) { - result.max = min; - result.min = max; - } - return result; -} - -fn Range1u64 mRangeFromNIdxMCount(u64 n_idx, u64 n_count, u64 m_count) { - u64 main_idxes_per_lane = m_count / n_count; - u64 leftover_idxes_count = m_count - main_idxes_per_lane * n_count; - u64 leftover_idxes_before_this_lane_count = Min(n_idx, leftover_idxes_count); - u64 lane_base_idx = n_idx*main_idxes_per_lane + leftover_idxes_before_this_lane_count; - u64 lane_base_idx__clamped = Min(lane_base_idx, m_count); - u64 lane_opl_idx = lane_base_idx__clamped + main_idxes_per_lane + ((n_idx < leftover_idxes_count) ? 1 : 0); - u64 lane_opl_idx__clamped = Min(lane_opl_idx, m_count); - Range1u64 result = range1u64Create(lane_base_idx__clamped, lane_opl_idx__clamped); - return result; -} - -void u32Swap(u32* a, u32* b) { - int t = *a; - *a = *b; - *b = t; -} - -u32 u32ArrPartition(u32 arr[], u32 low, u32 high) { - u32 pivot = arr[high]; - u32 i = low - 1; - - for (u32 j = low; j < high; j++) { - if (arr[j] < pivot) { - i++; - u32Swap(&arr[i], &arr[j]); - } - } - u32Swap(&arr[i + 1], &arr[high]); - return i + 1; -} - -fn void u32Quicksort(u32 arr[], u32 low, u32 high) { - if (low < high) { - u32 pi = u32ArrPartition(arr, low, high); - if (pi != 0) { - u32Quicksort(arr, low, pi - 1); - } - u32Quicksort(arr, pi + 1, high); - } -} - -fn void u32ReverseArray(u32 arr[], u32 size) { - u32 start = 0; - u32 end = size - 1; - while (start < end) { - u32 temp = arr[start]; - arr[start] = arr[end]; - arr[end] = temp; - start++; - end--; - } -} - diff --git a/src/base/memory.c b/src/base/memory.c deleted file mode 100644 index b0655ac..0000000 --- a/src/base/memory.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "all.h" - -fn u64 alignForward(u64 pointer, u64 align) { - u64 p, modulo; - assert(isPowerOfTwo(align)); - p = pointer; - // Same as (p % a) but faster as 'a' is a power of two - modulo = p & (align-1); - if (modulo != 0) { - // If 'p' address is not aligned, push the address to the - // next value which is aligned - p += align - modulo; - } - return p; -} - -fn void* arenaAlloc(Arena* arena, u64 size) { - void* memory = 0; - size = alignForward(size, DEFAULT_ALIGNMENT); - if (arena->alloc_position + size > arena->commit_position) { - if (!arena->static_size) { - u64 commit_size = size; - - commit_size += ARENA_COMMIT_SIZE - 1; - commit_size -= commit_size % ARENA_COMMIT_SIZE; - - if (arena->commit_position < arena->max) { - osMemoryCommit(arena->memory + arena->commit_position, commit_size); - arena->commit_position += commit_size; - } else { - assert(0 && "Arena is out of memory"); - } - } else { - assert(0 && "Static-Size Arena is out of memory"); - } - } - - memory = arena->memory + arena->alloc_position; - arena->alloc_position += size; - return memory; -} - -fn void* arenaAllocZero(Arena* a, u64 size) { - void* result = arenaAlloc(a, size); - MemoryZero(result, size); - return result; -} - -fn void* arenaAllocArraySized(Arena* arena, u64 elem_size, u64 count) { - return arenaAlloc(arena, elem_size * count); -} - -fn void arenaDealloc(Arena* arena, u64 size) { - if (size > arena->alloc_position) size = arena->alloc_position; - arena->alloc_position -= size; -} - -fn void arenaInit(Arena* arena) { - MemoryZeroStruct(arena, Arena); - arena->max = ARENA_MAX; - arena->memory = osMemoryReserve(arena->max); - arena->alloc_position = 0; - arena->commit_position = 0; - arena->static_size = false; -} - -// WARNING: segfault problems with this approach -fn void arenaInitStatic(Arena* arena, u64 max) { - MemoryZeroStruct(arena, Arena); - arena->max = max; - arena->memory = osMemoryReserve(arena->max); - osMemoryCommit(arena->memory, max + (max % ARENA_COMMIT_SIZE)); - arena->alloc_position = 0; - arena->commit_position = 0; - arena->static_size = true; -} - - -fn void arenaClear(Arena* a) { - a->alloc_position = 0; -} - -fn void arenaFree(Arena* a) { - osMemoryRelease(a->memory, a->max); -} - -ScratchMem scratchGet(void) { - ThreadContext* ctx = (ThreadContext*)osThreadContextGet(); - return tctxScratchGet(ctx); -} - -void scratchReset(ScratchMem* scratch) { - ThreadContext* ctx = (ThreadContext*)osThreadContextGet(); - tctxScratchReset(ctx, scratch); -} - -void scratchReturn(ScratchMem* scratch) { - ThreadContext* ctx = (ThreadContext*)osThreadContextGet(); - tctxScratchReturn(ctx, scratch); -} diff --git a/src/base/os.c b/src/base/os.c deleted file mode 100644 index d979442..0000000 --- a/src/base/os.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "all.h" - -#if OS_WINDOWS -# include "win32_os.c" -#elif OS_LINUX -# include "linux_os.c" -# include "unix_os.c" -#elif OS_MAC -# include "pthread_barrier.c" -# include "mac_os.c" -# include "unix_os.c" -#endif diff --git a/src/base/pthread_barrier.c b/src/base/pthread_barrier.c deleted file mode 100644 index 495cbc9..0000000 --- a/src/base/pthread_barrier.c +++ /dev/null @@ -1,102 +0,0 @@ -/* (C) Copyright 2019 Robert Sauter - * SPDX-License-Identifier: MIT - */ - -/** Pthread-barrier implementation for macOS using a pthread mutex and condition variable */ - - -#include "pthread_barrier.h" -#include - -#ifdef __APPLE__ - -int pthread_barrier_init(pthread_barrier_t *__restrict barrier, - const pthread_barrierattr_t * __restrict attr, - unsigned count) { - if (count == 0) { - return EINVAL; - } - - int ret; - - pthread_condattr_t condattr; - pthread_condattr_init(&condattr); - if (attr) { - int pshared; - ret = pthread_barrierattr_getpshared(attr, &pshared); - if (ret) { - return ret; - } - ret = pthread_condattr_setpshared(&condattr, pshared); - if (ret) { - return ret; - } - } - - ret = pthread_mutex_init(&barrier->mutex, attr); - if (ret) { - return ret; - } - - ret = pthread_cond_init(&barrier->cond, &condattr); - if (ret) { - pthread_mutex_destroy(&barrier->mutex); - return ret; - } - - barrier->count = count; - barrier->left = count; - barrier->round = 0; - - return 0; -} - -int pthread_barrier_destroy(pthread_barrier_t *barrier) { - if (barrier->count == 0) { - return EINVAL; - } - - barrier->count = 0; - int rm = pthread_mutex_destroy(&barrier->mutex); - int rc = pthread_cond_destroy(&barrier->cond); - return rm ? rm : rc; -} - - -int pthread_barrier_wait(pthread_barrier_t *barrier) { - pthread_mutex_lock(&barrier->mutex); - if (--barrier->left) { - unsigned round = barrier->round; - do { - pthread_cond_wait(&barrier->cond, &barrier->mutex); - } while (round == barrier->round); - pthread_mutex_unlock(&barrier->mutex); - return 0; - } else { - barrier->round += 1; - barrier->left = barrier->count; - pthread_cond_broadcast(&barrier->cond); - pthread_mutex_unlock(&barrier->mutex); - return PTHREAD_BARRIER_SERIAL_THREAD; - } -} - - -int pthread_barrierattr_init(pthread_barrierattr_t *attr) { - return pthread_mutexattr_init(attr); -} - -int pthread_barrierattr_destroy(pthread_barrierattr_t *attr) { - return pthread_mutexattr_destroy(attr); -} - -int pthread_barrierattr_getpshared(const pthread_barrierattr_t *__restrict attr, - int *__restrict pshared) { - return pthread_mutexattr_getpshared(attr, pshared); -} - -int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared) { - return pthread_mutexattr_setpshared(attr, pshared); -} - -#endif /* __APPLE */ \ No newline at end of file diff --git a/src/base/pthread_barrier.h b/src/base/pthread_barrier.h deleted file mode 100644 index 0db4acd..0000000 --- a/src/base/pthread_barrier.h +++ /dev/null @@ -1,49 +0,0 @@ -/** Pthread-barrier implementation for macOS */ -#ifndef PTHREAD_BARRIER_H -#define PTHREAD_BARRIER_H - -#include - -#ifdef __APPLE__ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef PTHREAD_BARRIER_SERIAL_THREAD -# define PTHREAD_BARRIER_SERIAL_THREAD -1 -#endif - -typedef pthread_mutexattr_t pthread_barrierattr_t; - -/* structure for internal use that should be considered opaque */ -typedef struct { - pthread_mutex_t mutex; - pthread_cond_t cond; - unsigned count; - unsigned left; - unsigned round; -} pthread_barrier_t; - -int pthread_barrier_init(pthread_barrier_t *__restrict barrier, - const pthread_barrierattr_t * __restrict attr, - unsigned count); -int pthread_barrier_destroy(pthread_barrier_t *barrier); - -int pthread_barrier_wait(pthread_barrier_t *barrier); - -int pthread_barrierattr_init(pthread_barrierattr_t *attr); -int pthread_barrierattr_destroy(pthread_barrierattr_t *attr); -int pthread_barrierattr_getpshared(const pthread_barrierattr_t *__restrict attr, - int *__restrict pshared); -int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, - int pshared); - - -#ifdef __cplusplus -} -#endif - -#endif /* __APPLE__ */ - -#endif /* PTHREAD_BARRIER_H */ diff --git a/src/base/serialize.c b/src/base/serialize.c deleted file mode 100644 index 93e0815..0000000 --- a/src/base/serialize.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "all.h" - -fn u64 writeU64ToBufferLE(u8* buffer, u64 value) { - buffer[0] = (u8)(value & 0xFF); - buffer[1] = (u8)((value >> 8) & 0xFF); - buffer[2] = (u8)((value >> 16) & 0xFF); - buffer[3] = (u8)((value >> 24) & 0xFF); - buffer[4] = (u8)((value >> 32) & 0xFF); - buffer[5] = (u8)((value >> 40) & 0xFF); - buffer[6] = (u8)((value >> 48) & 0xFF); - buffer[7] = (u8)((value >> 56) & 0xFF); - return 8;// number of bytes written -} - -fn u64 writeU32ToBufferLE(u8* buffer, u32 value) { - buffer[0] = (u8)(value & 0xFF); - buffer[1] = (u8)((value >> 8) & 0xFF); - buffer[2] = (u8)((value >> 16) & 0xFF); - buffer[3] = (u8)((value >> 24) & 0xFF); - return 4;// number of bytes written -} - -fn u64 writeI32ToBufferLE(u8* buffer, i32 value) { - buffer[0] = (u8)(value & 0xFF); - buffer[1] = (u8)((value >> 8) & 0xFF); - buffer[2] = (u8)((value >> 16) & 0xFF); - buffer[3] = (u8)((value >> 24) & 0xFF); - return 4;// number of bytes written -} - -fn u64 writeU16ToBufferLE(u8* buffer, u16 value) { - buffer[0] = (u8)(value & 0xFF); - buffer[1] = (u8)((value >> 8) & 0xFF); - return 2;// number of bytes written -} - -fn u64 writeF32ToBufferLE(u8* buffer, f32 value) { - u32 bits; - memcpy(&bits, &value, sizeof(u32)); // reinterpret float bits as integer - - buffer[0] = (u8)(bits & 0xFF); - buffer[1] = (u8)((bits >> 8) & 0xFF); - buffer[2] = (u8)((bits >> 16) & 0xFF); - buffer[3] = (u8)((bits >> 24) & 0xFF); - return 4;// number of bytes written -} - -fn u64 readU64FromBufferLE(u8 *buffer) { - return (u64)buffer[0] | - ((u64)buffer[1] << 8) | - ((u64)buffer[2] << 16) | - ((u64)buffer[3] << 24) | - ((u64)buffer[4] << 32) | - ((u64)buffer[5] << 40) | - ((u64)buffer[6] << 48) | - ((u64)buffer[7] << 56); -} - -fn u32 readU32FromBufferLE(u8 *buffer) { - return (u32)buffer[0] | - ((u32)buffer[1] << 8) | - ((u32)buffer[2] << 16) | - ((u32)buffer[3] << 24); -} - -fn i32 readI32FromBufferLE(u8 *buffer) { - return (i32)buffer[0] | - ((i32)buffer[1] << 8) | - ((i32)buffer[2] << 16) | - ((i32)buffer[3] << 24); -} - -fn u16 readU16FromBufferLE(u8 *buffer) { - return (u16)buffer[0] | - ((u16)buffer[1] << 8); -} - -fn f32 readF32FromBufferLE(u8 *buf) { - u32 bits = 0; - bits |= (u32)(u8)buf[0] << 0; - bits |= (u32)(u8)buf[1] << 8; - bits |= (u32)(u8)buf[2] << 16; - bits |= (u32)(u8)buf[3] << 24; - - f32 value; - memcpy(&value, &bits, sizeof(f32)); - return value; -} - diff --git a/src/base/string.c b/src/base/string.c deleted file mode 100644 index d475b7e..0000000 --- a/src/base/string.c +++ /dev/null @@ -1,216 +0,0 @@ -#include "all.h" - -fn bool stringsEq(String* a, String* b) { - if (a->length != b->length) { - return false; - } - for (i32 i = 0; i < a->length; i++) { - if (a->bytes[i] != b->bytes[i]) { - return false; - } - } - return true; -} - -fn bool cStringEqString(str a, String* b) { - if (strlen(a) != b->length) { - return false; - } - for (i32 i = 0; i < b->length; i++) { - if (a[i] != b->bytes[i]) { - return false; - } - } - return true; -} - -fn Utf8Character classifyUtf8Character(u8 c) { - /*two_byte utf8 starts with 1100. 192 - three_byte utf8 starts with 1110. 224 - four_byte utf8 starts with 1111. 240*/ - if (c <= 127) { - return Utf8CharacterAscii; - } else if (c >= 192 && c < 224) { - return Utf8CharacterTwoByte; - } else if (c >= 224 && c < 240) { - return Utf8CharacterThreeByte; - } else if (c >= 240) { - return Utf8CharacterFourByte; - } else { - assert(false && "Not a valid utf8 starting byte"); - return Utf8Character_Count; - } -} - -fn bool isUtf8Ascii(u8 c) { - return classifyUtf8Character(c) == Utf8CharacterAscii; -} - -fn bool isUtf8TwoByte(u8 c) { - return classifyUtf8Character(c) == Utf8CharacterTwoByte; -} - -fn bool isUtf8ThreeByte(u8 c) { - return classifyUtf8Character(c) == Utf8CharacterThreeByte; -} - -fn bool isUtf8FourByte(u8 c) { - return classifyUtf8Character(c) == Utf8CharacterFourByte; -} - -fn u8 lowerAscii(u8 c) { - if (c >= 65 && c <= 90) { - return c + 32; - } - return c; -} - -fn u8 upperAscii(u8 c) { - if (c >= 97 && c <= 122) { - return c - 32; - } - return c; -} - -fn bool isAlphaUnderscoreSpace(u8 c) { - return ((c >= 'A' && c <= 'Z') - || (c >= 'a' && c <= 'z') - || c == ' ' - || c == '_'); -} - -fn bool isSimplePrintable(u8 c) { - return (c >= ' ' && c <= '~'); -} - -typedef struct StrDecode { - u32 codepoint; - u32 size; -} StrDecode; - -fn StrDecode strDecodeUTF8(u8 *str, u32 cap){ - u8 length[] = { - 1, 1, 1, 1, // 000xx - 1, 1, 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, - 0, 0, 0, 0, // 100xx - 0, 0, 0, 0, - 2, 2, 2, 2, // 110xx - 3, 3, // 1110x - 4, // 11110 - 0, // 11111 - }; - u8 first_byte_mask[] = { 0, 0x7F, 0x1F, 0x0F, 0x07 }; - u8 final_shift[] = { 0, 18, 12, 6, 0 }; - - StrDecode result = {0}; - if (cap > 0){ - result.codepoint = '#'; - result.size = 1; - - u8 byte = str[0]; - u8 l = length[byte >> 3]; - if (0 < l && l <= cap){ - u32 cp = (byte & first_byte_mask[l]) << 18; - switch (l){ - case 4: cp |= ((str[3] & 0x3F) << 0); - case 3: cp |= ((str[2] & 0x3F) << 6); - case 2: cp |= ((str[1] & 0x3F) << 12); - default: break; - } - cp >>= final_shift[l]; - - result.codepoint = cp; - result.size = l; - } - } - - return result; -} - -fn u32 strEncodeUTF8(u8 *dst, u32 codepoint){ - u32 size = 0; - if (codepoint < (1 << 8)) { - dst[0] = codepoint; - size = 1; - } else if (codepoint < (1 << 11)) { - dst[0] = 0xC0 | (codepoint >> 6); - dst[1] = 0x80 | (codepoint & 0x3F); - size = 2; - } - else if (codepoint < (1 << 16)) { - dst[0] = 0xE0 | (codepoint >> 12); - dst[1] = 0x80 | ((codepoint >> 6) & 0x3F); - dst[2] = 0x80 | (codepoint & 0x3F); - size = 3; - } else if (codepoint < (1 << 21)) { - dst[0] = 0xF0 | (codepoint >> 18); - dst[1] = 0x80 | ((codepoint >> 12) & 0x3F); - dst[2] = 0x80 | ((codepoint >> 6) & 0x3F); - dst[3] = 0x80 | (codepoint & 0x3F); - size = 4; - } else { - dst[0] = '#'; - size = 1; - } - return size; -} - -fn StrDecode strDecodeUTF16(u16 *str, u32 cap){ - StrDecode result = {'#', 1}; - u16 x = str[0]; - if (x < 0xD800 || 0xDFFF < x) { - result.codepoint = x; - } else if (cap >= 2) { - u16 y = str[1]; - if (0xD800 <= x && x < 0xDC00 && - 0xDC00 <= y && y < 0xE000 - ) { - u16 xj = x - 0xD800; - u16 yj = y - 0xDc00; - u32 xy = (xj << 10) | yj; - result.codepoint = xy + 0x10000; - result.size = 2; - } - } - return result; -} - -fn u32 strEncodeUTF16(u16 *dst, u32 codepoint){ - u32 size = 0; - if (codepoint < 0x10000) { - dst[0] = codepoint; - size = 1; - } else { - u32 cpj = codepoint - 0x10000; - dst[0] = (cpj >> 10) + 0xD800; - dst[1] = (cpj & 0x3FF) + 0xDC00; - size = 2; - } - return(size); -} - -fn StringUTF16Const str16FromStr8(Arena* arena, String string) { - u16* memory = arenaAllocArray(arena, u16, string.length * 2 + 1); - - u16* dptr = memory; - u8* ptr = (u8*)string.bytes; - u8* opl = (u8*)string.bytes + string.length; - for (; ptr < opl;){ - StrDecode decode = strDecodeUTF8(ptr, (u64)(opl - ptr)); - u32 enc_size = strEncodeUTF16(dptr, decode.codepoint); - ptr += decode.size; - dptr += enc_size; - } - - *dptr = 0; - - u64 alloc_count = string.length*2 + 1; - u64 string_count = (u64)(dptr - memory); - u64 unused_count = alloc_count - string_count - 1; - arenaDealloc(arena, unused_count * sizeof(*memory)); - - StringUTF16Const result = { memory, string_count }; - return result; -} diff --git a/src/base/string_chunk.c b/src/base/string_chunk.c deleted file mode 100644 index de25a55..0000000 --- a/src/base/string_chunk.c +++ /dev/null @@ -1,162 +0,0 @@ -#include "all.h" - -fn StringChunkList allocStringChunkList(StringArena* a, String string) { - StringChunkList result = {0}; - u64 needed_chunks = (string.length + (STRING_CHUNK_PAYLOAD_SIZE-1)) / STRING_CHUNK_PAYLOAD_SIZE; - u64 bytes_left = string.length; - u64 string_offset = 0; - lockMutex(&a->mutex); { - for (u32 i = 0; i < needed_chunks; i++) { - StringChunk* chunk = a->first_free_str_chunk; - if (chunk == NULL) { - chunk = (StringChunk*)arenaAlloc(&a->a, sizeof(StringChunk)+STRING_CHUNK_PAYLOAD_SIZE); - } else { - a->first_free_str_chunk = a->first_free_str_chunk->next; - } - chunk->next = NULL; // makes sure we don't have a pointer to any other free_str_chunks - u64 bytes_to_copy = Min(bytes_left, STRING_CHUNK_PAYLOAD_SIZE); - // ryan's impl used chunk+1 which seems like a bug but what do I know he had a working demo - MemoryCopy(chunk+1, string.bytes+string_offset, bytes_to_copy); - QueuePush(result.first, result.last, chunk); - result.count += 1; - result.total_size += bytes_to_copy; - bytes_left -= bytes_to_copy; - string_offset += bytes_to_copy; - } - } unlockMutex(&a->mutex); - return result; -} - -fn void releaseStringChunkList(StringArena* a, StringChunkList* list) { - StringChunk* chunk = list->first; - lockMutex(&a->mutex); { - for (StringChunk* next = NULL; chunk != NULL; chunk = next) { - next = chunk->next; - chunk->next = a->first_free_str_chunk; - a->first_free_str_chunk = chunk; - } - } unlockMutex(&a->mutex); - MemoryZeroStruct(list, StringChunkList); -} - -fn String stringChunkToString(Arena* a, StringChunkList list) { - String result = { - .length = list.total_size, - .capacity = list.total_size + 1, - .bytes = arenaAllocArray(a, u8, list.total_size+1), - }; - // copy the string bytes out of the StringChunkList into the correctly-sized String - StringChunk* chunk = list.first; - for (u32 i = 0; i < list.total_size; i++) { - if (i > 0 && i % STRING_CHUNK_PAYLOAD_SIZE == 0) { - chunk = chunk->next; - } - result.bytes[i] = *((char*)(chunk + 1) + (i%STRING_CHUNK_PAYLOAD_SIZE)); - } - return result; -} - -fn void stringChunkListAppend(StringArena* a, StringChunkList* list, String string) { - u64 capacity = list->count * STRING_CHUNK_PAYLOAD_SIZE; - u64 remaining_space = capacity - list->total_size; - u64 bytes_in_last_chunk = (list->total_size % STRING_CHUNK_PAYLOAD_SIZE); - if (string.length < remaining_space) { - MemoryCopy(((u8*)list->last)+sizeof(StringChunk*)+(bytes_in_last_chunk), string.bytes, string.length); - list->total_size += string.length; - } else { - u64 string_offset = 0; - u64 bytes_left = string.length; - u64 bytes_to_copy = Min(bytes_left, remaining_space); - if (remaining_space > 0) { - // fill up the last chunk - MemoryCopy(((u8*)(list->last+1))+(bytes_in_last_chunk), string.bytes, bytes_to_copy); - bytes_left -= bytes_to_copy; - string_offset += bytes_to_copy; - list->total_size += bytes_to_copy; - } - - // then figure out how many more chunks we need - u64 needed_chunks = (bytes_left + (STRING_CHUNK_PAYLOAD_SIZE-1)) / STRING_CHUNK_PAYLOAD_SIZE; - lockMutex(&a->mutex); { - for (u32 i = 0; i < needed_chunks; i++) { - StringChunk* chunk = a->first_free_str_chunk; - if (chunk == NULL) { - chunk = (StringChunk*)arenaAlloc(&a->a, sizeof(StringChunk)+STRING_CHUNK_PAYLOAD_SIZE); - } else { - a->first_free_str_chunk = a->first_free_str_chunk->next; - } - chunk->next = NULL; // makes sure we don't have a pointer to any other free_str_chunks - bytes_to_copy = Min(bytes_left, STRING_CHUNK_PAYLOAD_SIZE); - // ryan's impl used chunk+1 which seems like a bug but what do I know he had a working demo - MemoryCopy(chunk+1, string.bytes+string_offset, bytes_to_copy); - QueuePush(list->first, list->last, chunk); - list->count += 1; - list->total_size += bytes_to_copy; - bytes_left -= bytes_to_copy; - string_offset += bytes_to_copy; - } - } unlockMutex(&a->mutex); - } -} - -fn void stringChunkListDeleteLast(StringArena* a, StringChunkList* list) { - if (list->total_size == 0) return; - - u64 capacity = list->count * STRING_CHUNK_PAYLOAD_SIZE; - u64 remaining_space = capacity - list->total_size; - u64 bytes_in_last_chunk = STRING_CHUNK_PAYLOAD_SIZE - remaining_space; - - bool theres_only_one_chunk = list->total_size <= STRING_CHUNK_PAYLOAD_SIZE; - bool last_chunk_only_has_one_byte = bytes_in_last_chunk == 1; - - if (theres_only_one_chunk) { - ptr char_to_delete = ((char*)(list->last + 1) + (list->total_size-1)); - char_to_delete[0] = '\0'; - } else if (last_chunk_only_has_one_byte) { - // remove the last chunk when it's not the only chunk - StringChunk* second_to_last_chunk = list->first; - while (second_to_last_chunk->next != list->last && second_to_last_chunk->next != NULL) { - second_to_last_chunk = second_to_last_chunk->next; - } - second_to_last_chunk->next = NULL; - lockMutex(&a->mutex); { - list->last->next = a->first_free_str_chunk; - a->first_free_str_chunk = list->last; - } unlockMutex(&a->mutex); - list->last = second_to_last_chunk; - list->count -= 1; - } else { - ptr char_to_delete = ((char*)(list->last + 1) + ((list->total_size-1) % STRING_CHUNK_PAYLOAD_SIZE)); - char_to_delete[0] = '\0'; - } - list->total_size -= 1; -} - -fn StringChunkList stringChunkListInit(StringArena* a) { - StringChunkList result = {0}; - lockMutex(&a->mutex); { - StringChunk* chunk = a->first_free_str_chunk; - if (chunk == NULL) { - chunk = (StringChunk*)arenaAlloc(&a->a, sizeof(StringChunk)+STRING_CHUNK_PAYLOAD_SIZE); - } else { - a->first_free_str_chunk = a->first_free_str_chunk->next; - } - chunk->next = NULL; // makes sure we don't have a pointer to any other free_str_chunks - MemoryZero(chunk+1, STRING_CHUNK_PAYLOAD_SIZE); - QueuePush(result.first, result.last, chunk); - result.count += 1; - } unlockMutex(&a->mutex); - return result; -} - -fn void stringChunkCopyToBuffer(StringChunkList* list, u8* buffer, u32 len) { - assert(list->total_size <= len); - - StringChunk* chunk = list->first; - for (u32 i = 0; i < list->total_size; i++) { - if (i > 0 && i % STRING_CHUNK_PAYLOAD_SIZE == 0) { - chunk = chunk->next; - } - buffer[i] = *((char*)(chunk + 1) + (i%STRING_CHUNK_PAYLOAD_SIZE)); - } -} diff --git a/src/base/tctx.c b/src/base/tctx.c deleted file mode 100644 index aaa9b00..0000000 --- a/src/base/tctx.c +++ /dev/null @@ -1,83 +0,0 @@ -#include "all.h" - -void tctxInit(ThreadContext* ctx) { - arenaInit(&ctx->arena); - osThreadContextSet(ctx); -} - -void tctxFree(ThreadContext* ctx) { - arenaFree(&ctx->arena); - osThreadContextSet(ctx); -} - -fn ThreadContext *tctxSelected(void) { - return (ThreadContext*)osThreadContextGet(); -} - -ScratchMem tctxScratchGet(ThreadContext* ctx) { - if (!ctx->free_list) { - ScratchMem scratch = {0}; - - scratch.arena.memory = arenaAlloc(&ctx->arena, M_SCRATCH_SIZE); - scratch.arena.max = M_SCRATCH_SIZE; - scratch.arena.alloc_position = 0; - scratch.arena.commit_position = M_SCRATCH_SIZE; - scratch.arena.static_size = true; - - ctx->max_created++; - return scratch; - } else { - ScratchMem scratch = {0}; - - scratch.arena.memory = (u8*) ctx->free_list; - scratch.arena.max = M_SCRATCH_SIZE; - scratch.arena.alloc_position = 0; - scratch.arena.commit_position = M_SCRATCH_SIZE; - scratch.arena.static_size = true; - - ctx->free_list = ctx->free_list->next; - return scratch; - } -} - -void tctxScratchReset(ThreadContext* ctx, ScratchMem* scratch) { - scratch->arena.alloc_position = 0; -} - -void tctxScratchReturn(ThreadContext* ctx, ScratchMem* scratch) { - ScratchFreeListNode* prev_head = ctx->free_list; - ctx->free_list = (ScratchFreeListNode*) scratch->arena.memory; - ctx->free_list->next = prev_head; -} - -fn LaneCtx tctxSetLaneCtx(LaneCtx lane_ctx) { - ThreadContext *tctx = tctxSelected(); - LaneCtx restore = tctx->lane_ctx; - tctx->lane_ctx = lane_ctx; - return restore; -} - -fn void tctxLaneBarrierWait(void *broadcast_ptr, u64 broadcast_size, u64 broadcast_src_lane_idx) { - ThreadContext *tctx = tctxSelected(); - - // broadcasting -> copy to broadcast memory on source lane - u64 broadcast_size_clamped = Min(broadcast_size, sizeof(tctx->lane_ctx.broadcast_memory[0])); - if(broadcast_ptr != 0 && LaneIdx() == broadcast_src_lane_idx) { - MemoryCopy(tctx->lane_ctx.broadcast_memory, broadcast_ptr, broadcast_size_clamped); - } - - // all cases: barrier - osBarrierWait(tctx->lane_ctx.barrier); - - // broadcasting -> copy from broadcast memory on destination lanes - if(broadcast_ptr != 0 && LaneIdx() != broadcast_src_lane_idx) - { - MemoryCopy(broadcast_ptr, tctx->lane_ctx.broadcast_memory, broadcast_size_clamped); - } - - // broadcasting -> barrier on all lanes - if(broadcast_ptr != 0) - { - osBarrierWait(tctx->lane_ctx.barrier); - } -} diff --git a/src/base/thread.c b/src/base/thread.c deleted file mode 100644 index 587a71d..0000000 --- a/src/base/thread.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "all.h" - -Thread spawnThread(void * (*threadFn)(void *), void* thread_arg) { - pthread_t thread; - pthread_create(&thread, NULL, threadFn, thread_arg); - Thread result = { thread }; - return result; -} - -Mutex newMutex() { - Mutex result = { PTHREAD_MUTEX_INITIALIZER }; - return result; -} - -Cond newCond() { - Cond result = { 0 }; - pthread_cond_init(&result.cond, NULL); - return result; -} - -void lockMutex(Mutex* m) { - pthread_mutex_lock(&m->mutex); -} - -void unlockMutex(Mutex* m) { - pthread_mutex_unlock(&m->mutex); -} - -void signalCond(Cond* cond) { - pthread_cond_signal(&cond->cond); -} - -void waitForCondSignal(Cond* cond, Mutex* mutex) { - pthread_cond_wait(&cond->cond, &mutex->mutex); -} - diff --git a/src/base/thread_context.h b/src/base/thread_context.h deleted file mode 100644 index c18d88d..0000000 --- a/src/base/thread_context.h +++ /dev/null @@ -1,114 +0,0 @@ -#include "types.h" -#include "memory.h" -#ifndef BASE_THREAD_CONTEXT_H -#define BASE_THREAD_CONTEXT_H - -typedef struct LaneCtx { - u64 lane_idx; - u64 lane_count; - Barrier barrier; - u64 *broadcast_memory; -} LaneCtx; - -typedef struct AccessPt AccessPt; -struct AccessPt -{ - u64 access_refcount; - u64 last_time_touched_us; - u64 last_update_idx_touched; -}; - -typedef struct AccessPtExpireParams AccessPtExpireParams; -struct AccessPtExpireParams -{ - u64 time; - u64 update_idxs; -}; - -typedef struct Touch Touch; -struct Touch -{ - Touch *next; - AccessPt *pt; - CondVar cv; -}; - -typedef struct Access Access; -struct Access -{ - Access *next; - Touch *top_touch; -}; - -typedef struct TCtx { - // scratch arenas - Arena *arenas[2]; - u8 thread_name[32]; - u64 thread_name_size; - - LaneCtx lane_ctx; - - // source location info - char *file_name; - u64 line_number; - - // accesses - Arena *access_arena; - Access *free_access; - Touch *free_touch; - - u64 *progress_counter_ptr; - u64 *progress_target_ptr; -} TCtx; - -//////////////////////////////// -// Thread Context Functions - -// thread-context allocation & selection -fn TCtx *tctxAlloc(void); -fn void tctxRelease(TCtx *tctx); -fn void tctxSelect(TCtx *tctx); -fn TCtx *tctxSelected(void); - -//- rjf: scratch arenas -internal Arena *tctx_get_scratch(Arena **conflicts, U64 count); -#define scratch_begin(conflicts, count) temp_begin(tctx_get_scratch((conflicts), (count))) -#define scratch_end(scratch) temp_end(scratch) - -//- rjf: lane metadata -internal LaneCtx tctx_set_lane_ctx(LaneCtx lane_ctx); -internal void tctx_lane_barrier_wait(void *broadcast_ptr, U64 broadcast_size, U64 broadcast_src_lane_idx); -#define lane_idx() (tctx_selected()->lane_ctx.lane_idx) -#define lane_count() (tctx_selected()->lane_ctx.lane_count) -#define lane_from_task_idx(idx) ((idx)%lane_count()) -#define lane_ctx(ctx) tctx_set_lane_ctx((ctx)) -#define lane_sync() tctx_lane_barrier_wait(0, 0, 0) -#define lane_sync_u64(ptr, src_lane_idx) tctx_lane_barrier_wait((ptr), sizeof(*(ptr)), (src_lane_idx)) -#define lane_range(count) m_range_from_n_idx_m_count(lane_idx(), lane_count(), (count)) - -//- rjf: thread names -internal void tctx_set_thread_name(String8 name); -internal String8 tctx_get_thread_name(void); - -//- rjf: thread source-locations -internal void tctx_write_srcloc(char *file_name, U64 line_number); -internal void tctx_read_srcloc(char **file_name, U64 *line_number); -#define tctx_write_this_srcloc() tctx_write_srcloc(__FILE__, __LINE__) - -//- rjf: access scopes -internal Access *access_open(void); -internal void access_close(Access *access); -internal void access_touch(Access *access, AccessPt *pt, CondVar cv); - -//- rjf: access points -internal B32 access_pt_is_expired_(AccessPt *pt, AccessPtExpireParams *params); -#define access_pt_is_expired(pt, ...) access_pt_is_expired_((pt), &(AccessPtExpireParams){.time = 2000000, .update_idxs = 2, __VA_ARGS__}) - -//- rjf: progress counters -#define set_progress_ptr(ptr) (tctx_selected()->progress_counter_ptr = (ptr)) -#define set_progress_target_ptr(ptr) (tctx_selected()->progress_target_ptr = (ptr)) -#define set_progress(val) (tctx_selected()->progress_counter_ptr ? ins_atomic_u64_eval_assign(tctx_selected()->progress_counter_ptr, (val)) : (void)0) -#define add_progress(val) (tctx_selected()->progress_counter_ptr ? ins_atomic_u64_add_eval(tctx_selected()->progress_counter_ptr, (val)) : (void)0) -#define set_progress_target(val) (tctx_selected()->progress_target_ptr ? ins_atomic_u64_eval_assign(tctx_selected()->progress_target_ptr, (val)) : (void)0) - -#endif // BASE_THREAD_CONTEXT_H diff --git a/src/base/unix_os.c b/src/base/unix_os.c deleted file mode 100644 index c39c96f..0000000 --- a/src/base/unix_os.c +++ /dev/null @@ -1,147 +0,0 @@ -#include "all.h" - -global pthread_key_t linux_thread_context_key; -// ThreadContext -void osInit() { - pthread_key_create(&linux_thread_context_key, NULL); -} - -void* osThreadContextGet() { - return pthread_getspecific(linux_thread_context_key); -} - -void osThreadContextSet(void* ctx) { - pthread_setspecific(linux_thread_context_key, ctx); -} - -bool osThreadJoin(Thread handle, u64 endt_us) { - /* - if(MemoryIsZeroStruct(&handle)) { return 0; } - OS_LNX_Entity *entity = (OS_LNX_Entity *)handle.u64[0]; - int join_result = pthread_join(entity->thread.handle, 0); - B32 result = (join_result == 0); - os_lnx_entity_release(entity); - return result; - */ - i32 join_result = pthread_join(handle.thread, NULL); - bool result = join_result == 0; - return result; -} - -// Memory -fn void* osMemoryReserve(u64 size) { - void* result = mmap(((void*)0), size, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); - if(result == MAP_FAILED) { - result = 0; - } - return result; -} - -fn void osMemoryCommit(void* memory, u64 size) { - i32 result = mprotect(memory, size, PROT_READ | PROT_WRITE); - assert(result == 0 && "osMemoryCommit() failed"); -} - -fn void osMemoryDecommit(void* memory, u64 size) { - mprotect(memory, size, PROT_NONE); -} - -fn void osMemoryRelease(void* memory, u64 size) { - munmap(memory, size); -} - -// TUI -TermIOs osStartTUI(bool blocking) { - // set up the TUI incantations - printf("\033[?1049h"); // go to alternate buffer - TermIOs terminal_attributes, old_terminal_attributes; - tcgetattr(STDOUT_FILENO, &terminal_attributes); - old_terminal_attributes = terminal_attributes; - terminal_attributes.c_lflag &= ~(ICANON | ECHO); // dont echo keypresses, dont wait for carriage return - tcsetattr(STDOUT_FILENO, TCSANOW, &terminal_attributes); - if (!blocking) { - fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); // non-blocking input mode - } - fflush(stdout); - return old_terminal_attributes; -} - -fn void osEndTUI(TermIOs old_terminal_attributes) { - tcsetattr(STDOUT_FILENO, TCSANOW, &old_terminal_attributes); - - // cleanup terminal TUI incantations - printf("\033[?1049l"); - fflush(stdout); -} - -fn Dim2 osGetTerminalDimensions() { - Dim2 result = {0}; - struct winsize ws; - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1) { - //perror("ioctl TIOCGWINSZ failed"); - //exit(1); - return result; - } - result.width = ws.ws_col; - result.height = ws.ws_row; - return result; -} - -void osBlitToTerminal(ptr writeable_output_ansi_string, i64 count) { - int flags = fcntl(STDOUT_FILENO, F_GETFL); - fcntl(STDOUT_FILENO, F_SETFL, flags & ~O_NONBLOCK); - - u64 total = 0; - while (total < count) { - i64 written_bytes = write(STDOUT_FILENO, writeable_output_ansi_string + total, count - total); - /* TODO handle this error - if (written_bytes < 0) { - if (errno == EINTR) continue; // Interrupted, retry - return -1; // Real error - } - */ - total += written_bytes; - } - fcntl(STDOUT_FILENO, F_SETFL, flags); -} - -bool osInitNetwork() { return true; } - -void osReadConsoleInput(u8* buffer, u32 len) { - MemoryZero(buffer, len); // reset the input so it's not contaminated by last keystroke - read(STDIN_FILENO, buffer, len); -} - -#define LOCALHOST_127 16777343 -i32 osLanIPAddress() { // returns as HOST byte-order - i32 result = 0; - struct ifaddrs *ifaddr, *ifa; - if (getifaddrs(&ifaddr) != -1) { - for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { - if (ifa->ifa_addr == NULL) continue; - - int family = ifa->ifa_addr->sa_family; - - if (family == AF_INET) { - struct sockaddr_in addr = *(struct sockaddr_in*)ifa->ifa_addr; - if (addr.sin_addr.s_addr != LOCALHOST_127) { - freeifaddrs(ifaddr); - //printf("%s %d %d", inet_ntoa(addr.sin_addr), addr.sin_addr.s_addr, ntohl(addr.sin_addr.s_addr)); - return ntohl(addr.sin_addr.s_addr); - } - /* - char host[NI_MAXHOST]; - int s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), - host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); - - if (s == 0) { - printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, host); - } - */ - } - } - - freeifaddrs(ifaddr); - } - return result; -} diff --git a/src/base/win32_os.c b/src/base/win32_os.c deleted file mode 100644 index 4f1b061..0000000 --- a/src/base/win32_os.c +++ /dev/null @@ -1,326 +0,0 @@ -#include "string.h" -#include "os.h" -#include -#include - -static u64 w32_ticks_per_sec = 1; -static u32 w32_thread_context_index; - -void osInit() { - LARGE_INTEGER perf_freq = {0}; - if (QueryPerformanceFrequency(&perf_freq)) { - w32_ticks_per_sec = ((u64)perf_freq.HighPart << 32) | perf_freq.LowPart; - } - timeBeginPeriod(1); - - w32_thread_context_index = TlsAlloc(); -} - -void* osThreadContextGet() { - return TlsGetValue(w32_thread_context_index); -} - -void osThreadContextSet(void* ctx) { - TlsSetValue(w32_thread_context_index, ctx); -} - -// Memory -fn void* osMemoryReserve(u64 size) { - return VirtualAlloc(0, size, MEM_RESERVE, PAGE_NOACCESS); -} - -fn void osMemoryCommit(void* memory, u64 size) { - VirtualAlloc(memory, size, MEM_COMMIT, PAGE_READWRITE); -} - -fn void osMemoryDecommit(void* memory, u64 size) { - VirtualFree(memory, size, MEM_DECOMMIT); -} - -fn void osMemoryRelease(void* memory, u64 size) { - VirtualFree(memory, 0, MEM_RELEASE); -} - -// Time -fn u64 osTimeMicrosecondsNow() { - u64 result = 0; - LARGE_INTEGER perf_counter = {0}; - if (QueryPerformanceCounter(&perf_counter)) { - u64 ticks = ((u64)perf_counter.HighPart << 32) | perf_counter.LowPart; - result = ticks * 1000000 / w32_ticks_per_sec; - } - return result; -} - -#define MICROSECONDS_PER_MILLISECOND 1000 -fn void osSleepMicroseconds(u32 t) { - Sleep(t / MICROSECONDS_PER_MILLISECOND); -} - -// Files -fn bool osFileExists(String filename) { - assert(false && "Not Implemented"); - ScratchMem scratch = scratchGet(); - StringUTF16Const filename16 = str16FromStr8(&scratch.arena, filename); - DWORD ret = GetFileAttributesW((WCHAR*)filename16.string); - scratchReturn(&scratch); - return (ret != INVALID_FILE_ATTRIBUTES && !(ret & FILE_ATTRIBUTE_DIRECTORY)); -} - -fn String osFileRead(Arena* arena, ptr filepath) { - assert(false && "Not Implemented"); - String result = {0}; - return result; -} - -fn bool osFileCreate(String filename) { - assert(false && "Not Implemented"); - return false; -} - -fn bool osFileCreateWrite(String filename, String data) { - assert(false && "Not Implemented"); - bool result = true; - return result; -} - -fn bool osFileWrite(String filename, String data) { - assert(false && "Not Implemented"); - bool result = true; - return result; -} - - -// Misc -fn void osDebugPrint(bool debug_mode, const char * format, ... ) { - if (debug_mode) { - va_list args; - va_start(args, format); - vprintf(format, args); - va_end(args); - } -} - - -// TUI -TermIOs osStartTUI(bool blocking) { - TermIOs old_settings; - - // Windows implementation - HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); - HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); - - // Save old console modes - GetConsoleMode(hStdin, &old_settings.input_mode); - GetConsoleMode(hStdout, &old_settings.output_mode); - - // Set up alternate screen buffer - printf("\033[?1049h"); - fflush(stdout); - - // Disable line input and echo (equivalent to ~ICANON and ~ECHO) - DWORD new_input_mode = old_settings.input_mode; - new_input_mode &= ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); - - // Enable virtual terminal processing for ANSI escape sequences - DWORD new_output_mode = old_settings.output_mode; - new_output_mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; - - SetConsoleMode(hStdin, new_input_mode); - SetConsoleMode(hStdout, new_output_mode); - - SetConsoleOutputCP(CP_UTF8); - - // Note: Windows console is inherently non-blocking when using - // ENABLE_LINE_INPUT disabled. You can check for input with: - // DWORD events; - // GetNumberOfConsoleInputEvents(hStdin, &events); - // Or use PeekConsoleInput() before ReadConsoleInput() - - return old_settings; -} - -fn void osEndTUI(TermIOs old_terminal_attributes) { - HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); - HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); - - // Restore console modes - SetConsoleMode(hStdin, old_terminal_attributes.input_mode); - SetConsoleMode(hStdout, old_terminal_attributes.output_mode); - - // cleanup terminal TUI incantations - printf("\033[?1049l"); - fflush(stdout); -} - -fn Dim2 osGetTerminalDimensions() { - Dim2 result = {0}; - - HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO csbi; - - if (GetConsoleScreenBufferInfo(hStdout, &csbi)) { - result.width = csbi.srWindow.Right - csbi.srWindow.Left + 1; - result.height = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; - } else { - exit(1); - } - - return result; -} - -void osBlitToTerminal(ptr writeable_output_ansi_string, i64 count) { - HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD written; - WriteConsole(hStdout, writeable_output_ansi_string, count, &written, NULL); - assert(written == count); -} - -bool osInitNetwork() { - WSADATA wsaData; - - if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { - return false; - } - - if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { - WSACleanup(); - return false; - } - - return true; -} - -void osReadConsoleInput(u8* buffer, u32 len) { - MemoryZero(buffer, len); // reset the input so it's not contaminated by last keystroke - - if (_kbhit()) { - buffer[0] = _getch(); - bool first_byte_is_special = buffer[0] == 0 || buffer[0] == 224; - if (first_byte_is_special && _kbhit()) { - u8 windows_key = _getch(); - switch (windows_key) { - case 72: buffer[0] = 27; buffer[1] = 91; buffer[2] = 65; break; // up - case 75: buffer[0] = 27; buffer[1] = 91; buffer[2] = 68; break; // left - case 77: buffer[0] = 27; buffer[1] = 91; buffer[2] = 67; break; // right - case 80: buffer[0] = 27; buffer[1] = 91; buffer[2] = 66; break; // down - default: buffer[1] = windows_key; - } - /*if (_kbhit()) { - buffer[2] = _getch(); - if (_kbhit()) { - buffer[3] = _getch(); - } - }*/ - } - } - /* - HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); - INPUT_RECORD ir; - DWORD read; - if (PeekConsoleInput(hStdin, &ir, 1, &read) && read > 0) { - ReadConsole(hStdin, buffer, len, &read, NULL); - ReadConsoleInput(hStdin, &ir, 1, &read); - if (ir.EventType == KEY_EVENT) { - buffer[0] = ir.Event.KeyEvent.uChar.AsciiChar; - } - } - */ -} - -i32 osLanIPAddress() { - i32 result = 0; - /* - IP_ADAPTER_INFO *pAdapterInfo; - IP_ADAPTER_INFO *pAdapter = NULL; - DWORD dwRetVal = 0; - ULONG ulOutBufLen; - - pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO)); - ulOutBufLen = sizeof(IP_ADAPTER_INFO); - - // Make an initial call to GetAdaptersInfo to get the necessary size - if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { - free(pAdapterInfo); - pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen); - } - - if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { - pAdapter = pAdapterInfo; - printf("LAN Addresses:\n"); - - // TODO: test this on windows - while (pAdapter) { - printf("Interface: %s\n", pAdapter->AdapterName); - printf("Description: %s\n", pAdapter->Description); - printf("IP Address: %s\n", pAdapter->IpAddressList.IpAddress.String); - printf("IP Address: %d\n", pAdapter->Address[0] << 24 | pAdapter->Address[1] << 16 | pAdapter->Address[2] << 8 | pAdapter->Address[3]); - printf("\n"); - pAdapter = pAdapter->Next; - } - } else { - printf("GetAdaptersInfo failed: %ld\n", dwRetVal); - } - - if (pAdapterInfo) { - free(pAdapterInfo); - } - */ - WSADATA wsa; - char hostname[256]; - struct addrinfo hints, *final = NULL, *ptr = NULL; - struct sockaddr_in *sockaddr_ipv4; - - // Initialize Winsock - if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { - return 0; - } - - // Get hostname - if (gethostname(hostname, sizeof(hostname)) == SOCKET_ERROR) { - WSACleanup(); - return 0; - } - - // Set up hints for getaddrinfo - ZeroMemory(&hints, sizeof(hints)); - hints.ai_family = AF_INET; // IPv4 - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - // Get address info - if (getaddrinfo(hostname, NULL, &hints, &final) != 0) { - WSACleanup(); - return 0; - } - - // Loop through results to find a non-loopback address - for (ptr = final; ptr != NULL; ptr = ptr->ai_next) { - sockaddr_ipv4 = (struct sockaddr_in *)ptr->ai_addr; - unsigned long addr = ntohl(sockaddr_ipv4->sin_addr.s_addr); - - // Skip loopback addresses (127.x.x.x) - if ((addr >> 24) != 127) { - result = sockaddr_ipv4->sin_addr.s_addr; - break; - } - } - - freeaddrinfo(final); - WSACleanup(); - - return ntohl(result); -} - -bool osThreadJoin(Thread handle, u64 endt_us) { - DWORD sleep_ms = os_w32_sleep_ms_from_endt_us(endt_us); - OS_W32_Entity *entity = (OS_W32_Entity *)PtrFromInt(handle.u64[0]); - DWORD wait_result = WAIT_OBJECT_0; - if(entity != 0) - { - wait_result = WaitForSingleObject(entity->thread.handle, sleep_ms); - CloseHandle(entity->thread.handle); - os_w32_entity_release(entity); - } - return (wait_result == WAIT_OBJECT_0); -}