Platform and OS stability stuff
[vg.git] / src / vg / vg_platform.h
index d7c0a0cff6ee13d0a08ff5ef1e09bcbef45ba449..e5deae28a1a39626b7c1d0eae8ebe64103b9d826 100644 (file)
@@ -2,6 +2,7 @@
 #define VG_PLATFORM_H
 
 #include "vg.h"
+#include "vg_stdint.h"
 
 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
 
@@ -30,81 +31,118 @@ 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))
 
-#ifdef _WIN32
+#ifdef _WIN32_NO
        #include <windows.h>
 
-/* TODO */
+#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 <pthread.h>
    #include <semaphore.h>
 
+   #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;
 
-static int vg_semaphore_init( vg_semaphore *sem, u32 value )
-{
-   if( !sem_init( sem, 0, value ) )
-      return 1;
-   else
-      return 0;
-}
+#endif
 
-static int vg_semaphore_wait( vg_semaphore *sem )
-{
-   if( !sem_wait( sem ) )
-      return 1;
-   else
-      return 0;
-}
+#include <stdlib.h>
 
-static int vg_semaphore_post( vg_semaphore *sem )
+static void vg_fatal_exit_loop( const char *error );
+static void *vg_alloc( size_t size )
 {
-   if( !sem_post( sem ) )
-      return 1;
-   else
-      return 0;
-}
+   void *ptr = malloc( size );
+   
+   if( !ptr )
+      vg_fatal_exit_loop( "Out of memory" );
 
-static void vg_semaphore_free( vg_semaphore *sem )
-{
-   sem_destroy( sem );
+   return ptr;
 }
 
-static int vg_mutex_init( vg_mutex *mutex )
+static void *vg_realloc( void *orig, size_t size )
 {
-   memset( mutex, 0, sizeof(vg_mutex) );
-   return 1;
-}
+   void *ptr = realloc( orig, size );
 
-static int vg_mutex_lock( vg_mutex *mutex )
-{
-   if( !pthread_mutex_lock( mutex ) )
-      return 1;
-   else
-      return 0;
+   if( !ptr )
+      vg_fatal_exit_loop( "Out of memory" );
+
+   return ptr;
 }
 
-static int vg_mutex_unlock( vg_mutex *mutex )
+/* seems to be a GCC bug when inlining this, its low priority anyway */
+__attribute__ ((noinline))
+static void vg_free( void *ptr )
 {
-   if( !pthread_mutex_unlock( mutex ) )
-      return 1;
-   else
-      return 0;
+   free( ptr );
 }
 
-static void vg_mutex_free( vg_mutex *mutex )
+static void vg_required( void *ptr, const char *path )
 {
-
+   if( !ptr )
+   {
+      vg_fatal_exit_loop( path );
+   }
 }
 
-#endif
-
-
-int vg_thread_run( void *pfunc, void *data )
+#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 <stdio.h>
+#include <dirent.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <math.h>
+#include <assert.h>
+
+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 */
@@ -128,7 +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 ) )
        {
@@ -139,9 +204,74 @@ 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;
@@ -160,6 +290,8 @@ static double vg_time_diff( struct timespec start, struct timespec end )
    return elapsed;
 }
 
+#endif
+
 #define VG_MIN( A, B ) ((A)<(B)?(A):(B))
 #define VG_MAX( A, B ) ((A)>(B)?(A):(B))
 
@@ -169,8 +301,7 @@ static void *buffer_reserve( void *buffer, u32 count, u32 *cap, u32 amount,
    if( count+amount > *cap )
    {
       *cap = VG_MAX( (*cap)*2, (*cap)+amount );
-      
-      return realloc( buffer, (*cap) * emsize );
+      return vg_realloc( buffer, (*cap) * emsize );
    }
 
    return buffer;
@@ -179,7 +310,7 @@ static void *buffer_reserve( void *buffer, u32 count, u32 *cap, u32 amount,
 static void *buffer_fix( void *buffer, u32 count, u32 *cap, size_t emsize )
 {
    *cap = count;
-   return realloc( buffer, (*cap) * emsize );
+   return vg_realloc( buffer, (*cap) * emsize );
 }
 
 #endif