From f863470262dedb33fdc64d5816237799c764c9bb Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Thu, 30 Apr 2026 14:57:44 -0600 Subject: [PATCH] [libc] Implement sched_getcpu (#195001) This is extremely similar to getcpu, but was available in a much earlier glibc, so a lot more code depends on it. Do a similar implementation. We can only have a simple smoke test as the only documented failure mode in the man page is running on a kernel that does not support the system call, and such kernels (<2.6) are ancient at this point. --- libc/config/linux/aarch64/entrypoints.txt | 1 + libc/config/linux/riscv/entrypoints.txt | 1 + libc/config/linux/x86_64/entrypoints.txt | 1 + libc/include/sched.yaml | 6 +++++ libc/src/sched/CMakeLists.txt | 7 +++++ libc/src/sched/linux/CMakeLists.txt | 11 ++++++++ libc/src/sched/linux/sched_getcpu.cpp | 31 +++++++++++++++++++++++ libc/src/sched/sched_getcpu.h | 20 +++++++++++++++ libc/test/src/sched/CMakeLists.txt | 12 +++++++++ libc/test/src/sched/sched_getcpu_test.cpp | 18 +++++++++++++ 10 files changed, 108 insertions(+) create mode 100644 libc/src/sched/linux/sched_getcpu.cpp create mode 100644 libc/src/sched/sched_getcpu.h create mode 100644 libc/test/src/sched/sched_getcpu_test.cpp diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index b15edc5e3e10..2b2f2314da10 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -39,6 +39,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.sched.sched_get_priority_max libc.src.sched.sched_get_priority_min libc.src.sched.sched_getaffinity + libc.src.sched.sched_getcpu libc.src.sched.sched_getparam libc.src.sched.sched_getscheduler libc.src.sched.sched_rr_get_interval diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index 6478aed3b039..12f44c5c8c68 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -39,6 +39,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.sched.sched_get_priority_max libc.src.sched.sched_get_priority_min libc.src.sched.sched_getaffinity + libc.src.sched.sched_getcpu libc.src.sched.sched_getparam libc.src.sched.sched_getscheduler libc.src.sched.sched_rr_get_interval diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index d1c1d9496af6..54f2280a8d9a 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -41,6 +41,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.sched.sched_get_priority_max libc.src.sched.sched_get_priority_min libc.src.sched.sched_getaffinity + libc.src.sched.sched_getcpu libc.src.sched.sched_getparam libc.src.sched.sched_getscheduler libc.src.sched.sched_rr_get_interval diff --git a/libc/include/sched.yaml b/libc/include/sched.yaml index b07dd0df7c92..33731acf4fac 100644 --- a/libc/include/sched.yaml +++ b/libc/include/sched.yaml @@ -75,6 +75,12 @@ functions: - type: pid_t - type: size_t - type: cpu_set_t * + - name: sched_getcpu + standards: + - GNUExtensions + return_type: int + arguments: + - type: void - name: sched_getparam standards: - POSIX diff --git a/libc/src/sched/CMakeLists.txt b/libc/src/sched/CMakeLists.txt index d1d1de0718c5..39ac8c8c6f24 100644 --- a/libc/src/sched/CMakeLists.txt +++ b/libc/src/sched/CMakeLists.txt @@ -16,6 +16,13 @@ add_entrypoint_object( .${LIBC_TARGET_OS}.sched_getaffinity ) +add_entrypoint_object( + sched_getcpu + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.sched_getcpu +) + add_entrypoint_object( sched_setaffinity ALIAS diff --git a/libc/src/sched/linux/CMakeLists.txt b/libc/src/sched/linux/CMakeLists.txt index ceb755f8e1d1..6cc41e97baa0 100644 --- a/libc/src/sched/linux/CMakeLists.txt +++ b/libc/src/sched/linux/CMakeLists.txt @@ -24,6 +24,17 @@ add_entrypoint_object( libc.src.errno.errno ) +add_entrypoint_object( + sched_getcpu + SRCS + sched_getcpu.cpp + HDRS + ../sched_getcpu.h + DEPENDS + libc.src.__support.OSUtil.osutil + libc.src.errno.errno +) + add_entrypoint_object( sched_setaffinity SRCS diff --git a/libc/src/sched/linux/sched_getcpu.cpp b/libc/src/sched/linux/sched_getcpu.cpp new file mode 100644 index 000000000000..2463f9e053d9 --- /dev/null +++ b/libc/src/sched/linux/sched_getcpu.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/sched/sched_getcpu.h" + +#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/common.h" +#include "src/__support/libc_errno.h" +#include "src/__support/macros/config.h" + +#include // For syscall numbers. + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, sched_getcpu, ()) { + unsigned int cpu = 0; + int ret = + LIBC_NAMESPACE::syscall_impl(SYS_getcpu, &cpu, nullptr, nullptr); + if (ret < 0) { + libc_errno = -ret; + return -1; + } + return cpu; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/sched/sched_getcpu.h b/libc/src/sched/sched_getcpu.h new file mode 100644 index 000000000000..6e6857cc33b4 --- /dev/null +++ b/libc/src/sched/sched_getcpu.h @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SCHED_SCHED_GETCPU_H +#define LLVM_LIBC_SRC_SCHED_SCHED_GETCPU_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int sched_getcpu(void); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_SCHED_SCHED_GETCPU_H diff --git a/libc/test/src/sched/CMakeLists.txt b/libc/test/src/sched/CMakeLists.txt index 66c37e3d5a53..421be2cf2743 100644 --- a/libc/test/src/sched/CMakeLists.txt +++ b/libc/test/src/sched/CMakeLists.txt @@ -56,6 +56,18 @@ add_libc_unittest( libc.test.UnitTest.ErrnoCheckingTest ) +add_libc_unittest( + sched_getcpu_test + SUITE + libc_sched_unittests + SRCS + sched_getcpu_test.cpp + DEPENDS + libc.src.errno.errno + libc.src.sched.sched_getcpu + libc.test.UnitTest.ErrnoCheckingTest +) + add_libc_unittest( scheduler_test SUITE diff --git a/libc/test/src/sched/sched_getcpu_test.cpp b/libc/test/src/sched/sched_getcpu_test.cpp new file mode 100644 index 000000000000..d39fe7345f08 --- /dev/null +++ b/libc/test/src/sched/sched_getcpu_test.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/sched/sched_getcpu.h" +#include "test/UnitTest/ErrnoCheckingTest.h" +#include "test/UnitTest/ErrnoSetterMatcher.h" + +using LlvmLibcSchedSchedGetCpuTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest; + +TEST_F(LlvmLibcSchedSchedGetCpuTest, SmokeTest) { + ASSERT_GE(LIBC_NAMESPACE::sched_getcpu(), 0); + ASSERT_ERRNO_SUCCESS(); +}