#OS Detection
./000 core.h detects the host OS and defines a few portable helpers so the rest of the library can use one code path per platform.
#Platform macros
| Macro | POSIX value | Windows value | Notes |
|---|---|---|---|
FIO_OS_POSIX |
1 |
0 |
Set on Linux, macOS, BSD, and other __unix__/__linux__/__APPLE__ systems. |
FIO_OS_WIN |
0 |
1 |
Set on Windows, including MinGW, MSYS2, Cygwin, and Borland. |
The Windows check is evaluated first, because MinGW/MSYS2 define both _WIN32 and __unix__. Treating the system as Windows avoids calling POSIX socket functions on Winsock SOCKET handles.
After detection, FIO_OS_WIN always wins over FIO_OS_POSIX:
#if FIO_OS_WIN
#undef FIO_OS_POSIX
#define FIO_OS_POSIX 0
#endif#Unix-tools level
FIO_HAVE_UNIX_TOOLS tells the library how Unix-like the environment is:
0— no Unix tools (pure MSVC).1— full POSIX.2— MinGW.3— Cygwin.
It is used to decide whether functions such as pipe(), fcntl(), and POSIX signal APIs are available.
#Process helpers
| Macro | POSIX | Windows |
|---|---|---|
fio_getpid |
getpid |
_getpid |
FIO_KILL_SELF() |
kill(0, SIGINT) |
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0) |
FIO_KILL_SELF is guarded by #ifndef, so you can define your own version before including the header. The default implementation is used by the assertion/debug machinery to deliver a signal to the running process.
#Thread sleep and yield
| Macro | POSIX | Windows |
|---|---|---|
FIO_THREAD_WAIT(nano_sec) |
nanosleep |
Sleep |
FIO_THREAD_YIELD() |
see below | see below |
FIO_THREAD_RESCHEDULE() |
FIO_THREAD_WAIT(4) |
FIO_THREAD_WAIT(4) |
FIO_THREAD_WAIT(nano_sec) sleeps the current thread for the requested number of nanoseconds. On POSIX it builds a struct timespec and calls nanosleep. On Windows it converts the interval to milliseconds and calls Sleep; any non-zero request is rounded up to at least 1 ms.
FIO_THREAD_YIELD() hints the processor that the thread is in a spin loop. On x86/x86-64 with GCC or Clang it emits a pause instruction; on ARM/AArch64 with GCC or Clang it emits a yield instruction; with MSVC it calls YieldProcessor(); otherwise it falls back to sched_yield() on POSIX.
FIO_THREAD_RESCHEDULE() yields the thread by sleeping for 4 nanoseconds (FIO_THREAD_WAIT(4)). It is used by the lock code to back off busy waits without fully suspending the thread.
#Portable type patches
On pure MSVC ssize_t is missing, so the core header defines it from SSIZE_T:
typedef SSIZE_T ssize_t;SSIZE_MAX and SSIZE_MIN are also provided if the system headers do not:
#ifndef SSIZE_MAX
#define SSIZE_MAX ((ssize_t)((~(size_t)0) >> 1))
#endif
#ifndef SSIZE_MIN
#define SSIZE_MIN ((ssize_t)(~((~(size_t)0) >> 1)))
#endif#printf-style format checking
The FIO___PRINTF_STYLE(string_index, check_index) macro is defined differently on each toolchain so the compiler can check printf-style arguments. MinGW/Cygwin use the MinGW format attribute, pure MSVC leaves it empty, and POSIX/GCC/Clang use the standard printf format attribute. It is documented in ./001 compiler attributes.md.