diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -28,6 +28,7 @@ # sched.h entrypoints libc.src.sched.sched_getaffinity libc.src.sched.sched_setaffinity + libc.src.sched.sched_yield # string.h entrypoints libc.src.string.bcmp diff --git a/libc/config/linux/riscv64/entrypoints.txt b/libc/config/linux/riscv64/entrypoints.txt --- a/libc/config/linux/riscv64/entrypoints.txt +++ b/libc/config/linux/riscv64/entrypoints.txt @@ -28,6 +28,7 @@ # sched.h entrypoints libc.src.sched.sched_getaffinity libc.src.sched.sched_setaffinity + libc.src.sched.sched_yield # string.h entrypoints libc.src.string.bcmp diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -28,6 +28,7 @@ # sched.h entrypoints libc.src.sched.sched_getaffinity libc.src.sched.sched_setaffinity + libc.src.sched.sched_yield # string.h entrypoints libc.src.string.bcmp diff --git a/libc/spec/gnu_ext.td b/libc/spec/gnu_ext.td --- a/libc/spec/gnu_ext.td +++ b/libc/spec/gnu_ext.td @@ -32,7 +32,7 @@ FunctionSpec<"exp10f", RetValSpec, [ArgSpec]>, ] >; - + HeaderSpec Sched = HeaderSpec< "sched.h", [], // Macros @@ -51,7 +51,7 @@ >, ] >; - + HeaderSpec String = HeaderSpec< "string.h", [], // Macros diff --git a/libc/spec/posix.td b/libc/spec/posix.td --- a/libc/spec/posix.td +++ b/libc/spec/posix.td @@ -630,6 +630,20 @@ ] >; + HeaderSpec Sched = HeaderSpec< + "sched.h", + [], // Macros + [PidT, SizeTType, CpuSetT], // Types + [], // Enumerations + [ + FunctionSpec< + "sched_yield", + RetValSpec, + [] + >, + ] + >; + HeaderSpec String = HeaderSpec< "string.h", [ @@ -1300,6 +1314,7 @@ Errno, FCntl, PThread, + Sched, Signal, Spawn, StdIO, diff --git a/libc/src/sched/CMakeLists.txt b/libc/src/sched/CMakeLists.txt --- a/libc/src/sched/CMakeLists.txt +++ b/libc/src/sched/CMakeLists.txt @@ -16,6 +16,13 @@ .${LIBC_TARGET_OS}.sched_setaffinity ) +add_entrypoint_object( + sched_yield + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.sched_yield +) + add_entrypoint_object( __sched_getcpucount ALIAS diff --git a/libc/src/sched/linux/CMakeLists.txt b/libc/src/sched/linux/CMakeLists.txt --- a/libc/src/sched/linux/CMakeLists.txt +++ b/libc/src/sched/linux/CMakeLists.txt @@ -30,4 +30,16 @@ ../sched_getcpucount.h DEPENDS libc.include.sched + ) + +add_entrypoint_object( + sched_yield + SRCS + sched_yield.cpp + HDRS + ../sched_yield.h + DEPENDS + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.errno.errno ) diff --git a/libc/src/sched/linux/sched_yield.cpp b/libc/src/sched/linux/sched_yield.cpp new file mode 100644 --- /dev/null +++ b/libc/src/sched/linux/sched_yield.cpp @@ -0,0 +1,29 @@ +//===-- Implementation of sched_yield -------------------------------------===// +// +// 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_yield.h" + +#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/common.h" +#include "src/errno/libc_errno.h" + +#include // For syscall numbers. + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, sched_yield, ()) { + long ret = __llvm_libc::syscall_impl(SYS_sched_yield); + // As of writing this, yield() cannot fail + if (ret < 0) { + libc_errno = -ret; + return -1; + } + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/sched/sched_yield.h b/libc/src/sched/sched_yield.h new file mode 100644 --- /dev/null +++ b/libc/src/sched/sched_yield.h @@ -0,0 +1,18 @@ +//===-- Implementation header for sched_yield -------------------*- C++ -*-===// +// +// 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_YIELD_H +#define LLVM_LIBC_SRC_SCHED_SCHED_YIELD_H + +namespace __llvm_libc { + +int sched_yield(void); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_SCHED_SCHED_YIELD_H diff --git a/libc/test/src/sched/CMakeLists.txt b/libc/test/src/sched/CMakeLists.txt --- a/libc/test/src/sched/CMakeLists.txt +++ b/libc/test/src/sched/CMakeLists.txt @@ -16,6 +16,17 @@ libc.test.errno_setter_matcher ) +add_libc_unittest( + yield_test + SUITE + libc_sched_unittests + SRCS + yield_test.cpp + DEPENDS + libc.src.errno.errno + libc.src.sched.sched_yield +) + add_libc_unittest( cpu_count_test SUITE diff --git a/libc/test/src/sched/yield_test.cpp b/libc/test/src/sched/yield_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/sched/yield_test.cpp @@ -0,0 +1,19 @@ +//===-- Unittests for sched_yield -----------------------------------------===// +// +// 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/errno/libc_errno.h" +#include "src/sched/sched_yield.h" +#include "test/UnitTest/Test.h" + +TEST(LlvmLibcSchedYieldTest, SmokeTest) { + libc_errno = 0; + // sched_yield() always succeeds, just do a basic test that errno/ret are + // properly 0. + ASSERT_EQ(__llvm_libc::sched_yield(), 0); + ASSERT_EQ(libc_errno, 0); +}