e5deae28a1a39626b7c1d0eae8ebe64103b9d826
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 static void vg_fatal_exit_loop( const char *error
);
71 static void *vg_alloc( size_t size
)
73 void *ptr
= malloc( size
);
76 vg_fatal_exit_loop( "Out of memory" );
81 static void *vg_realloc( void *orig
, size_t size
)
83 void *ptr
= realloc( orig
, size
);
86 vg_fatal_exit_loop( "Out of memory" );
91 /* seems to be a GCC bug when inlining this, its low priority anyway */
92 __attribute__ ((noinline
))
93 static void vg_free( void *ptr
)
98 static void vg_required( void *ptr
, const char *path
)
102 vg_fatal_exit_loop( path
);
106 #define VG_REQUIRED_ASSET( TYPE, DECL, FN, PATH, ... ) \
107 TYPE DECL = FN( PATH,##__VA_ARGS__ ); \
108 vg_required( DECL, "Resource is required but failed to load: '" PATH "'" );
111 void *malloc( size_t size
);
114 void *realloc( void *orig
, size_t size
);
117 void free( void *ptr
);
127 static int vg_thread_run( void *pfunc
, void *data
);
128 static void vg_thread_exit(void);
129 static void vg_set_thread_name( const char *name
);
130 static int vg_semaphore_init( vg_semaphore
*sem
, u32 value
);
131 static int vg_semaphore_trywait( vg_semaphore
*sem
);
132 static int vg_semaphore_wait( vg_semaphore
*sem
);
133 static int vg_semaphore_post( vg_semaphore
*sem
);
134 static void vg_semaphore_free( vg_semaphore
*sem
);
135 static int vg_mutex_init( vg_mutex
*mutex
);
136 static int vg_mutex_lock( vg_mutex
*mutex
);
137 static int vg_mutex_unlock( vg_mutex
*mutex
);
138 static void vg_mutex_free( vg_mutex
*mutex
);
139 static void vg_sleep_ms( long msec
);
140 static double vg_time_diff( vg_timespec start
, vg_timespec end
);
144 static int vg_thread_run( void *pfunc
, void *data
)
146 HANDLE hThread
= CreateThread
148 NULL
, /* Thread attributes */
149 0, /* Stack size (0 = use default) */
150 pfunc
, /* Thread start address */
151 data
, /* Parameter to pass to the thread */
152 0, /* Creation flags */
156 if ( hThread
== NULL
)
159 * Thread creation failed.
160 * More details can be retrieved by calling GetLastError()
166 CloseHandle( hThread
);
171 static void vg_thread_exit(void)
176 static void vg_set_thread_name( const char *name
)
178 /* I believe this is a meaningless concept in windows */
181 static int vg_semaphore_init( vg_semaphore
*sem
, u32 value
);
182 static int vg_semaphore_trywait( vg_semaphore
*sem
);
183 static int vg_semaphore_wait( vg_semaphore
*sem
);
184 static int vg_semaphore_post( vg_semaphore
*sem
);
185 static void vg_semaphore_free( vg_semaphore
*sem
);
186 static int vg_mutex_init( vg_mutex
*mutex
);
187 static int vg_mutex_lock( vg_mutex
*mutex
);
188 static int vg_mutex_unlock( vg_mutex
*mutex
);
189 static void vg_mutex_free( vg_mutex
*mutex
);
190 static void vg_sleep_ms( long msec
);
191 static double vg_time_diff( vg_timespec start
, vg_timespec end
);
195 static int vg_thread_run( void *pfunc
, void *data
)
198 if( pthread_create( &hThread
, NULL
, pfunc
, data
) )
204 pthread_detach( hThread
);
210 static void vg_thread_exit(void)
215 static void vg_set_thread_name( const char *name
)
217 /* not defined but links?? */
219 pthread_setname_np(pthread_self());
223 static int vg_semaphore_init( vg_semaphore
*sem
, u32 value
)
225 return !sem_init( sem
, 0, value
);
228 static int vg_semaphore_trywait( vg_semaphore
*sem
)
230 return !sem_trywait( sem
);
233 static int vg_semaphore_wait( vg_semaphore
*sem
)
235 return !sem_wait( sem
);
238 static int vg_semaphore_post( vg_semaphore
*sem
)
240 return !sem_post( sem
);
243 static void vg_semaphore_free( vg_semaphore
*sem
)
248 static int vg_mutex_init( vg_mutex
*mutex
)
250 memset( mutex
, 0, sizeof(vg_mutex
) );
254 static int vg_mutex_lock( vg_mutex
*mutex
)
256 if( !pthread_mutex_lock( mutex
) )
262 static int vg_mutex_unlock( vg_mutex
*mutex
)
264 if( !pthread_mutex_unlock( mutex
) )
270 static void vg_mutex_free( vg_mutex
*mutex
)
275 static void vg_sleep_ms( long msec
)
279 ts
.tv_sec
= msec
/ 1000;
280 ts
.tv_nsec
= (msec
% 1000) * 1000000;
281 nanosleep( &ts
, &ts
);
284 /* diff two timespecs in MS */
285 static double vg_time_diff( struct timespec start
, struct timespec end
)
287 double elapsed
= 1000.0*end
.tv_sec
+ 1e-6*end
.tv_nsec
288 - (1000.0*start
.tv_sec
+ 1e-6*start
.tv_nsec
);
295 #define VG_MIN( A, B ) ((A)<(B)?(A):(B))
296 #define VG_MAX( A, B ) ((A)>(B)?(A):(B))
298 static void *buffer_reserve( void *buffer
, u32 count
, u32
*cap
, u32 amount
,
301 if( count
+amount
> *cap
)
303 *cap
= VG_MAX( (*cap
)*2, (*cap
)+amount
);
304 return vg_realloc( buffer
, (*cap
) * emsize
);
310 static void *buffer_fix( void *buffer
, u32 count
, u32
*cap
, size_t emsize
)
313 return vg_realloc( buffer
, (*cap
) * emsize
);