[PATCH v1 1/2] x86: Implement sched_yield syscall for x86 only.

Noah Goldstein goldstein.w.n@gmail.com
Thu Jun 8 09:00:49 GMT 2023


We slightly optimize it by using `vzeroall` before the actual syscall.
This returns the SSE, AVX, and ZMM_HI256 xsave/xrstor states to the
init-state which allows the imminent context switch to skip
saving/restoring those states.
---
 .../unix/sysv/linux/x86_64/sched-yield-impl.h | 29 ++++++++++
 sysdeps/unix/sysv/linux/x86_64/sched_yield.c  | 56 +++++++++++++++++++
 2 files changed, 85 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/sched-yield-impl.h
 create mode 100644 sysdeps/unix/sysv/linux/x86_64/sched_yield.c

diff --git a/sysdeps/unix/sysv/linux/x86_64/sched-yield-impl.h b/sysdeps/unix/sysv/linux/x86_64/sched-yield-impl.h
new file mode 100644
index 0000000000..03622ccea4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/sched-yield-impl.h
@@ -0,0 +1,29 @@
+/* Yield current process.  Linux specific syscall.
+   Copyright (C) 2023 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+static int TARGET
+SCHED_YIELD (void)
+{
+  PREPARE_CONTEXT_SWITCH ();
+  return INLINE_SYSCALL_CALL (sched_yield);
+}
+#undef TARGET
+#undef SCHED_YIELD
+#undef PREPARE_CONTEXT_SWITCH
diff --git a/sysdeps/unix/sysv/linux/x86_64/sched_yield.c b/sysdeps/unix/sysv/linux/x86_64/sched_yield.c
new file mode 100644
index 0000000000..e87acf124b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/sched_yield.c
@@ -0,0 +1,56 @@
+/* clock_nanosleep for x86_64.
+   Copyright (C) 2023 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
+   <https://www.gnu.org/licenses/>.  */
+
+/* Only difference is if we have AVX, use vzeroall to clear inuse for SSE, AVX,
+   and ZMM_HI256 xsave/xrstor state.  This enables the init-state optimization
+   saving overhead on context switches.  */
+
+#include <isa-level.h>
+#if ISA_SHOULD_BUILD(4)
+# include <immintrin.h>
+# define TARGET __attribute__ ((target ("avx")))
+# define PREPARE_CONTEXT_SWITCH() _mm256_zeroall ()
+# define SCHED_YIELD __sched_yield_avx
+# include "sched-yield-impl.h"
+#endif
+#if ISA_SHOULD_BUILD(2)
+# define TARGET
+# define PREPARE_CONTEXT_SWITCH()
+# define SCHED_YIELD __sched_yield_generic
+# include "sched-yield-impl.h"
+#endif
+
+#include <init-arch.h>
+#include <ifunc-init.h>
+
+static inline void *
+__sched_yield_ifunc_selector (void)
+{
+#if MINIMUM_X86_ISA_LEVEL >= 3
+  return __sched_yield_avx;
+#else
+  const struct cpu_features *cpu_features = __get_cpu_features ();
+  if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX))
+    return __sched_yield_avx;
+  return __sched_yield_generic;
+#endif
+}
+
+libc_ifunc (__sched_yield, __sched_yield_ifunc_selector ());
+libc_hidden_def (__sched_yield);
+weak_alias (__sched_yield, sched_yield);
-- 
2.34.1



More information about the Libc-alpha mailing list