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
;
68 static void vg_strncpy( const char *src
, char *dst
, u32 len
)
70 for( u32 i
=0; i
<len
; i
++ )
81 #define VG_ZERO_NEW_MEM
83 static void vg_fatal_exit_loop( const char *error
);
84 static void *vg_alloc( size_t size
)
89 void *ptr
= malloc( size
);
93 vg_fatal_exit_loop( "Out of memory" );
96 #ifdef VG_ZERO_NEW_MEM
98 for( u32 i
=0; i
<size
; i
++ )
107 static void *vg_realloc( void *orig
, size_t size
)
109 void *ptr
= realloc( orig
, size
);
116 vg_fatal_exit_loop( "Out of memory" );
122 /* seems to be a GCC bug when inlining this, its low priority anyway */
123 __attribute__ ((noinline
))
124 static void vg_free( void *ptr
)
129 static void vg_required( void *ptr
, const char *path
)
133 vg_fatal_exit_loop( path
);
137 #define VG_REQUIRED_ASSET( TYPE, DECL, FN, PATH, ... ) \
138 TYPE DECL = FN( PATH,##__VA_ARGS__ ); \
139 vg_required( DECL, "Resource is required but failed to load: '" PATH "'" );
143 char *strcpy(char* destination
, const char* source
);
145 char *strncpy(char *restrict dest
, const char *restrict src
, size_t n
);
147 char *strcat(char *restrict dest
, const char *restrict src
);
149 char *strncat(char *restrict dest
, const char *restrict src
, size_t n
);
153 void *malloc( size_t size
);
156 void *realloc( void *orig
, size_t size
);
159 void free( void *ptr
);
169 static int vg_thread_run( void *pfunc
, void *data
);
170 static void vg_thread_exit(void);
171 static void vg_set_thread_name( const char *name
);
172 static int vg_semaphore_init( vg_semaphore
*sem
, u32 value
);
173 static int vg_semaphore_trywait( vg_semaphore
*sem
);
174 static int vg_semaphore_wait( vg_semaphore
*sem
);
175 static int vg_semaphore_post( vg_semaphore
*sem
);
176 static void vg_semaphore_free( vg_semaphore
*sem
);
177 static int vg_mutex_init( vg_mutex
*mutex
);
178 static int vg_mutex_lock( vg_mutex
*mutex
);
179 static int vg_mutex_unlock( vg_mutex
*mutex
);
180 static void vg_mutex_free( vg_mutex
*mutex
);
181 static void vg_sleep_ms( long msec
);
182 static double vg_time_diff( vg_timespec start
, vg_timespec end
);
186 static int vg_thread_run( void *pfunc
, void *data
)
188 HANDLE hThread
= CreateThread
190 NULL
, /* Thread attributes */
191 0, /* Stack size (0 = use default) */
192 pfunc
, /* Thread start address */
193 data
, /* Parameter to pass to the thread */
194 0, /* Creation flags */
198 if ( hThread
== NULL
)
201 * Thread creation failed.
202 * More details can be retrieved by calling GetLastError()
208 CloseHandle( hThread
);
213 static void vg_thread_exit(void)
218 static void vg_set_thread_name( const char *name
)
220 /* I believe this is a meaningless concept in windows */
223 static int vg_semaphore_init( vg_semaphore
*sem
, u32 value
);
224 static int vg_semaphore_trywait( vg_semaphore
*sem
);
225 static int vg_semaphore_wait( vg_semaphore
*sem
);
226 static int vg_semaphore_post( vg_semaphore
*sem
);
227 static void vg_semaphore_free( vg_semaphore
*sem
);
228 static int vg_mutex_init( vg_mutex
*mutex
);
229 static int vg_mutex_lock( vg_mutex
*mutex
);
230 static int vg_mutex_unlock( vg_mutex
*mutex
);
231 static void vg_mutex_free( vg_mutex
*mutex
);
232 static void vg_sleep_ms( long msec
);
233 static double vg_time_diff( vg_timespec start
, vg_timespec end
);
237 static int vg_thread_run( void *pfunc
, void *data
)
240 if( pthread_create( &hThread
, NULL
, pfunc
, data
) )
246 pthread_detach( hThread
);
252 static void vg_thread_exit(void)
257 static void vg_set_thread_name( const char *name
)
259 /* not defined but links?? */
261 pthread_setname_np(pthread_self());
265 static int vg_semaphore_init( vg_semaphore
*sem
, u32 value
)
267 return !sem_init( sem
, 0, value
);
270 static int vg_semaphore_trywait( vg_semaphore
*sem
)
272 return !sem_trywait( sem
);
275 static int vg_semaphore_wait( vg_semaphore
*sem
)
277 return !sem_wait( sem
);
280 static int vg_semaphore_post( vg_semaphore
*sem
)
282 return !sem_post( sem
);
285 static void vg_semaphore_free( vg_semaphore
*sem
)
290 static int vg_mutex_init( vg_mutex
*mutex
)
292 memset( mutex
, 0, sizeof(vg_mutex
) );
296 static int vg_mutex_lock( vg_mutex
*mutex
)
298 if( !pthread_mutex_lock( mutex
) )
304 static int vg_mutex_unlock( vg_mutex
*mutex
)
306 if( !pthread_mutex_unlock( mutex
) )
312 static void vg_mutex_free( vg_mutex
*mutex
)
317 static void vg_sleep_ms( long msec
)
321 ts
.tv_sec
= msec
/ 1000;
322 ts
.tv_nsec
= (msec
% 1000) * 1000000;
323 nanosleep( &ts
, &ts
);
326 /* diff two timespecs in MS */
327 static double vg_time_diff( struct timespec start
, struct timespec end
)
329 double elapsed
= 1000.0*end
.tv_sec
+ 1e-6*end
.tv_nsec
330 - (1000.0*start
.tv_sec
+ 1e-6*start
.tv_nsec
);
337 #define VG_MIN( A, B ) ((A)<(B)?(A):(B))
338 #define VG_MAX( A, B ) ((A)>(B)?(A):(B))
340 static void *buffer_reserve( void *buffer
, u32 count
, u32
*cap
, u32 amount
,
343 if( count
+amount
> *cap
)
345 *cap
= VG_MAX( (*cap
)*2, (*cap
)+amount
);
346 return vg_realloc( buffer
, (*cap
) * emsize
);
352 static void *buffer_fix( void *buffer
, u32 count
, u32
*cap
, size_t emsize
)
355 return vg_realloc( buffer
, (*cap
) * emsize
);