diff --git a/bits/types/once_flag.h b/bits/types/once_flag.h
new file mode 100644
index 0000000000..9180adce1a
--- /dev/null
+++ b/bits/types/once_flag.h
@@ -0,0 +1,27 @@
+/* Define once_flag and ONCE_FLAG_INIT.
+ Copyright (C) 2018-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ . */
+
+#ifndef __once_flag_defined
+#define __once_flag_defined 1
+
+#include
+
+typedef __once_flag once_flag;
+#define ONCE_FLAG_INIT __ONCE_FLAG_INIT
+
+#endif
diff --git a/manual/threads.texi b/manual/threads.texi
index eeefa9b800..1e9be32d66 100644
--- a/manual/threads.texi
+++ b/manual/threads.texi
@@ -219,6 +219,9 @@ invoked from several threads. The completion of the function
@code{call_once} with the same @code{flag} variable.
@end deftypefun
+These definitions are from C11, where they appear in @file{threads.h}.
+In C23, they appear in @file{stdlib.h} as well as in @file{threads.h}.
+
@node ISO C Mutexes
@subsection Mutexes
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 25f777e1a5..d2c594885a 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -37,6 +37,7 @@ headers := \
bits/time64.h \
bits/timesize.h \
bits/types/error_t.h \
+ bits/types/once_flag.h \
bits/wordsize.h \
errno.h \
fmtmsg.h \
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
index cd4503c761..1d6a83a22c 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -1158,6 +1158,14 @@ extern int getloadavg (double __loadavg[], int __nelem)
extern int ttyslot (void) __THROW;
#endif
+#if __GLIBC_USE (ISOC23)
+# include
+
+/* Call function __FUNC exactly once, even if invoked from several threads.
+ All calls must be made with the same __FLAGS object. */
+extern void call_once (once_flag *__flag, void (*__func)(void));
+#endif
+
#include
/* Define some macros helping to catch buffer overflows. */
diff --git a/sysdeps/pthread/threads.h b/sysdeps/pthread/threads.h
index 44c9bc7b1f..48fcda5992 100644
--- a/sysdeps/pthread/threads.h
+++ b/sysdeps/pthread/threads.h
@@ -25,6 +25,7 @@
__BEGIN_DECLS
#include
+#include
#include
#if (!defined __STDC_VERSION__ \
@@ -58,9 +59,6 @@ enum
mtx_timed = 2
};
-typedef __once_flag once_flag;
-#define ONCE_FLAG_INIT __ONCE_FLAG_INIT
-
typedef union
{
char __size[__SIZEOF_PTHREAD_MUTEX_T];