#pragma once #include #include #include #include #include #include #include #include #include #include #if defined(_WIN32) || defined(_WIN64) #define PLATFORM_WINDOWS 1 #include #include #include #include #include #include #define strdup _strdup #else #include #include #include #include #include #include #endif /* ------------------------------------------------------------ Base types ------------------------------------------------------------ */ typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; typedef int8_t i8; typedef int16_t i16; typedef int32_t i32; typedef int64_t i64; typedef i8 b8; typedef int b32; typedef float f32; typedef double f64; /* ------------------------------------------------------------ Size helpers ------------------------------------------------------------ */ #define KiB(x) ((u64)(x) * 1024ULL) #define MiB(x) (KiB(x) * 1024ULL) #define GiB(x) (MiB(x) * 1024ULL) /* ------------------------------------------------------------ Min / Max helpers ------------------------------------------------------------ */ #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef MAX #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif /* ------------------------------------------------------------ Alignment helpers ------------------------------------------------------------ */ #define ALIGN_UP_POW2(x, a) ((a) ? (((x) + ((a) - 1)) & ~((a) - 1)) : (x)) /* ------------------------------------------------------------ Assert ------------------------------------------------------------ */ #ifndef ASSERT #define ASSERT(x) assert(x) #endif #define NDEBUG // Comment to enable asserts /* ------------------------------------------------------------ Some helper functions ------------------------------------------------------------ */ #if defined(_WIN32) || defined(_WIN64) // Memory allocation static u32 plat_get_pagesize(void) { SYSTEM_INFO sysinfo = {0}; GetSystemInfo(&sysinfo); return sysinfo.dwPageSize; } static void *plat_mem_reserve(u64 size) { return VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_READWRITE); } static b32 plat_mem_commit(void *ptr, u64 size) { void *ret = VirtualAlloc(ptr, size, MEM_COMMIT, PAGE_READWRITE); return ret != NULL; } static b32 plat_mem_decommit(void *ptr, u64 size) { return VirtualFree(ptr, size, MEM_DECOMMIT); } static b32 plat_mem_release(void *ptr, u64 size) { return VirtualFree(ptr, size, MEM_RELEASE); } // Semaphores typedef struct plat_sem { HANDLE handle; } plat_sem; static b32 plat_sem_init(plat_sem *s, u32 initial) { s->handle = CreateSemaphore(NULL, initial, LONG_MAX, NULL); return s->handle != NULL; } static void plat_sem_wait(plat_sem *s) { WaitForSingleObject(s->handle, INFINITE); } static b32 plat_sem_trywait(HANDLE sem) { DWORD r = WaitForSingleObject(sem, 0); return r == WAIT_OBJECT_0; } static void plat_sem_post(plat_sem *s, u32 count) { ReleaseSemaphore(s->handle, count, NULL); } static void plat_sem_destroy(plat_sem *s) { if (s->handle) { CloseHandle(s->handle); s->handle = NULL; } } // Sleep static void sleep_ms(int ms) { Sleep(ms); } #elif defined(__linux__) // Memory allocation #ifndef _DEFAULT_SOURCE #define _DEFAULT_SOURCE #endif #include #include static u32 plat_get_pagesize(void) { return (u32)sysconf(_SC_PAGESIZE); } static void *plat_mem_reserve(u64 size) { void *out = mmap(NULL, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (out == MAP_FAILED) { return NULL; } return out; } static b32 plat_mem_commit(void *ptr, u64 size) { i32 ret = mprotect(ptr, size, PROT_READ | PROT_WRITE); return ret == 0; } static b32 plat_mem_decommit(void *ptr, u64 size) { i32 ret = mprotect(ptr, size, PROT_NONE); if (ret != 0) return false; ret = madvise(ptr, size, MADV_DONTNEED); return ret == 0; } static b32 plat_mem_release(void *ptr, u64 size) { i32 ret = munmap(ptr, size); return ret == 0; } // Semaphores #include typedef struct plat_sem { sem_t sem; } plat_sem; static b32 plat_sem_init(plat_sem *s, u32 initial) { return sem_init(&s->sem, 0, initial) == 0; } static void plat_sem_wait(plat_sem *s) { while (sem_wait(&s->sem) == -1 && errno == EINTR) { } } static b32 plat_sem_trywait(sem_t *sem) { return sem_trywait(sem) == 0; } static void plat_sem_post(plat_sem *s, u32 count) { for (u32 i = 0; i < count; i++) { sem_post(&s->sem); } } static void plat_sem_destroy(plat_sem *s) { sem_destroy(&s->sem); } // Sleep static void sleep_ms(int ms) { usleep(ms * 1000); } #endif