7 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
9 typedef unsigned int uint
;
24 typedef struct vg_tex2d vg_tex2d
;
32 #define vg_static_assert _Static_assert
33 #define vg_list_size( A ) (sizeof(A)/sizeof(A[0]))
34 #define VG_MUST_USE_RESULT __attribute__((warn_unused_result))
39 #ifdef I_THINK_THIS_IS_WHAT_MSCV_WANTS_BUT_HAVNT_TESTED_IT_YET
41 #define VG_DEPRECATED __declspec(deprecated)
42 #define VG_THREAD_LOCAL __declspec( thread )
46 #define VG_THREAD_LOCAL __thread
47 #define VG_DEPRECATED __attribute__((deprecated))
51 typedef HANDLE vg_semaphore
;
52 typedef HANDLE vg_mutex
;
53 typedef u64 vg_timespec
;
57 #include <semaphore.h>
59 #define VG_DEPRECATED __attribute__((deprecated))
60 #define VG_THREAD_LOCAL __thread
62 typedef sem_t vg_semaphore
;
63 typedef pthread_mutex_t vg_mutex
;
64 typedef struct timespec vg_timespec
;
70 #define VG_ZERO_NEW_MEM
72 static void vg_fatal_exit_loop( const char *error
);
73 static void *vg_alloc( size_t size
)
75 void *ptr
= malloc( size
);
78 vg_fatal_exit_loop( "Out of memory" );
80 #ifdef VG_ZERO_NEW_MEM
82 for( u32 i
=0; i
<size
; i
++ )
91 static void *vg_realloc( void *orig
, size_t size
)
93 void *ptr
= realloc( orig
, size
);
96 vg_fatal_exit_loop( "Out of memory" );
101 /* seems to be a GCC bug when inlining this, its low priority anyway */
102 __attribute__ ((noinline
))
103 static void vg_free( void *ptr
)
108 static void vg_required( void *ptr
, const char *path
)
112 vg_fatal_exit_loop( path
);
116 #define VG_REQUIRED_ASSET( TYPE, DECL, FN, PATH, ... ) \
117 TYPE DECL = FN( PATH,##__VA_ARGS__ ); \
118 vg_required( DECL, "Resource is required but failed to load: '" PATH "'" );
121 void *malloc( size_t size
);
124 void *realloc( void *orig
, size_t size
);
127 void free( void *ptr
);
137 static int vg_thread_run( void *pfunc
, void *data
);
138 static void vg_thread_exit(void);
139 static void vg_set_thread_name( const char *name
);
140 static int vg_semaphore_init( vg_semaphore
*sem
, u32 value
);
141 static int vg_semaphore_trywait( vg_semaphore
*sem
);
142 static int vg_semaphore_wait( vg_semaphore
*sem
);
143 static int vg_semaphore_post( vg_semaphore
*sem
);
144 static void vg_semaphore_free( vg_semaphore
*sem
);
145 static int vg_mutex_init( vg_mutex
*mutex
);
146 static int vg_mutex_lock( vg_mutex
*mutex
);
147 static int vg_mutex_unlock( vg_mutex
*mutex
);
148 static void vg_mutex_free( vg_mutex
*mutex
);
149 static void vg_sleep_ms( long msec
);
150 static double vg_time_diff( vg_timespec start
, vg_timespec end
);
154 static int vg_thread_run( void *pfunc
, void *data
)
156 HANDLE hThread
= CreateThread
158 NULL
, /* Thread attributes */
159 0, /* Stack size (0 = use default) */
160 pfunc
, /* Thread start address */
161 data
, /* Parameter to pass to the thread */
162 0, /* Creation flags */
166 if ( hThread
== NULL
)
169 * Thread creation failed.
170 * More details can be retrieved by calling GetLastError()
176 CloseHandle( hThread
);
181 static void vg_thread_exit(void)
186 static void vg_set_thread_name( const char *name
)
188 /* I believe this is a meaningless concept in windows */
191 static int vg_semaphore_init( vg_semaphore
*sem
, u32 value
);
192 static int vg_semaphore_trywait( vg_semaphore
*sem
);
193 static int vg_semaphore_wait( vg_semaphore
*sem
);
194 static int vg_semaphore_post( vg_semaphore
*sem
);
195 static void vg_semaphore_free( vg_semaphore
*sem
);
196 static int vg_mutex_init( vg_mutex
*mutex
);
197 static int vg_mutex_lock( vg_mutex
*mutex
);
198 static int vg_mutex_unlock( vg_mutex
*mutex
);
199 static void vg_mutex_free( vg_mutex
*mutex
);
200 static void vg_sleep_ms( long msec
);
201 static double vg_time_diff( vg_timespec start
, vg_timespec end
);
205 static int vg_thread_run( void *pfunc
, void *data
)
208 if( pthread_create( &hThread
, NULL
, pfunc
, data
) )
214 pthread_detach( hThread
);
220 static void vg_thread_exit(void)
225 static void vg_set_thread_name( const char *name
)
227 /* not defined but links?? */
229 pthread_setname_np(pthread_self());
233 static int vg_semaphore_init( vg_semaphore
*sem
, u32 value
)
235 return !sem_init( sem
, 0, value
);
238 static int vg_semaphore_trywait( vg_semaphore
*sem
)
240 return !sem_trywait( sem
);
243 static int vg_semaphore_wait( vg_semaphore
*sem
)
245 return !sem_wait( sem
);
248 static int vg_semaphore_post( vg_semaphore
*sem
)
250 return !sem_post( sem
);
253 static void vg_semaphore_free( vg_semaphore
*sem
)
258 static int vg_mutex_init( vg_mutex
*mutex
)
260 memset( mutex
, 0, sizeof(vg_mutex
) );
264 static int vg_mutex_lock( vg_mutex
*mutex
)
266 if( !pthread_mutex_lock( mutex
) )
272 static int vg_mutex_unlock( vg_mutex
*mutex
)
274 if( !pthread_mutex_unlock( mutex
) )
280 static void vg_mutex_free( vg_mutex
*mutex
)
285 static void vg_sleep_ms( long msec
)
289 ts
.tv_sec
= msec
/ 1000;
290 ts
.tv_nsec
= (msec
% 1000) * 1000000;
291 nanosleep( &ts
, &ts
);
294 /* diff two timespecs in MS */
295 static double vg_time_diff( struct timespec start
, struct timespec end
)
297 double elapsed
= 1000.0*end
.tv_sec
+ 1e-6*end
.tv_nsec
298 - (1000.0*start
.tv_sec
+ 1e-6*start
.tv_nsec
);
305 #define VG_MIN( A, B ) ((A)<(B)?(A):(B))
306 #define VG_MAX( A, B ) ((A)>(B)?(A):(B))
308 static void *buffer_reserve( void *buffer
, u32 count
, u32
*cap
, u32 amount
,
311 if( count
+amount
> *cap
)
313 *cap
= VG_MAX( (*cap
)*2, (*cap
)+amount
);
314 return vg_realloc( buffer
, (*cap
) * emsize
);
320 static void *buffer_fix( void *buffer
, u32 count
, u32
*cap
, size_t emsize
)
323 return vg_realloc( buffer
, (*cap
) * emsize
);