X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=src%2Fvg%2Fvg_platform.h;h=e5deae28a1a39626b7c1d0eae8ebe64103b9d826;hb=367883958336d1c04c8a304af6119b21f0f2f15a;hp=b1986b96d088e26732166a5020c6d6c2602e9d60;hpb=6cfa3e0895e42f702276e97c85ad371f3512c67d;p=vg.git diff --git a/src/vg/vg_platform.h b/src/vg/vg_platform.h index b1986b9..e5deae2 100644 --- a/src/vg/vg_platform.h +++ b/src/vg/vg_platform.h @@ -1,13 +1,10 @@ -// Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved +#ifndef VG_PLATFORM_H +#define VG_PLATFORM_H -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; +#include "vg.h" +#include "vg_stdint.h" + +/* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */ typedef unsigned int uint; @@ -20,6 +17,7 @@ typedef float v4f[4]; typedef v2f m2x2f[2]; typedef v3f m3x3f[3]; typedef v3f m4x3f[4]; +typedef v4f m4x4f[4]; typedef v3f boxf[2]; // Resource types @@ -32,60 +30,135 @@ struct vg_achievement }; #define vg_static_assert _Static_assert - #define vg_list_size( A ) (sizeof(A)/sizeof(A[0])) +#define VG_MUST_USE_RESULT __attribute__((warn_unused_result)) -// THREADING -// ================================================================================================================== - -// Pthred emulation for windows -#ifdef _WIN32 +#ifdef _WIN32_NO #include - #define MUTEX_TYPE HANDLE - #define MUTEX_INITIALIZER NULL - #define MUTEX_SETUP(x) (x) = CreateMutex(NULL, FALSE, NULL) - #define MUTEX_CLEANUP(x) (CloseHandle(x)) //TODO: Why is this defined but never used? - #define MUTEX_LOCK(x) emulate_pthread_mutex_lock(&(x)) - #define MUTEX_UNLOCK(x) (ReleaseMutex(x)) - - int emulate_pthread_mutex_lock( volatile MUTEX_TYPE *mx ) - { - if( *mx == NULL ) /* static initializer? */ - { - HANDLE p = CreateMutex( NULL, FALSE, NULL ); - if( InterlockedCompareExchangePointer( (PVOID*)mx, (PVOID)p, NULL ) != NULL ) - CloseHandle(p); - } - - return WaitForSingleObject( *mx, INFINITE ) == WAIT_FAILED; - } + +#ifdef I_THINK_THIS_IS_WHAT_MSCV_WANTS_BUT_HAVNT_TESTED_IT_YET + + #define VG_DEPRECATED __declspec(deprecated) + #define VG_THREAD_LOCAL __declspec( thread ) + +#else /* MINGW-64 */ + + #define VG_THREAD_LOCAL __thread + #define VG_DEPRECATED __attribute__((deprecated)) + +#endif + + typedef HANDLE vg_semaphore; + typedef HANDLE vg_mutex; + typedef u64 vg_timespec; + #else #include - #define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) - #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) - #define MUTEX_TYPE pthread_mutex_t - #define MUTEX_INITIALIZER {0} + #include + + #define VG_DEPRECATED __attribute__((deprecated)) + #define VG_THREAD_LOCAL __thread + + typedef sem_t vg_semaphore; + typedef pthread_mutex_t vg_mutex; + typedef struct timespec vg_timespec; + #endif +#include -int vg_thread_run( void *pfunc, void *data ) +static void vg_fatal_exit_loop( const char *error ); +static void *vg_alloc( size_t size ) +{ + void *ptr = malloc( size ); + + if( !ptr ) + vg_fatal_exit_loop( "Out of memory" ); + + return ptr; +} + +static void *vg_realloc( void *orig, size_t size ) +{ + void *ptr = realloc( orig, size ); + + if( !ptr ) + vg_fatal_exit_loop( "Out of memory" ); + + return ptr; +} + +/* seems to be a GCC bug when inlining this, its low priority anyway */ +__attribute__ ((noinline)) +static void vg_free( void *ptr ) +{ + free( ptr ); +} + +static void vg_required( void *ptr, const char *path ) +{ + if( !ptr ) + { + vg_fatal_exit_loop( path ); + } +} + +#define VG_REQUIRED_ASSET( TYPE, DECL, FN, PATH, ... ) \ + TYPE DECL = FN( PATH,##__VA_ARGS__ ); \ + vg_required( DECL, "Resource is required but failed to load: '" PATH "'" ); + +VG_DEPRECATED +void *malloc( size_t size ); + +VG_DEPRECATED +void *realloc( void *orig, size_t size ); + +VG_DEPRECATED +void free( void *ptr ); + +#include +#include +#include +#include +#include +#include +#include + +static int vg_thread_run( void *pfunc, void *data ); +static void vg_thread_exit(void); +static void vg_set_thread_name( const char *name ); +static int vg_semaphore_init( vg_semaphore *sem, u32 value ); +static int vg_semaphore_trywait( vg_semaphore *sem ); +static int vg_semaphore_wait( vg_semaphore *sem ); +static int vg_semaphore_post( vg_semaphore *sem ); +static void vg_semaphore_free( vg_semaphore *sem ); +static int vg_mutex_init( vg_mutex *mutex ); +static int vg_mutex_lock( vg_mutex *mutex ); +static int vg_mutex_unlock( vg_mutex *mutex ); +static void vg_mutex_free( vg_mutex *mutex ); +static void vg_sleep_ms( long msec ); +static double vg_time_diff( vg_timespec start, vg_timespec end ); + +#ifdef _WIN32_NO + +static int vg_thread_run( void *pfunc, void *data ) { -#ifdef _WIN32 - HANDLE hThread = CreateThread ( - NULL, // Thread attributes - 0, // Stack size (0 = use default) - pfunc, // Thread start address - data, // Parameter to pass to the thread - 0, // Creation flags - NULL // Thread id + NULL, /* Thread attributes */ + 0, /* Stack size (0 = use default) */ + pfunc, /* Thread start address */ + data, /* Parameter to pass to the thread */ + 0, /* Creation flags */ + NULL /* Thread id */ ); if ( hThread == NULL ) { - // Thread creation failed. - // More details can be retrieved by calling GetLastError() + /* + * Thread creation failed. + * More details can be retrieved by calling GetLastError() + */ return 1; } else @@ -93,9 +166,34 @@ int vg_thread_run( void *pfunc, void *data ) CloseHandle( hThread ); return 0; } - +} + +static void vg_thread_exit(void) +{ + ExitThread(0); +} + +static void vg_set_thread_name( const char *name ) +{ + /* I believe this is a meaningless concept in windows */ +} + +static int vg_semaphore_init( vg_semaphore *sem, u32 value ); +static int vg_semaphore_trywait( vg_semaphore *sem ); +static int vg_semaphore_wait( vg_semaphore *sem ); +static int vg_semaphore_post( vg_semaphore *sem ); +static void vg_semaphore_free( vg_semaphore *sem ); +static int vg_mutex_init( vg_mutex *mutex ); +static int vg_mutex_lock( vg_mutex *mutex ); +static int vg_mutex_unlock( vg_mutex *mutex ); +static void vg_mutex_free( vg_mutex *mutex ); +static void vg_sleep_ms( long msec ); +static double vg_time_diff( vg_timespec start, vg_timespec end ); + #else +static int vg_thread_run( void *pfunc, void *data ) +{ pthread_t hThread; if( pthread_create( &hThread, NULL, pfunc, data ) ) { @@ -106,6 +204,113 @@ int vg_thread_run( void *pfunc, void *data ) pthread_detach( hThread ); return 0; } +} + +static void vg_thread_exit(void) +{ + pthread_exit(NULL); +} + +static void vg_set_thread_name( const char *name ) +{ + /* not defined but links?? */ +#if 0 + pthread_setname_np(pthread_self()); #endif } + +static int vg_semaphore_init( vg_semaphore *sem, u32 value ) +{ + return !sem_init( sem, 0, value ); +} + +static int vg_semaphore_trywait( vg_semaphore *sem ) +{ + return !sem_trywait( sem ); +} + +static int vg_semaphore_wait( vg_semaphore *sem ) +{ + return !sem_wait( sem ); +} + +static int vg_semaphore_post( vg_semaphore *sem ) +{ + return !sem_post( sem ); +} + +static void vg_semaphore_free( vg_semaphore *sem ) +{ + sem_destroy( sem ); +} + +static int vg_mutex_init( vg_mutex *mutex ) +{ + memset( mutex, 0, sizeof(vg_mutex) ); + return 1; +} + +static int vg_mutex_lock( vg_mutex *mutex ) +{ + if( !pthread_mutex_lock( mutex ) ) + return 1; + else + return 0; +} + +static int vg_mutex_unlock( vg_mutex *mutex ) +{ + if( !pthread_mutex_unlock( mutex ) ) + return 1; + else + return 0; +} + +static void vg_mutex_free( vg_mutex *mutex ) +{ + +} + +static void vg_sleep_ms( long msec ) +{ + struct timespec ts; + + ts.tv_sec = msec / 1000; + ts.tv_nsec = (msec % 1000) * 1000000; + nanosleep( &ts, &ts ); +} + +/* diff two timespecs in MS */ +static double vg_time_diff( struct timespec start, struct timespec end ) +{ + double elapsed = 1000.0*end.tv_sec + 1e-6*end.tv_nsec + - (1000.0*start.tv_sec + 1e-6*start.tv_nsec); + + return elapsed; +} + +#endif + +#define VG_MIN( A, B ) ((A)<(B)?(A):(B)) +#define VG_MAX( A, B ) ((A)>(B)?(A):(B)) + +static void *buffer_reserve( void *buffer, u32 count, u32 *cap, u32 amount, + size_t emsize ) +{ + if( count+amount > *cap ) + { + *cap = VG_MAX( (*cap)*2, (*cap)+amount ); + return vg_realloc( buffer, (*cap) * emsize ); + } + + return buffer; +} + +static void *buffer_fix( void *buffer, u32 count, u32 *cap, size_t emsize ) +{ + *cap = count; + return vg_realloc( buffer, (*cap) * emsize ); +} + +#endif