1 // Copyright © Tavian Barnes <tavianator@tavianator.com>
2 // SPDX-License-Identifier: 0BSD
5 * Configuration and feature/platform detection.
13 #if __STDC_VERSION__ < 202311L
14 # include <stdalign.h>
16 # include <stdnoreturn.h>
19 // bfs packaging configuration
22 # define BFS_COMMAND "bfs"
25 # define BFS_VERSION "3.0.3"
28 # define BFS_HOMEPAGE "https://tavianator.com/projects/bfs.html"
31 // Check for system headers
35 #if __has_include(<mntent.h>)
36 # define BFS_HAS_MNTENT_H true
38 #if __has_include(<paths.h>)
39 # define BFS_HAS_PATHS_H true
41 #if __has_include(<sys/acl.h>)
42 # define BFS_HAS_SYS_ACL_H true
44 #if __has_include(<sys/capability.h>)
45 # define BFS_HAS_SYS_CAPABILITY_H true
47 #if __has_include(<sys/extattr.h>)
48 # define BFS_HAS_SYS_EXTATTR_H true
50 #if __has_include(<sys/mkdev.h>)
51 # define BFS_HAS_SYS_MKDEV_H true
53 #if __has_include(<sys/param.h>)
54 # define BFS_HAS_SYS_PARAM_H true
56 #if __has_include(<sys/sysmacros.h>)
57 # define BFS_HAS_SYS_SYSMACROS_H true
59 #if __has_include(<sys/xattr.h>)
60 # define BFS_HAS_SYS_XATTR_H true
62 #if __has_include(<threads.h>)
63 # define BFS_HAS_THREADS_H true
65 #if __has_include(<util.h>)
66 # define BFS_HAS_UTIL_H true
69 #else // !__has_include
71 #define BFS_HAS_MNTENT_H __GLIBC__
72 #define BFS_HAS_PATHS_H true
73 #define BFS_HAS_SYS_ACL_H true
74 #define BFS_HAS_SYS_CAPABILITY_H __linux__
75 #define BFS_HAS_SYS_EXTATTR_H __FreeBSD__
76 #define BFS_HAS_SYS_MKDEV_H false
77 #define BFS_HAS_SYS_PARAM_H true
78 #define BFS_HAS_SYS_SYSMACROS_H __GLIBC__
79 #define BFS_HAS_SYS_XATTR_H __linux__
80 #define BFS_HAS_THREADS_H (!__STDC_NO_THREADS__)
81 #define BFS_HAS_UTIL_H __NetBSD__
83 #endif // !__has_include
85 #ifndef BFS_USE_MNTENT_H
86 # define BFS_USE_MNTENT_H BFS_HAS_MNTENT_H
88 #ifndef BFS_USE_PATHS_H
89 # define BFS_USE_PATHS_H BFS_HAS_PATHS_H
91 #ifndef BFS_USE_SYS_ACL_H
92 # define BFS_USE_SYS_ACL_H BFS_HAS_SYS_ACL_H
94 #ifndef BFS_USE_SYS_CAPABILITY_H
95 # define BFS_USE_SYS_CAPABILITY_H (BFS_HAS_SYS_CAPABILITY_H && !__FreeBSD__)
97 #ifndef BFS_USE_SYS_EXTATTR_H
98 # define BFS_USE_SYS_EXTATTR_H BFS_HAS_SYS_EXTATTR_H
100 #ifndef BFS_USE_SYS_MKDEV_H
101 # define BFS_USE_SYS_MKDEV_H BFS_HAS_SYS_MKDEV_H
103 #ifndef BFS_USE_SYS_PARAM_H
104 # define BFS_USE_SYS_PARAM_H BFS_HAS_SYS_PARAM_H
106 #ifndef BFS_USE_SYS_SYSMACROS_H
107 # define BFS_USE_SYS_SYSMACROS_H BFS_HAS_SYS_SYSMACROS_H
109 #ifndef BFS_USE_SYS_XATTR_H
110 # define BFS_USE_SYS_XATTR_H BFS_HAS_SYS_XATTR_H
112 #ifndef BFS_USE_THREADS_H
113 # define BFS_USE_THREADS_H BFS_HAS_THREADS_H
115 #ifndef BFS_USE_UTIL_H
116 # define BFS_USE_UTIL_H BFS_HAS_UTIL_H
119 // Stub out feature detection on old/incompatible compilers
121 #ifndef __has_feature
122 # define __has_feature(feat) false
125 #ifndef __has_c_attribute
126 # define __has_c_attribute(attr) false
129 #ifndef __has_attribute
130 # define __has_attribute(attr) false
133 // Platform detection
135 // Get the definition of BSD if available
136 #if BFS_USE_SYS_PARAM_H
137 # include <sys/param.h>
140 #ifndef __GLIBC_PREREQ
141 # define __GLIBC_PREREQ(maj, min) false
144 // Fundamental utilities
147 * Get the length of an array.
149 #define countof(array) (sizeof(array) / sizeof(0[array]))
152 * False sharing/destructive interference/largest cache line size.
154 #ifdef __GCC_DESTRUCTIVE_SIZE
155 # define FALSE_SHARING_SIZE __GCC_DESTRUCTIVE_SIZE
157 # define FALSE_SHARING_SIZE 64
161 * True sharing/constructive interference/smallest cache line size.
163 #ifdef __GCC_CONSTRUCTIVE_SIZE
164 # define TRUE_SHARING_SIZE __GCC_CONSTRUCTIVE_SIZE
166 # define TRUE_SHARING_SIZE 64
170 * Alignment specifier that avoids false sharing.
172 #define cache_align alignas(FALSE_SHARING_SIZE)
174 // Wrappers for attributes
177 * Silence compiler warnings about switch/case fall-throughs.
179 #if __has_c_attribute(fallthrough)
180 # define fallthru [[fallthrough]]
181 #elif __has_attribute(fallthrough)
182 # define fallthru __attribute__((fallthrough))
184 # define fallthru ((void)0)
188 * Adds compiler warnings for bad printf()-style function calls, if supported.
190 #if __has_attribute(format)
191 # define BFS_FORMATTER(fmt, args) __attribute__((format(printf, fmt, args)))
193 # define BFS_FORMATTER(fmt, args)
197 * Check if function multiversioning via GNU indirect functions (ifunc) is supported.
199 #ifndef BFS_USE_TARGET_CLONES
200 # if __has_attribute(target_clones) && (__GLIBC__ || __FreeBSD__ || __NetBSD__)
201 # define BFS_USE_TARGET_CLONES true
206 * Ignore a particular GCC warning for a region of code.
209 # define BFS_PRAGMA_STRINGIFY(...) _Pragma(#__VA_ARGS__)
210 # define BFS_SUPPRESS(warning) \
211 _Pragma("GCC diagnostic push"); \
212 BFS_PRAGMA_STRINGIFY(GCC diagnostic ignored warning)
213 # define BFS_UNSUPPRESS() \
214 _Pragma("GCC diagnostic pop")
216 # define BFS_SUPPRESS(warning)
217 # define BFS_UNSUPPRESS()
220 #endif // BFS_CONFIG_H