summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/header.mk1
-rw-r--r--config/max-align-t.c8
-rw-r--r--src/prelude.h19
3 files changed, 24 insertions, 4 deletions
diff --git a/config/header.mk b/config/header.mk
index 86a4dc5..bba03ef 100644
--- a/config/header.mk
+++ b/config/header.mk
@@ -18,6 +18,7 @@ HEADERS := \
${GEN}/getdents64-syscall.h \
${GEN}/getprogname.h \
${GEN}/getprogname-gnu.h \
+ ${GEN}/max-align-t.h \
${GEN}/pipe2.h \
${GEN}/posix-spawn-addfchdir.h \
${GEN}/posix-spawn-addfchdir-np.h \
diff --git a/config/max-align-t.c b/config/max-align-t.c
new file mode 100644
index 0000000..96165ce
--- /dev/null
+++ b/config/max-align-t.c
@@ -0,0 +1,8 @@
+// Copyright © Tavian Barnes <tavianator@tavianator.com>
+// SPDX-License-Identifier: 0BSD
+
+#include <stddef.h>
+
+int main(void) {
+ return _Alignof(max_align_t);
+}
diff --git a/src/prelude.h b/src/prelude.h
index a23b167..390666b 100644
--- a/src/prelude.h
+++ b/src/prelude.h
@@ -182,14 +182,25 @@ extern const char bfs_version[];
#endif
/**
+ * Polyfill max_align_t if we don't already have it.
+ */
+#if !BFS_HAS_MAX_ALIGN_T
+typedef union {
+# ifdef __BIGGEST_ALIGNMENT__
+ alignas(__BIGGEST_ALIGNMENT__) char c;
+# else
+ long double ld;
+ long long ll;
+ void *ptr;
+# endif
+} max_align_t;
+#endif
+
+/**
* Alignment specifier that avoids false sharing.
*/
#define cache_align alignas(FALSE_SHARING_SIZE)
-#if __COSMOPOLITAN__
-typedef long double max_align_t;
-#endif
-
// Wrappers for attributes
/**