Zen API
 All Classes Files Functions Variables Typedefs Friends Macros Modules Pages
kApiCfg.h
Go to the documentation of this file.
1 
10 #ifndef K_API_API_CFG_H
11 #define K_API_API_CFG_H
12 
13 /* Detect the compiler family; fall back to GCC as default. */
14 #if defined(_MSC_VER)
15 # define K_MSVC
16 #else
17 # define K_GCC
18 #endif
19 
20 /* Helpful constants that can be compared with K_CPP_VERSION (defined below). */
21 #define K_CPP_VERSION_1998 (199711L)
22 #define K_CPP_VERSION_2011 (201103L)
23 #define K_CPP_VERSION_2014 (201402L)
24 #define K_CPP_VERSION_2017 (201703L)
25 
26 /*
27 * Detect language; K_CPP is defined only if the compiler is a C++ compiler; K_CPP_VERSION is
28 * always defined, but will have a definition of -1 if the compiler is a C compiler. */
29 #if defined(__cplusplus)
30 
31 # if defined(_MSVC_LANG)
32 # define K_CPP _MSVC_LANG
33 # else
34 # define K_CPP __cplusplus
35 # endif
36 
37 # if (K_CPP < K_CPP_VERSION_1998)
38 # undef K_CPP
39 # define K_CPP K_CPP_VERSION_1998
40 # endif
41 
42 # define K_CPP_VERSION K_CPP
43 
44 #else
45 
46 # define K_CPP_VERSION -1
47 
48 #endif
49 
50 #if defined(__cplusplus_cli)
51 # define K_CPP_CLI
52 #endif
53 
54 /* Detect the OS; fall back to non-specific POSIX as default. */
55 #if defined(_WIN32) || defined(_WIN64)
56 # define K_WINDOWS
57 #else
58 # define K_POSIX
59 # if defined(__linux__)
60 # define K_LINUX
61 # endif
62 # if defined(__APPLE__)
63 # define K_DARWIN
64 # endif
65 # if defined(__QNXNTO__)
66 # define K_QNX
67 # endif
68 #endif
69 
70 /* Code profiling always enabled in debug builds. */
71 #if defined(K_DEBUG)
72 # define K_PROFILE
73 #endif
74 
75 #if defined(K_DEBUG)
76 # define K_DEBUG_ENABLED (1)
77 #else
78 # define K_DEBUG_ENABLED (0)
79 #endif
80 
81 #if defined(K_PROFILE)
82 # define K_PROFILE_ENABLED (1)
83 #else
84 # define K_PROFILE_ENABLED (0)
85 #endif
86 
87 #if (defined(K_DEBUG) || defined(K_ASSERT)) && !defined(K_NO_ASSERT)
88 # define K_ASSERT_ENABLED (1)
89 #else
90 # define K_ASSERT_ENABLED (0)
91 #endif
92 
93 /* Provide shorter symbol to use when checking for Cuda support. */
94 #if defined(K_HAVE_CUDA)
95 # define K_CUDA
96 #endif
97 
98 /*
99  * Include some C standard headers that we heavily rely on. This list is subject to change;
100  * dependent code should not assume that these headers will always be included here.
101  */
102 #if defined(K_MSVC) && defined(K_DEBUG)
103 # define _CRTDBG_MAP_ALLOC
104 # include <stdlib.h>
105 # include <crtdbg.h>
106 #else
107 # include <stdlib.h>
108 #endif
109 
110 #include <stdarg.h>
111 #include <stddef.h>
112 #include <string.h>
113 
114 #if defined(K_MSVC)
115 # include <intrin.h>
116 #endif
117 
118 #if (K_CPP_VERSION >= K_CPP_VERSION_2011)
119 # include <type_traits>
120 #endif
121 
122 /* Utilty macros for stringizing macro arguments. */
123 #define xkStringize(X) #X
124 #define xkStringizeDefine(X) xkStringize(X)
125 
126 /*
127  * Detect pointer size; raise an eror if the pointer size cannot be detected. The behaviour
128  * can be overridden by defining K_POINTER_SIZE as a compiler flag.
129  */
130 #if !defined(K_POINTER_SIZE)
131 # if defined(_WIN64) || defined(WIN64)
132 # define K_POINTER_SIZE (8)
133 # elif defined(_WIN32) || defined(WIN32)
134 # define K_POINTER_SIZE (4)
135 # elif defined(__SIZEOF_POINTER__)
136 # define K_POINTER_SIZE (__SIZEOF_POINTER__)
137 # elif defined(__LP64__) || defined(__LLP64__) || defined(__SILP64__)
138 # define K_POINTER_SIZE (8)
139 # elif defined(__LP32__) || defined(__ILP32__)
140 # define K_POINTER_SIZE (4)
141 # elif defined(_TMS320C6X)
142 # define K_POINTER_SIZE (4)
143 # else
144 # error "Pointer size not detected; define K_POINTER_SIZE as compiler flag."
145 # endif
146 #endif
147 
148 #if (K_POINTER_SIZE == 8)
149 # define K_POINTER_SHIFT (3)
150 #elif (K_POINTER_SIZE == 4)
151 # define K_POINTER_SHIFT (2)
152 #endif
153 
154 /*
155  * Detect endianness; fall back to little endian as default. The behaviour can be overridden
156  * by defining K_ENDIANNESS as a compiler flag.
157  */
158 #if !defined(K_ENDIANNESS)
159 # if defined(K_GCC) && defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
160 # define K_ENDIANNESS (kENDIANNESS_BIG)
161 # else
162 # define K_ENDIANNESS (kENDIANNESS_LITTLE)
163 # endif
164 #endif
165 
166 #if defined(K_CPP)
167 # define kExtern extern "C"
168 #else
169 # define kExtern extern
170 #endif
171 
172 #if defined(K_GCC)
173 # define K_ATTRIBUTE_UNUSED __attribute__((unused))
174 #elif defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L)
175 # define K_ATTRIBUTE_UNUSED [[maybe_unused]]
176 #else
177 # define K_ATTRIBUTE_UNUSED
178 # if defined(K_MSVC) && !defined(K_WARNINGS_ALL)
179 # pragma warning(disable: 4189)
180 # endif
181 #endif
182 
183 #if defined(K_WINDOWS)
184 # if defined(K_GCC)
185 # define K_ATTRIBUTE_EXPORT __attribute__((dllexport))
186 # define K_ATTRIBUTE_IMPORT __attribute__((dllimport))
187 # else
188 # define K_ATTRIBUTE_EXPORT __declspec(dllexport)
189 # define K_ATTRIBUTE_IMPORT __declspec(dllimport)
190 # endif
191 #else
192 # if defined(K_GCC)
193 # define K_ATTRIBUTE_EXPORT __attribute__((visibility ("default")))
194 # define K_ATTRIBUTE_IMPORT
195 # else
196 # define K_ATTRIBUTE_EXPORT
197 # define K_ATTRIBUTE_IMPORT
198 # endif
199 #endif
200 
201 #if (K_CPP_VERSION >= K_CPP_VERSION_2014)
202 # define kDeprecateEx [[deprecated]]
203 #else
204 # define kDeprecateEx
205 #endif
206 
207 /* Define primitive data types and calling conventions. */
208 #if defined(K_MSVC)
209 
210 # define xkCall __stdcall
211 # define xkDlCall __cdecl
212 
213 # if _MSC_VER >= 1500
214 # define kInline __inline
215 # else
216 # define kInline
217 # endif
218 
219  typedef unsigned __int8 xk8u;
220  typedef unsigned __int16 xk16u;
221  typedef unsigned __int32 xk32u;
222  typedef unsigned __int64 xk64u;
223  typedef __int8 xk8s;
224  typedef __int16 xk16s;
225  typedef __int32 xk32s;
226  typedef __int64 xk64s;
227  typedef float xk32f;
228  typedef double xk64f;
229  typedef char xkChar;
230  typedef unsigned char xkByte;
231 
232 # define xk64U(CONSTANT) (CONSTANT##ui64)
233 # define xk64S(CONSTANT) (CONSTANT##i64)
234 
235 #else
236 
237 # define xkCall
238 # define xkDlCall
239 
240 # define kInline inline
241 
242  typedef unsigned char xk8u;
243  typedef unsigned short xk16u;
244  typedef unsigned int xk32u;
245  typedef unsigned long long xk64u;
246  typedef signed char xk8s;
247  typedef signed short xk16s;
248  typedef signed int xk32s;
249  typedef signed long long xk64s;
250  typedef float xk32f;
251  typedef double xk64f;
252  typedef char xkChar;
253  typedef unsigned char xkByte;
254 
255 # define xk64U(CONSTANT) (CONSTANT##LLU)
256 # define xk64S(CONSTANT) (CONSTANT##LL)
257 
258 #endif
259 
260 #define kExportFx(TYPE) kExtern K_ATTRIBUTE_EXPORT TYPE kCall
261 #define kImportFx(TYPE) kExtern K_ATTRIBUTE_IMPORT TYPE kCall
262 
263 #define kExportCx(TYPE) kExtern K_ATTRIBUTE_EXPORT TYPE xkDlCall
264 #define kImportCx(TYPE) kExtern K_ATTRIBUTE_IMPORT TYPE xkDlCall
265 
266 #define kExportDx(TYPE) K_ATTRIBUTE_EXPORT TYPE
267 #define kImportDx(TYPE) K_ATTRIBUTE_IMPORT TYPE
268 
269 #define kInFx(TYPE) kExtern TYPE kCall
270 #define kInCx(TYPE) kExtern TYPE kCall
271 #define kInDx(TYPE) TYPE
272 
273 #define kExport K_ATTRIBUTE_EXPORT
274 #define kImport K_ATTRIBUTE_IMPORT
275 
276 #define kExportEx(TYPE) K_ATTRIBUTE_EXPORT TYPE
277 #define kImportEx(TYPE) K_ATTRIBUTE_IMPORT TYPE
278 
279 #define xkInlineFx(TYPE) static kInline TYPE kCall
280 
281 #if (K_POINTER_SIZE == 4)
282 
283 typedef xk32u xkSize;
284 # define xkSIZE_MAX k32U_MAX
285 
286 typedef xk32s xkSSize;
287 # define xkSSIZE_MIN k32S_MIN
288 # define xkSSIZE_MAX k32S_MAX
289 
290 #elif (K_POINTER_SIZE == 8)
291 
292 typedef xk64u xkSize;
293 # define xkSIZE_MAX k64U_MAX
294 
295 typedef xk64s xkSSize;
296 # define xkSSIZE_MIN k64S_MIN
297 # define xkSSIZE_MAX k64S_MAX
298 
299 #endif
300 
301 #define kALIGN_ANY (kMEMORY_ALIGNMENT_16)
302 #define kALIGN_ANY_SIZE (1 << kALIGN_ANY)
303 
304 #define kVarArgList va_list
305 
306 #if defined(K_MSVC)
307 # define kVarArgList_Start(ARG_PTR, PREV_PARAM) va_start(ARG_PTR, PREV_PARAM)
308 # define kVarArgList_End(ARG_PTR) va_end(ARG_PTR)
309 # define kVarArgList_Copy(ARG_PTR, SOURCE) ((ARG_PTR) = (SOURCE))
310 # define kVarArgList_Next(ARG_PTR, TYPE) va_arg(ARG_PTR, TYPE)
311 #else
312 # define kVarArgList_Start(ARG_PTR, PREV_PARAM) va_start(ARG_PTR, PREV_PARAM)
313 # define kVarArgList_End(ARG_PTR) va_end(ARG_PTR)
314 # define kVarArgList_Copy(ARG_PTR, SOURCE) va_copy(ARG_PTR, SOURCE)
315 # define kVarArgList_Next(ARG_PTR, TYPE) va_arg(ARG_PTR, TYPE)
316 #endif
317 
318 
319 /* Deprecation support. */
320 #if !defined(K_NO_DEPRECATION)
321 # if defined(K_MSVC)
322 # define xkDeprecate(SYMBOL) __pragma(deprecated(SYMBOL))
323 # else
324 # define xkDeprecate(SYMBOL)
325 # endif
326 #else
327 # define xkDeprecate(SYMBOL)
328 #endif
329 
330 /* Warning support. */
331 #if defined(K_MSVC)
332 
333 # define xkWarn(MESSAGE) __pragma(message(__FILE__ "(" xkStringizeDefine(__LINE__) "): warning: " MESSAGE))
334 
335 #elif defined(K_GCC)
336 
337 # define xkWarnHelper(x) _Pragma (#x)
338 # define xkWarn(MESSAGE) xkWarnHelper(GCC warning MESSAGE)
339 
340 #else
341 
342 # define xkWarn(MESSAGE)
343 
344 #endif
345 
346 /* Software breakpoint support. */
347 #if defined(K_DEBUG) && defined(K_MSVC)
348 # define xkDebugBreak() __debugbreak()
349 #else
350 # define xkDebugBreak()
351 #endif
352 
353 #if defined (K_CPP)
354 # define kBeginCHeader() extern "C" {
355 # define kEndCHeader() }
356 #else
357 # define kBeginCHeader()
358 # define kEndCHeader()
359 #endif
360 
361 
362 /*
363  * Some source files require platform library headers to be included. And, at least
364  * for Windows, there can sometimes exist complicated rules about the particular order
365  * in which headers have to be included. The K_PLATFORM symbol helps to deal with
366  * these issues.
367  *
368  * Any kApi source file that requires platform headers should have #define K_PLATFORM as the
369  * first line in the source file. This ensures that the most common platform headers are
370  * included here, in the correct order.
371  */
372 #if defined(K_PLATFORM)
373 
374 /*
375  * Common for all platforms.
376  */
377 # include <assert.h>
378 
379 /*
380  * Platform specific includes.
381  */
382 # if defined(K_WINDOWS)
383 # include <winsock2.h>
384 # include <mswsock.h>
385 # include <ws2tcpip.h>
386 # include <iphlpapi.h>
387 # include <windows.h>
388 # include <process.h>
389 # endif
390 # if defined(K_POSIX)
391 # include <errno.h>
392 # include <unistd.h>
393 # include <pthread.h>
394 # include <semaphore.h>
395 # include <sys/types.h>
396 # include <sys/stat.h>
397 # if defined(K_QNX)
398 # include <fcntl.h>
399 # else
400 # include <sys/fcntl.h>
401 # endif
402 # include <sys/socket.h>
403 # include <sys/select.h>
404 # include <sys/syscall.h>
405 # include <sys/ioctl.h>
406 # include <sys/resource.h>
407 # include <sys/time.h>
408 # include <sys/timeb.h>
409 # include <netinet/in.h>
410 # include <netinet/tcp.h>
411 # include <dlfcn.h>
412 # include <dirent.h>
413 # include <net/if.h>
414 # include <net/if_arp.h>
415 # include <ifaddrs.h> /* not technically posix, but seemingly supported everywhere that matters */
416 # include <netdb.h>
417 
418 # endif
419 # if defined(K_DARWIN)
420 # include <mach-o/dyld.h>
421 # endif
422 # if defined (K_LINUX)
423 # include <signal.h>
424 # include <sys/prctl.h>
425 # include <sys/wait.h>
426 # include <linux/sockios.h>
427 # include <linux/ethtool.h>
428 # include <linux/netlink.h>
429 # include <linux/rtnetlink.h>
430 # endif
431 #endif
432 
433 typedef volatile xk32s xkAtomic32s;
434 typedef volatile xk64s xkAtomic64s;
435 typedef void* volatile xkAtomicPointer;
436 
437 #if defined(K_PLATFORM)
438 # if defined(K_WINDOWS)
439 # define kOS_INFINITE INFINITE
440  typedef DWORD xkThreadId;
441 # elif defined(K_POSIX)
442 # define kOS_INFINITE 0 /* no special "infinite" value */
443  typedef pthread_t xkThreadId;
444 # endif
445 #endif
446 
447 #if defined(K_PLATFORM) && defined (K_POSIX)
448 # if defined (K_LINUX) && defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 30)
449 # define sem_timedwait_(SEM, ABSTIME) sem_clockwait(SEM, CLOCK_MONOTONIC, ABSTIME)
450 # define pthread_mutex_timedlock_(MUTEX, ABSTIME) pthread_mutex_clocklock(MUTEX, CLOCK_MONOTONIC, ABSTIME)
451 # define pthread_cond_timedwait_(COND, MUTEX, ABSTIME) pthread_cond_clockwait(COND, MUTEX, CLOCK_MONOTONIC, ABSTIME)
452 # define clock_gettime_(ABSTIME) clock_gettime(CLOCK_MONOTONIC, ABSTIME)
453 # else
454 # define sem_timedwait_(SEM, ABSTIME) sem_timedwait(SEM, ABSTIME)
455 # define pthread_mutex_timedlock_(MUTEX, ABSTIME) pthread_mutex_timedlock(MUTEX, ABSTIME)
456 # define pthread_cond_timedwait_(COND, MUTEX, ABSTIME) pthread_cond_timedwait(COND, MUTEX, ABSTIME)
457 # define clock_gettime_(ABSTIME) clock_gettime(CLOCK_REALTIME, ABSTIME)
458 # endif
459 #endif
460 
461 /*
462 * Deprecated (Stage 1): not recommended for further use, but not yet announced via kDeprecate
463 */
464 
465 #if defined (K_CPP)
466 
467  //[Deprecated] No longer required; provided that any C functions are properly annotated.
468  //Use kBeginCHeader/kEndCHeader to include a C header from C++ if the header was not designed to support C++.
469 # define kBeginHeader() extern "C" {
470 
471  //[Deprecated] No longer required; provided that any C functions are properly annotated.
472  //Use kBeginCHeader/kEndCHeader to include a C header from C++ if the header was not designed to support C++.
473 # define kEndHeader() }
474 
475 #else
476 
477  //[Deprecated] No longer required; provided that any C functions are properly annotated.
478  //Use kBeginCHeader/kEndCHeader to include a C header from C++ if the header was not designed to support C++.
479 # define kBeginHeader()
480 
481  //[Deprecated] No longer required; provided that any C functions are properly annotated.
482  //Use kBeginCHeader/kEndCHeader to include a C header from C++ if the header was not designed to support C++.
483 # define kEndHeader()
484 
485 #endif
486 
487 #endif