Flecs v3.2
A fast entity component system (ECS) for C & C++
Loading...
Searching...
No Matches
os_api.h
Go to the documentation of this file.
1
13#ifndef FLECS_OS_API_H
14#define FLECS_OS_API_H
15
24#include <stdarg.h>
25#include <errno.h>
26
27#if defined(ECS_TARGET_WINDOWS)
28#include <malloc.h>
29#elif defined(ECS_TARGET_FREEBSD)
30#include <stdlib.h>
31#else
32#include <alloca.h>
33#endif
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39typedef struct ecs_time_t {
40 uint32_t sec;
41 uint32_t nanosec;
43
44/* Allocation counters */
45extern int64_t ecs_os_api_malloc_count;
46extern int64_t ecs_os_api_realloc_count;
47extern int64_t ecs_os_api_calloc_count;
48extern int64_t ecs_os_api_free_count;
49
50/* Use handle types that _at least_ can store pointers */
51typedef uintptr_t ecs_os_thread_t;
52typedef uintptr_t ecs_os_cond_t;
53typedef uintptr_t ecs_os_mutex_t;
54typedef uintptr_t ecs_os_dl_t;
55typedef uintptr_t ecs_os_sock_t;
56
57/* 64 bit thread id */
58typedef uint64_t ecs_os_thread_id_t;
59
60/* Generic function pointer type */
61typedef void (*ecs_os_proc_t)(void);
62
63/* OS API init */
64typedef
65void (*ecs_os_api_init_t)(void);
66
67/* OS API deinit */
68typedef
69void (*ecs_os_api_fini_t)(void);
70
71/* Memory management */
72typedef
73void* (*ecs_os_api_malloc_t)(
74 ecs_size_t size);
75
76typedef
77void (*ecs_os_api_free_t)(
78 void *ptr);
79
80typedef
81void* (*ecs_os_api_realloc_t)(
82 void *ptr,
83 ecs_size_t size);
84
85typedef
86void* (*ecs_os_api_calloc_t)(
87 ecs_size_t size);
88
89typedef
90char* (*ecs_os_api_strdup_t)(
91 const char *str);
92
93/* Threads */
94typedef
95void* (*ecs_os_thread_callback_t)(
96 void*);
97
98typedef
99ecs_os_thread_t (*ecs_os_api_thread_new_t)(
100 ecs_os_thread_callback_t callback,
101 void *param);
102
103typedef
104void* (*ecs_os_api_thread_join_t)(
105 ecs_os_thread_t thread);
106
107typedef
108ecs_os_thread_id_t (*ecs_os_api_thread_self_t)(void);
109
110/* Tasks */
111typedef
112ecs_os_thread_t (*ecs_os_api_task_new_t)(
113 ecs_os_thread_callback_t callback,
114 void *param);
115
116typedef
117void* (*ecs_os_api_task_join_t)(
118 ecs_os_thread_t thread);
119
120/* Atomic increment / decrement */
121typedef
122int32_t (*ecs_os_api_ainc_t)(
123 int32_t *value);
124
125typedef
126int64_t (*ecs_os_api_lainc_t)(
127 int64_t *value);
128
129/* Mutex */
130typedef
131ecs_os_mutex_t (*ecs_os_api_mutex_new_t)(
132 void);
133
134typedef
135void (*ecs_os_api_mutex_lock_t)(
136 ecs_os_mutex_t mutex);
137
138typedef
139void (*ecs_os_api_mutex_unlock_t)(
140 ecs_os_mutex_t mutex);
141
142typedef
143void (*ecs_os_api_mutex_free_t)(
144 ecs_os_mutex_t mutex);
145
146/* Condition variable */
147typedef
148ecs_os_cond_t (*ecs_os_api_cond_new_t)(
149 void);
150
151typedef
152void (*ecs_os_api_cond_free_t)(
153 ecs_os_cond_t cond);
154
155typedef
156void (*ecs_os_api_cond_signal_t)(
157 ecs_os_cond_t cond);
158
159typedef
160void (*ecs_os_api_cond_broadcast_t)(
161 ecs_os_cond_t cond);
162
163typedef
164void (*ecs_os_api_cond_wait_t)(
165 ecs_os_cond_t cond,
166 ecs_os_mutex_t mutex);
167
168typedef
169void (*ecs_os_api_sleep_t)(
170 int32_t sec,
171 int32_t nanosec);
172
173typedef
174void (*ecs_os_api_enable_high_timer_resolution_t)(
175 bool enable);
176
177typedef
178void (*ecs_os_api_get_time_t)(
179 ecs_time_t *time_out);
180
181typedef
182uint64_t (*ecs_os_api_now_t)(void);
183
184/* Logging */
185typedef
186void (*ecs_os_api_log_t)(
187 int32_t level, /* Logging level */
188 const char *file, /* File where message was logged */
189 int32_t line, /* Line it was logged */
190 const char *msg);
191
192/* Application termination */
193typedef
194void (*ecs_os_api_abort_t)(
195 void);
196
197/* Dynamic libraries */
198typedef
199ecs_os_dl_t (*ecs_os_api_dlopen_t)(
200 const char *libname);
201
202typedef
203ecs_os_proc_t (*ecs_os_api_dlproc_t)(
204 ecs_os_dl_t lib,
205 const char *procname);
206
207typedef
208void (*ecs_os_api_dlclose_t)(
209 ecs_os_dl_t lib);
210
211typedef
212char* (*ecs_os_api_module_to_path_t)(
213 const char *module_id);
214
215/* Prefix members of struct with 'ecs_' as some system headers may define
216 * macros for functions like "strdup", "log" or "_free" */
217
218typedef struct ecs_os_api_t {
219 /* API init / deinit */
220 ecs_os_api_init_t init_;
221 ecs_os_api_fini_t fini_;
222
223 /* Memory management */
224 ecs_os_api_malloc_t malloc_;
225 ecs_os_api_realloc_t realloc_;
226 ecs_os_api_calloc_t calloc_;
227 ecs_os_api_free_t free_;
228
229 /* Strings */
230 ecs_os_api_strdup_t strdup_;
231
232 /* Threads */
233 ecs_os_api_thread_new_t thread_new_;
234 ecs_os_api_thread_join_t thread_join_;
235 ecs_os_api_thread_self_t thread_self_;
236
237 /* Tasks */
238 ecs_os_api_thread_new_t task_new_;
239 ecs_os_api_thread_join_t task_join_;
240
241 /* Atomic incremenet / decrement */
242 ecs_os_api_ainc_t ainc_;
243 ecs_os_api_ainc_t adec_;
244 ecs_os_api_lainc_t lainc_;
245 ecs_os_api_lainc_t ladec_;
246
247 /* Mutex */
248 ecs_os_api_mutex_new_t mutex_new_;
249 ecs_os_api_mutex_free_t mutex_free_;
250 ecs_os_api_mutex_lock_t mutex_lock_;
251 ecs_os_api_mutex_lock_t mutex_unlock_;
252
253 /* Condition variable */
254 ecs_os_api_cond_new_t cond_new_;
255 ecs_os_api_cond_free_t cond_free_;
256 ecs_os_api_cond_signal_t cond_signal_;
257 ecs_os_api_cond_broadcast_t cond_broadcast_;
258 ecs_os_api_cond_wait_t cond_wait_;
259
260 /* Time */
261 ecs_os_api_sleep_t sleep_;
262 ecs_os_api_now_t now_;
263 ecs_os_api_get_time_t get_time_;
264
265 /* Logging */
266 ecs_os_api_log_t log_; /* Logging function. The level should be interpreted as: */
267 /* >0: Debug tracing. Only enabled in debug builds. */
268 /* 0: Tracing. Enabled in debug/release builds. */
269 /* -2: Warning. An issue occurred, but operation was successful. */
270 /* -3: Error. An issue occurred, and operation was unsuccessful. */
271 /* -4: Fatal. An issue occurred, and application must quit. */
272
273 /* Application termination */
274 ecs_os_api_abort_t abort_;
275
276 /* Dynamic library loading */
277 ecs_os_api_dlopen_t dlopen_;
278 ecs_os_api_dlproc_t dlproc_;
279 ecs_os_api_dlclose_t dlclose_;
280
281 /* Overridable function that translates from a logical module id to a
282 * shared library filename */
283 ecs_os_api_module_to_path_t module_to_dl_;
284
285 /* Overridable function that translates from a logical module id to a
286 * path that contains module-specif resources or assets */
287 ecs_os_api_module_to_path_t module_to_etc_;
288
289 /* Trace level */
290 int32_t log_level_;
291
292 /* Trace indentation */
293 int32_t log_indent_;
294
295 /* Last error code */
296 int32_t log_last_error_;
297
298 /* Last recorded timestamp */
299 int64_t log_last_timestamp_;
300
301 /* OS API flags */
302 ecs_flags32_t flags_;
304
305FLECS_API
306extern ecs_os_api_t ecs_os_api;
307
308FLECS_API
309void ecs_os_init(void);
310
311FLECS_API
312void ecs_os_fini(void);
313
314FLECS_API
315void ecs_os_set_api(
316 ecs_os_api_t *os_api);
317
318FLECS_API
319ecs_os_api_t ecs_os_get_api(void);
320
321FLECS_API
322void ecs_os_set_api_defaults(void);
323
324/* Memory management */
325#ifndef ecs_os_malloc
326#define ecs_os_malloc(size) ecs_os_api.malloc_(size)
327#endif
328#ifndef ecs_os_free
329#define ecs_os_free(ptr) ecs_os_api.free_(ptr)
330#endif
331#ifndef ecs_os_realloc
332#define ecs_os_realloc(ptr, size) ecs_os_api.realloc_(ptr, size)
333#endif
334#ifndef ecs_os_calloc
335#define ecs_os_calloc(size) ecs_os_api.calloc_(size)
336#endif
337#if defined(ECS_TARGET_WINDOWS)
338#define ecs_os_alloca(size) _alloca((size_t)(size))
339#else
340#define ecs_os_alloca(size) alloca((size_t)(size))
341#endif
342
343#define ecs_os_malloc_t(T) ECS_CAST(T*, ecs_os_malloc(ECS_SIZEOF(T)))
344#define ecs_os_malloc_n(T, count) ECS_CAST(T*, ecs_os_malloc(ECS_SIZEOF(T) * (count)))
345#define ecs_os_calloc_t(T) ECS_CAST(T*, ecs_os_calloc(ECS_SIZEOF(T)))
346#define ecs_os_calloc_n(T, count) ECS_CAST(T*, ecs_os_calloc(ECS_SIZEOF(T) * (count)))
347
348#define ecs_os_realloc_t(ptr, T) ECS_CAST(T*, ecs_os_realloc([ptr, ECS_SIZEOF(T)))
349#define ecs_os_realloc_n(ptr, T, count) ECS_CAST(T*, ecs_os_realloc(ptr, ECS_SIZEOF(T) * (count)))
350#define ecs_os_alloca_t(T) ECS_CAST(T*, ecs_os_alloca(ECS_SIZEOF(T)))
351#define ecs_os_alloca_n(T, count) ECS_CAST(T*, ecs_os_alloca(ECS_SIZEOF(T) * (count)))
352
353/* Strings */
354#ifndef ecs_os_strdup
355#define ecs_os_strdup(str) ecs_os_api.strdup_(str)
356#endif
357
358#ifdef __cplusplus
359#define ecs_os_strlen(str) static_cast<ecs_size_t>(strlen(str))
360#define ecs_os_strncmp(str1, str2, num) strncmp(str1, str2, static_cast<size_t>(num))
361#define ecs_os_memcmp(ptr1, ptr2, num) memcmp(ptr1, ptr2, static_cast<size_t>(num))
362#define ecs_os_memcpy(ptr1, ptr2, num) memcpy(ptr1, ptr2, static_cast<size_t>(num))
363#define ecs_os_memset(ptr, value, num) memset(ptr, value, static_cast<size_t>(num))
364#define ecs_os_memmove(dst, src, size) memmove(dst, src, static_cast<size_t>(size))
365#else
366#define ecs_os_strlen(str) (ecs_size_t)strlen(str)
367#define ecs_os_strncmp(str1, str2, num) strncmp(str1, str2, (size_t)(num))
368#define ecs_os_memcmp(ptr1, ptr2, num) memcmp(ptr1, ptr2, (size_t)(num))
369#define ecs_os_memcpy(ptr1, ptr2, num) memcpy(ptr1, ptr2, (size_t)(num))
370#define ecs_os_memset(ptr, value, num) memset(ptr, value, (size_t)(num))
371#define ecs_os_memmove(dst, src, size) memmove(dst, src, (size_t)(size))
372#endif
373
374#define ecs_os_memcpy_t(ptr1, ptr2, T) ecs_os_memcpy(ptr1, ptr2, ECS_SIZEOF(T))
375#define ecs_os_memcpy_n(ptr1, ptr2, T, count) ecs_os_memcpy(ptr1, ptr2, ECS_SIZEOF(T) * count)
376#define ecs_os_memcmp_t(ptr1, ptr2, T) ecs_os_memcmp(ptr1, ptr2, ECS_SIZEOF(T))
377
378#define ecs_os_strcmp(str1, str2) strcmp(str1, str2)
379#define ecs_os_memset_t(ptr, value, T) ecs_os_memset(ptr, value, ECS_SIZEOF(T))
380#define ecs_os_memset_n(ptr, value, T, count) ecs_os_memset(ptr, value, ECS_SIZEOF(T) * count)
381#define ecs_os_zeromem(ptr) ecs_os_memset(ptr, 0, ECS_SIZEOF(*ptr))
382
383#define ecs_os_memdup_t(ptr, T) ecs_os_memdup(ptr, ECS_SIZEOF(T))
384#define ecs_os_memdup_n(ptr, T, count) ecs_os_memdup(ptr, ECS_SIZEOF(T) * count)
385
386#define ecs_offset(ptr, T, index)\
387 ECS_CAST(T*, ECS_OFFSET(ptr, ECS_SIZEOF(T) * index))
388
389#if defined(ECS_TARGET_MSVC)
390#define ecs_os_strcat(str1, str2) strcat_s(str1, INT_MAX, str2)
391#define ecs_os_sprintf(ptr, ...) sprintf_s(ptr, INT_MAX, __VA_ARGS__)
392#define ecs_os_vsprintf(ptr, fmt, args) vsprintf_s(ptr, INT_MAX, fmt, args)
393#define ecs_os_strcpy(str1, str2) strcpy_s(str1, INT_MAX, str2)
394#ifdef __cplusplus
395#define ecs_os_strncpy(str1, str2, num) strncpy_s(str1, INT_MAX, str2, static_cast<size_t>(num))
396#else
397#define ecs_os_strncpy(str1, str2, num) strncpy_s(str1, INT_MAX, str2, (size_t)(num))
398#endif
399#else
400#define ecs_os_strcat(str1, str2) strcat(str1, str2)
401#define ecs_os_sprintf(ptr, ...) sprintf(ptr, __VA_ARGS__)
402#define ecs_os_vsprintf(ptr, fmt, args) vsprintf(ptr, fmt, args)
403#define ecs_os_strcpy(str1, str2) strcpy(str1, str2)
404#ifdef __cplusplus
405#define ecs_os_strncpy(str1, str2, num) strncpy(str1, str2, static_cast<size_t>(num))
406#else
407#define ecs_os_strncpy(str1, str2, num) strncpy(str1, str2, (size_t)(num))
408#endif
409#endif
410
411/* Files */
412#if defined(ECS_TARGET_MSVC)
413#define ecs_os_fopen(result, file, mode) fopen_s(result, file, mode)
414#else
415#define ecs_os_fopen(result, file, mode) (*(result)) = fopen(file, mode)
416#endif
417
418/* Threads */
419#define ecs_os_thread_new(callback, param) ecs_os_api.thread_new_(callback, param)
420#define ecs_os_thread_join(thread) ecs_os_api.thread_join_(thread)
421#define ecs_os_thread_self() ecs_os_api.thread_self_()
422
423/* Tasks */
424#define ecs_os_task_new(callback, param) ecs_os_api.task_new_(callback, param)
425#define ecs_os_task_join(thread) ecs_os_api.task_join_(thread)
426
427/* Atomic increment / decrement */
428#define ecs_os_ainc(value) ecs_os_api.ainc_(value)
429#define ecs_os_adec(value) ecs_os_api.adec_(value)
430#define ecs_os_lainc(value) ecs_os_api.lainc_(value)
431#define ecs_os_ladec(value) ecs_os_api.ladec_(value)
432
433/* Mutex */
434#define ecs_os_mutex_new() ecs_os_api.mutex_new_()
435#define ecs_os_mutex_free(mutex) ecs_os_api.mutex_free_(mutex)
436#define ecs_os_mutex_lock(mutex) ecs_os_api.mutex_lock_(mutex)
437#define ecs_os_mutex_unlock(mutex) ecs_os_api.mutex_unlock_(mutex)
438
439/* Condition variable */
440#define ecs_os_cond_new() ecs_os_api.cond_new_()
441#define ecs_os_cond_free(cond) ecs_os_api.cond_free_(cond)
442#define ecs_os_cond_signal(cond) ecs_os_api.cond_signal_(cond)
443#define ecs_os_cond_broadcast(cond) ecs_os_api.cond_broadcast_(cond)
444#define ecs_os_cond_wait(cond, mutex) ecs_os_api.cond_wait_(cond, mutex)
445
446/* Time */
447#define ecs_os_sleep(sec, nanosec) ecs_os_api.sleep_(sec, nanosec)
448#define ecs_os_now() ecs_os_api.now_()
449#define ecs_os_get_time(time_out) ecs_os_api.get_time_(time_out)
450
451/* Logging */
452FLECS_API
453void ecs_os_dbg(const char *file, int32_t line, const char *msg);
454
455FLECS_API
456void ecs_os_trace(const char *file, int32_t line, const char *msg);
457
458FLECS_API
459void ecs_os_warn(const char *file, int32_t line, const char *msg);
460
461FLECS_API
462void ecs_os_err(const char *file, int32_t line, const char *msg);
463
464FLECS_API
465void ecs_os_fatal(const char *file, int32_t line, const char *msg);
466
467FLECS_API
468const char* ecs_os_strerror(int err);
469
470FLECS_API
471void ecs_os_strset(char **str, const char *value);
472
473#ifdef FLECS_ACCURATE_COUNTERS
474#define ecs_os_inc(v) (ecs_os_ainc(v))
475#define ecs_os_linc(v) (ecs_os_lainc(v))
476#define ecs_os_dec(v) (ecs_os_adec(v))
477#define ecs_os_ldec(v) (ecs_os_ladec(v))
478#else
479#define ecs_os_inc(v) (++(*v))
480#define ecs_os_linc(v) (++(*v))
481#define ecs_os_dec(v) (--(*v))
482#define ecs_os_ldec(v) (--(*v))
483#endif
484
485/* Application termination */
486#define ecs_os_abort() ecs_os_api.abort_()
487
488/* Dynamic libraries */
489#define ecs_os_dlopen(libname) ecs_os_api.dlopen_(libname)
490#define ecs_os_dlproc(lib, procname) ecs_os_api.dlproc_(lib, procname)
491#define ecs_os_dlclose(lib) ecs_os_api.dlclose_(lib)
492
493/* Module id translation */
494#define ecs_os_module_to_dl(lib) ecs_os_api.module_to_dl_(lib)
495#define ecs_os_module_to_etc(lib) ecs_os_api.module_to_etc_(lib)
496
497/* Sleep with floating point time */
498FLECS_API
499void ecs_sleepf(
500 double t);
501
502/* Measure time since provided timestamp */
503FLECS_API
504double ecs_time_measure(
506
507/* Calculate difference between two timestamps */
508FLECS_API
509ecs_time_t ecs_time_sub(
510 ecs_time_t t1,
511 ecs_time_t t2);
512
513/* Convert time value to a double */
514FLECS_API
515double ecs_time_to_double(
516 ecs_time_t t);
517
518FLECS_API
519void* ecs_os_memdup(
520 const void *src,
521 ecs_size_t size);
522
524FLECS_API
526
528FLECS_API
530
532FLECS_API
534
536FLECS_API
538
540FLECS_API
542
544FLECS_API
545bool ecs_os_has_dl(void);
546
548FLECS_API
550
551#ifdef __cplusplus
552}
553#endif
554
557#endif
FLECS_API bool ecs_os_has_time(void)
Are time functions available?
FLECS_API bool ecs_os_has_dl(void)
Are dynamic library functions available?
FLECS_API bool ecs_os_has_logging(void)
Are logging functions available?
FLECS_API bool ecs_os_has_modules(void)
Are module path functions available?
FLECS_API bool ecs_os_has_task_support(void)
Are task functions available?
FLECS_API bool ecs_os_has_threading(void)
Are threading functions available?
FLECS_API bool ecs_os_has_heap(void)
Are heap functions available?
void start()
Start timer.