1 /*
2  * Copyright 2022 Yonggang Luo
3  * SPDX-License-Identifier: MIT
4  *
5  * C11 <time.h> emulation library
6  */
7 
8 #ifndef C11_TIME_H_INCLUDED_
9 #define C11_TIME_H_INCLUDED_
10 
11 #include <time.h>
12 
13 /*---------------------------- macros ---------------------------*/
14 
15 /* Refer to https://htmlpreview.github.io/?https://icube-forge.unistra.fr/icps/c23-library/-/raw/main/README.html#time_monotonic-time_active-time_thread_active */
16 #if defined(TIME_UTC) && \
17    defined(TIME_MONOTONIC) && \
18    defined(TIME_ACTIVE) && \
19    defined(TIME_THREAD_ACTIVE) && \
20    defined(TIME_MONOTONIC_RAW)
21 /* all needed time base is implemented */
22 #else
23 #define _TIMESPEC_GET_NEED_IMPL
24 #endif
25 
26 #ifdef _TIMESPEC_GET_NEED_IMPL
27 #undef TIME_UTC
28 #undef TIME_MONOTONIC
29 #undef TIME_ACTIVE
30 #undef TIME_THREAD_ACTIVE
31 #undef TIME_MONOTONIC_RAW
32 /* c11 */
33 #define TIME_UTC 1
34 /* c23 */
35 #define TIME_MONOTONIC 2
36 #define TIME_ACTIVE 3
37 #define TIME_THREAD_ACTIVE 4
38 #define TIME_MONOTONIC_RAW 5
39 #define timespec_get c23_timespec_get
40 #endif
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 /*---------------------------- types ----------------------------*/
47 
48 /*
49  * On MINGW `struct timespec` present but `timespec_get` may not present;
50  * On MSVC `struct timespec` and `timespec_get` present at the same time;
51  * So detecting `HAVE_STRUCT_TIMESPEC` in meson script dynamically.
52  */
53 #ifndef HAVE_STRUCT_TIMESPEC
54 struct timespec
55 {
56     time_t tv_sec;  // Seconds - >= 0
57     long   tv_nsec; // Nanoseconds - [0, 999999999]
58 };
59 #endif
60 
61 /*-------------------------- functions --------------------------*/
62 
63 #if defined(_TIMESPEC_GET_NEED_IMPL)
64 #define _TIMESPEC_GET_NEED_DECL
65 #elif defined(__APPLE__) && defined(__cplusplus) && (__cplusplus < 201703L)
66 /* On macOS, the guard for declaration of timespec_get is by
67  * (defined(__cplusplus) && __cplusplus >= 201703L),
68  * fix the declaration for C++14 and lower here
69  */
70 #define _TIMESPEC_GET_NEED_DECL
71 #endif
72 
73 #ifdef _TIMESPEC_GET_NEED_DECL
74 /*-------------------- 7.25.7 Time functions --------------------*/
75 // 7.25.6.1
76 int
77 timespec_get(struct timespec *ts, int base);
78 #undef _TIMESPEC_GET_NEED_DECL
79 #endif
80 
81 #ifdef __cplusplus
82 }
83 #endif
84 
85 #endif /* C11_TIME_H_INCLUDED_ */
86