[libc-commits] [libc] [libc] Implement pthread_setschedparam and getschedparam (PR #205770)
Jeff Bailey via libc-commits
libc-commits at lists.llvm.org
Tue Jul 21 06:57:55 PDT 2026
https://github.com/kaladron updated https://github.com/llvm/llvm-project/pull/205770
>From d5e493a2db02805ba94283c5c98aa8cc35a0ada3 Mon Sep 17 00:00:00 2001
From: Jeff Bailey <jbailey at raspberryginger.com>
Date: Thu, 25 Jun 2026 08:32:09 +0100
Subject: [PATCH 1/2] [libc] Implement pthread_setschedparam and getschedparam
Implemented the pthread_setschedparam and pthread_getschedparam
functions.
Added Linux syscall wrappers:
* sched_setscheduler
* sched_getscheduler
* sched_getparam
Updated the Thread class to support getting and setting scheduling
parameters.
Added integration tests to verify the implementation.
Assisted-by: Automated tooling, human reviewed.
---
libc/config/linux/aarch64/entrypoints.txt | 2 +
libc/config/linux/riscv/entrypoints.txt | 2 +
libc/config/linux/x86_64/entrypoints.txt | 2 +
libc/include/pthread.yaml | 12 +++
.../linux/syscall_wrappers/CMakeLists.txt | 41 +++++++++
.../linux/syscall_wrappers/sched_getparam.h | 39 ++++++++
.../syscall_wrappers/sched_getscheduler.h | 38 ++++++++
.../syscall_wrappers/sched_setscheduler.h | 40 ++++++++
.../__support/threads/linux/CMakeLists.txt | 3 +
libc/src/__support/threads/linux/thread.cpp | 24 +++++
libc/src/__support/threads/thread.h | 16 ++++
libc/src/pthread/CMakeLists.txt | 24 +++++
libc/src/pthread/pthread_getschedparam.cpp | 37 ++++++++
libc/src/pthread/pthread_getschedparam.h | 27 ++++++
libc/src/pthread/pthread_setschedparam.cpp | 36 ++++++++
libc/src/pthread/pthread_setschedparam.h | 27 ++++++
.../integration/src/pthread/CMakeLists.txt | 17 ++++
.../pthread/pthread_setschedparam_test.cpp | 92 +++++++++++++++++++
18 files changed, 479 insertions(+)
create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getparam.h
create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getscheduler.h
create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/sched_setscheduler.h
create mode 100644 libc/src/pthread/pthread_getschedparam.cpp
create mode 100644 libc/src/pthread/pthread_getschedparam.h
create mode 100644 libc/src/pthread/pthread_setschedparam.cpp
create mode 100644 libc/src/pthread/pthread_setschedparam.h
create mode 100644 libc/test/integration/src/pthread/pthread_setschedparam_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 2e7b9276ab068..8eaa4871837bd 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1085,6 +1085,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.pthread.pthread_equal
libc.src.pthread.pthread_exit
libc.src.pthread.pthread_getname_np
+ libc.src.pthread.pthread_getschedparam
libc.src.pthread.pthread_getspecific
libc.src.pthread.pthread_getthreadid_np
libc.src.pthread.pthread_getunique_np
@@ -1129,6 +1130,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.pthread.pthread_spin_unlock
libc.src.pthread.pthread_self
libc.src.pthread.pthread_setname_np
+ libc.src.pthread.pthread_setschedparam
libc.src.pthread.pthread_setspecific
# sched.h entrypoints
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 8a29e77ffe0fd..c6a4b431f33de 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1279,6 +1279,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.pthread.pthread_equal
libc.src.pthread.pthread_exit
libc.src.pthread.pthread_getname_np
+ libc.src.pthread.pthread_getschedparam
libc.src.pthread.pthread_getspecific
libc.src.pthread.pthread_getthreadid_np
libc.src.pthread.pthread_getunique_np
@@ -1326,6 +1327,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.pthread.pthread_spin_unlock
libc.src.pthread.pthread_self
libc.src.pthread.pthread_setname_np
+ libc.src.pthread.pthread_setschedparam
libc.src.pthread.pthread_setspecific
# sched.h entrypoints
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 0a4fb747c2940..fb0886e2e650a 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1284,6 +1284,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.pthread.pthread_equal
libc.src.pthread.pthread_exit
libc.src.pthread.pthread_getname_np
+ libc.src.pthread.pthread_getschedparam
libc.src.pthread.pthread_getspecific
libc.src.pthread.pthread_getthreadid_np
libc.src.pthread.pthread_getunique_np
@@ -1331,6 +1332,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.pthread.pthread_spin_unlock
libc.src.pthread.pthread_self
libc.src.pthread.pthread_setname_np
+ libc.src.pthread.pthread_setschedparam
libc.src.pthread.pthread_setspecific
# sched.h entrypoints
diff --git a/libc/include/pthread.yaml b/libc/include/pthread.yaml
index eeb8a200b0038..c3e967c67ee8f 100644
--- a/libc/include/pthread.yaml
+++ b/libc/include/pthread.yaml
@@ -232,6 +232,12 @@ functions:
- type: pthread_t
- type: char *
- type: size_t
+ - name: pthread_getschedparam
+ return_type: int
+ arguments:
+ - type: pthread_t
+ - type: int *__restrict
+ - type: struct sched_param *__restrict
- name: pthread_getspecific
return_type: void *
arguments:
@@ -422,6 +428,12 @@ functions:
arguments:
- type: pthread_t
- type: const char *
+ - name: pthread_setschedparam
+ return_type: int
+ arguments:
+ - type: pthread_t
+ - type: int
+ - type: const struct sched_param *
- name: pthread_setspecific
return_type: int
arguments:
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index 27df4c3f22afb..7d5f94513d0de 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -40,6 +40,47 @@ add_header_library(
libc.include.sys_syscall
)
+add_header_library(
+ sched_setscheduler
+ HDRS
+ sched_setscheduler.h
+ DEPENDS
+ libc.hdr.types.pid_t
+ libc.hdr.types.struct_sched_param
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.include.sys_syscall
+)
+
+add_header_library(
+ sched_getscheduler
+ HDRS
+ sched_getscheduler.h
+ DEPENDS
+ libc.hdr.types.pid_t
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.include.sys_syscall
+)
+
+add_header_library(
+ sched_getparam
+ HDRS
+ sched_getparam.h
+ DEPENDS
+ libc.hdr.types.pid_t
+ libc.hdr.types.struct_sched_param
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.include.sys_syscall
+)
+
add_header_library(
close
HDRS
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getparam.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getparam.h
new file mode 100644
index 0000000000000..7eab051c67972
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getparam.h
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for sched_getparam syscall wrapper.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SCHED_GETPARAM_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SCHED_GETPARAM_H
+
+#include "hdr/types/pid_t.h"
+#include "hdr/types/struct_sched_param.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> sched_getparam(pid_t tid, struct sched_param *param) {
+ int ret = syscall_impl<int>(SYS_sched_getparam, tid, param);
+ if (ret < 0)
+ return Error(-ret);
+ return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SCHED_GETPARAM_H
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getscheduler.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getscheduler.h
new file mode 100644
index 0000000000000..84ebf1aecc4ad
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getscheduler.h
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for sched_getscheduler syscall wrapper.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SCHED_GETSCHEDULER_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SCHED_GETSCHEDULER_H
+
+#include "hdr/types/pid_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> sched_getscheduler(pid_t tid) {
+ int ret = syscall_impl<int>(SYS_sched_getscheduler, tid);
+ if (ret < 0)
+ return Error(-ret);
+ return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SCHED_GETSCHEDULER_H
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_setscheduler.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_setscheduler.h
new file mode 100644
index 0000000000000..122f4c1e7c4ed
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_setscheduler.h
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for sched_setscheduler syscall wrapper.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SCHED_SETSCHEDULER_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SCHED_SETSCHEDULER_H
+
+#include "hdr/types/pid_t.h"
+#include "hdr/types/struct_sched_param.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> sched_setscheduler(pid_t tid, int policy,
+ const struct sched_param *param) {
+ int ret = syscall_impl<int>(SYS_sched_setscheduler, tid, policy, param);
+ if (ret < 0)
+ return Error(-ret);
+ return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SCHED_SETSCHEDULER_H
diff --git a/libc/src/__support/threads/linux/CMakeLists.txt b/libc/src/__support/threads/linux/CMakeLists.txt
index f9f2a455cd7a1..1124d1254ba76 100644
--- a/libc/src/__support/threads/linux/CMakeLists.txt
+++ b/libc/src/__support/threads/linux/CMakeLists.txt
@@ -47,6 +47,9 @@ add_object_library(
libc.src.__support.OSUtil.linux.syscall_wrappers.munmap
libc.src.__support.OSUtil.linux.syscall_wrappers.open
libc.src.__support.OSUtil.linux.syscall_wrappers.read
+ libc.src.__support.OSUtil.linux.syscall_wrappers.sched_getparam
+ libc.src.__support.OSUtil.linux.syscall_wrappers.sched_getscheduler
+ libc.src.__support.OSUtil.linux.syscall_wrappers.sched_setscheduler
libc.src.__support.OSUtil.linux.syscall_wrappers.write
libc.src.__support.threads.thread_common
COMPILE_OPTIONS
diff --git a/libc/src/__support/threads/linux/thread.cpp b/libc/src/__support/threads/linux/thread.cpp
index f094484b64062..4d43f59f8ea9d 100644
--- a/libc/src/__support/threads/linux/thread.cpp
+++ b/libc/src/__support/threads/linux/thread.cpp
@@ -17,6 +17,9 @@
#include "src/__support/OSUtil/linux/syscall_wrappers/munmap.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/open.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/read.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/sched_getparam.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/sched_getscheduler.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/sched_setscheduler.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/write.h"
#include "src/__support/OSUtil/syscall.h" // For syscall functions.
#include "src/__support/common.h"
@@ -490,6 +493,27 @@ int Thread::get_name(cpp::StringStream &name) const {
return 0;
}
+int Thread::setschedparam(int policy, const struct sched_param *param) {
+ auto result = linux_syscalls::sched_setscheduler(attrib->tid, policy, param);
+ if (!result.has_value())
+ return result.error();
+ return 0;
+}
+
+int Thread::getschedparam(int *policy, struct sched_param *param) const {
+ auto pol_result = linux_syscalls::sched_getscheduler(attrib->tid);
+ if (!pol_result.has_value())
+ return pol_result.error();
+
+ auto param_result = linux_syscalls::sched_getparam(attrib->tid, param);
+ if (!param_result.has_value())
+ return param_result.error();
+
+ if (policy != nullptr)
+ *policy = pol_result.value();
+ return 0;
+}
+
void thread_exit(ThreadReturnValue retval, ThreadStyle style) {
auto attrib = self.attrib;
diff --git a/libc/src/__support/threads/thread.h b/libc/src/__support/threads/thread.h
index 232b300bbba5b..9c66db5a15598 100644
--- a/libc/src/__support/threads/thread.h
+++ b/libc/src/__support/threads/thread.h
@@ -23,6 +23,8 @@
#include <stddef.h> // For size_t
+struct sched_param;
+
namespace LIBC_NAMESPACE_DECL {
using ThreadRunnerPosix = void *(void *);
@@ -230,6 +232,20 @@ struct Thread {
// Return the name of the thread in |name|. Return the error number of error.
int get_name(cpp::StringStream &name) const;
+
+ /// Set the scheduling policy and parameters of the thread.
+ ///
+ /// \param policy The new scheduling policy.
+ /// \param param The new scheduling parameters.
+ /// \return 0 on success, or an error number on failure.
+ int setschedparam(int policy, const struct sched_param *param);
+
+ /// Get the scheduling policy and parameters of the thread.
+ ///
+ /// \param policy Pointer to store the retrieved policy (can be null).
+ /// \param param Pointer to store the retrieved parameters.
+ /// \return 0 on success, or an error number on failure.
+ int getschedparam(int *policy, struct sched_param *param) const;
};
LIBC_INLINE_VAR LIBC_THREAD_LOCAL Thread self;
diff --git a/libc/src/pthread/CMakeLists.txt b/libc/src/pthread/CMakeLists.txt
index 422116c978fb5..2b87a54b02002 100644
--- a/libc/src/pthread/CMakeLists.txt
+++ b/libc/src/pthread/CMakeLists.txt
@@ -941,3 +941,27 @@ add_entrypoint_object(
libc.src.__support.threads.fork_callbacks
libc.src.errno.errno
)
+
+add_entrypoint_object(
+ pthread_setschedparam
+ SRCS
+ pthread_setschedparam.cpp
+ HDRS
+ pthread_setschedparam.h
+ DEPENDS
+ libc.include.pthread
+ libc.src.__support.threads.thread
+ libc.src.__support.macros.null_check
+)
+
+add_entrypoint_object(
+ pthread_getschedparam
+ SRCS
+ pthread_getschedparam.cpp
+ HDRS
+ pthread_getschedparam.h
+ DEPENDS
+ libc.include.pthread
+ libc.src.__support.threads.thread
+ libc.src.__support.macros.null_check
+)
diff --git a/libc/src/pthread/pthread_getschedparam.cpp b/libc/src/pthread/pthread_getschedparam.cpp
new file mode 100644
index 0000000000000..ade50a11af263
--- /dev/null
+++ b/libc/src/pthread/pthread_getschedparam.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Linux implementation of the pthread_getschedparam function.
+///
+//===----------------------------------------------------------------------===//
+
+#include "pthread_getschedparam.h"
+
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+#include "src/__support/threads/thread.h"
+
+#include <pthread.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+static_assert(sizeof(pthread_t) == sizeof(LIBC_NAMESPACE::Thread),
+ "Mismatch between pthread_t and internal Thread.");
+
+LLVM_LIBC_FUNCTION(int, pthread_getschedparam,
+ (pthread_t th, int *__restrict policy,
+ struct sched_param *__restrict param)) {
+ LIBC_CRASH_ON_NULLPTR(policy);
+ LIBC_CRASH_ON_NULLPTR(param);
+ auto *thread = reinterpret_cast<Thread *>(&th);
+ return thread->getschedparam(policy, param);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/pthread/pthread_getschedparam.h b/libc/src/pthread/pthread_getschedparam.h
new file mode 100644
index 0000000000000..54c79811cc800
--- /dev/null
+++ b/libc/src/pthread/pthread_getschedparam.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for pthread_getschedparam.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_GETSCHEDPARAM_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_GETSCHEDPARAM_H
+
+#include "src/__support/macros/config.h"
+#include <pthread.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+int pthread_getschedparam(pthread_t thread, int *__restrict policy,
+ struct sched_param *__restrict param);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_GETSCHEDPARAM_H
diff --git a/libc/src/pthread/pthread_setschedparam.cpp b/libc/src/pthread/pthread_setschedparam.cpp
new file mode 100644
index 0000000000000..c7b29848c58de
--- /dev/null
+++ b/libc/src/pthread/pthread_setschedparam.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Linux implementation of the pthread_setschedparam function.
+///
+//===----------------------------------------------------------------------===//
+
+#include "pthread_setschedparam.h"
+
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/null_check.h"
+#include "src/__support/threads/thread.h"
+
+#include <pthread.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+static_assert(sizeof(pthread_t) == sizeof(LIBC_NAMESPACE::Thread),
+ "Mismatch between pthread_t and internal Thread.");
+
+LLVM_LIBC_FUNCTION(int, pthread_setschedparam,
+ (pthread_t th, int policy,
+ const struct sched_param *param)) {
+ LIBC_CRASH_ON_NULLPTR(param);
+ auto *thread = reinterpret_cast<Thread *>(&th);
+ return thread->setschedparam(policy, param);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/pthread/pthread_setschedparam.h b/libc/src/pthread/pthread_setschedparam.h
new file mode 100644
index 0000000000000..437d39f0fb522
--- /dev/null
+++ b/libc/src/pthread/pthread_setschedparam.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for pthread_setschedparam.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_PTHREAD_PTHREAD_SETSCHEDPARAM_H
+#define LLVM_LIBC_SRC_PTHREAD_PTHREAD_SETSCHEDPARAM_H
+
+#include "src/__support/macros/config.h"
+#include <pthread.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+int pthread_setschedparam(pthread_t thread, int policy,
+ const struct sched_param *param);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_PTHREAD_PTHREAD_SETSCHEDPARAM_H
diff --git a/libc/test/integration/src/pthread/CMakeLists.txt b/libc/test/integration/src/pthread/CMakeLists.txt
index 5afad2f674763..5c59c7fda5d29 100644
--- a/libc/test/integration/src/pthread/CMakeLists.txt
+++ b/libc/test/integration/src/pthread/CMakeLists.txt
@@ -291,3 +291,20 @@ add_integration_test(
libc.src.__support.CPP.array
libc.src.__support.CPP.new
)
+
+add_integration_test(
+ pthread_setschedparam_test
+ SUITE
+ libc-pthread-integration-tests
+ SRCS
+ pthread_setschedparam_test.cpp
+ DEPENDS
+ libc.hdr.sched_macros
+ libc.include.pthread
+ libc.src.errno.errno
+ libc.src.pthread.pthread_create
+ libc.src.pthread.pthread_join
+ libc.src.pthread.pthread_self
+ libc.src.pthread.pthread_setschedparam
+ libc.src.pthread.pthread_getschedparam
+)
diff --git a/libc/test/integration/src/pthread/pthread_setschedparam_test.cpp b/libc/test/integration/src/pthread/pthread_setschedparam_test.cpp
new file mode 100644
index 0000000000000..555f8c54ca432
--- /dev/null
+++ b/libc/test/integration/src/pthread/pthread_setschedparam_test.cpp
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Integration tests for pthread_setschedparam and pthread_getschedparam.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/sched_macros.h"
+#include "src/pthread/pthread_create.h"
+#include "src/pthread/pthread_getschedparam.h"
+#include "src/pthread/pthread_join.h"
+#include "src/pthread/pthread_self.h"
+#include "src/pthread/pthread_setschedparam.h"
+#include "test/IntegrationTest/test.h"
+
+#include <errno.h>
+#include <pthread.h>
+
+static void *child_func(void *) { return nullptr; }
+
+TEST_MAIN() {
+ auto main_thread = LIBC_NAMESPACE::pthread_self();
+ struct sched_param param;
+ int policy;
+
+ // 1. Test getschedparam on self
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_getschedparam(main_thread, &policy, ¶m),
+ 0);
+
+ // 2. Test setschedparam on self (Success)
+ param.sched_priority = 0;
+ ASSERT_EQ(
+ LIBC_NAMESPACE::pthread_setschedparam(main_thread, SCHED_OTHER, ¶m),
+ 0);
+
+ // Verify it was set
+ int new_policy;
+ struct sched_param new_param;
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_getschedparam(main_thread, &new_policy,
+ &new_param),
+ 0);
+ ASSERT_EQ(new_policy, SCHED_OTHER);
+ ASSERT_EQ(new_param.sched_priority, 0);
+
+ // 3. Test setschedparam on self (Failure - Invalid Policy)
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_setschedparam(main_thread, -1, ¶m),
+ EINVAL);
+
+ // 4. Test setschedparam on self (Failure - Invalid Priority for SCHED_OTHER)
+ param.sched_priority = 1; // Invalid for SCHED_OTHER
+ ASSERT_EQ(
+ LIBC_NAMESPACE::pthread_setschedparam(main_thread, SCHED_OTHER, ¶m),
+ EINVAL);
+ param.sched_priority = 0; // Reset
+
+ // 5. Test on Child Thread
+ pthread_t th;
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_create(&th, nullptr, child_func, nullptr),
+ 0);
+
+ // Get child's default sched param
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_getschedparam(th, &policy, ¶m), 0);
+
+ // Set child's sched param (Success)
+ param.sched_priority = 0;
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_setschedparam(th, SCHED_OTHER, ¶m), 0);
+
+ // Verify child's sched param
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_getschedparam(th, &new_policy, &new_param),
+ 0);
+ ASSERT_EQ(new_policy, SCHED_OTHER);
+ ASSERT_EQ(new_param.sched_priority, 0);
+
+ // Set child's sched param (Failure - Invalid Policy)
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_setschedparam(th, -1, ¶m), EINVAL);
+
+ // Set child's sched param (Failure - Invalid Priority)
+ param.sched_priority = 1;
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_setschedparam(th, SCHED_OTHER, ¶m),
+ EINVAL);
+
+ void *retval;
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_join(th, &retval), 0);
+
+ return 0;
+}
>From 85c06721421ec2bf17baf3a54b04c4c13bf62cc3 Mon Sep 17 00:00:00 2001
From: Jeff Bailey <jbailey at raspberryginger.com>
Date: Thu, 2 Jul 2026 23:21:09 +0100
Subject: [PATCH 2/2] [libc] Refactor internal thread scheduling APIs
Refactored the internal thread scheduling APIs to address PR comments:
* Use syscall_checked in scheduling syscall wrappers.
* Group scheduling policy and parameters into SchedParameters struct.
* Update Thread scheduling methods to use the new struct.
* Use ErrorOr for getschedparam to propagate errors.
* Remove redundant null checks in Thread implementation.
Assisted-by: Automated tooling, human reviewed.
---
.../linux/syscall_wrappers/sched_getparam.h | 7 ++-----
.../syscall_wrappers/sched_getscheduler.h | 7 ++-----
.../syscall_wrappers/sched_setscheduler.h | 7 ++-----
libc/src/__support/threads/CMakeLists.txt | 2 ++
libc/src/__support/threads/linux/thread.cpp | 18 +++++++++---------
libc/src/__support/threads/thread.h | 19 +++++++++++--------
libc/src/pthread/pthread_getschedparam.cpp | 8 +++++++-
libc/src/pthread/pthread_setschedparam.cpp | 2 +-
8 files changed, 36 insertions(+), 34 deletions(-)
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getparam.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getparam.h
index 7eab051c67972..e51c9f4ff3e32 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getparam.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getparam.h
@@ -16,7 +16,7 @@
#include "hdr/types/pid_t.h"
#include "hdr/types/struct_sched_param.h"
-#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_checked
#include "src/__support/common.h"
#include "src/__support/error_or.h"
#include "src/__support/macros/config.h"
@@ -27,10 +27,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace linux_syscalls {
LIBC_INLINE ErrorOr<int> sched_getparam(pid_t tid, struct sched_param *param) {
- int ret = syscall_impl<int>(SYS_sched_getparam, tid, param);
- if (ret < 0)
- return Error(-ret);
- return ret;
+ return syscall_checked<int>(SYS_sched_getparam, tid, param);
}
} // namespace linux_syscalls
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getscheduler.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getscheduler.h
index 84ebf1aecc4ad..2db85d77be67b 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getscheduler.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_getscheduler.h
@@ -15,7 +15,7 @@
#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SCHED_GETSCHEDULER_H
#include "hdr/types/pid_t.h"
-#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_checked
#include "src/__support/common.h"
#include "src/__support/error_or.h"
#include "src/__support/macros/config.h"
@@ -26,10 +26,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace linux_syscalls {
LIBC_INLINE ErrorOr<int> sched_getscheduler(pid_t tid) {
- int ret = syscall_impl<int>(SYS_sched_getscheduler, tid);
- if (ret < 0)
- return Error(-ret);
- return ret;
+ return syscall_checked<int>(SYS_sched_getscheduler, tid);
}
} // namespace linux_syscalls
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_setscheduler.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_setscheduler.h
index 122f4c1e7c4ed..132d258f9680e 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_setscheduler.h
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/sched_setscheduler.h
@@ -16,7 +16,7 @@
#include "hdr/types/pid_t.h"
#include "hdr/types/struct_sched_param.h"
-#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_checked
#include "src/__support/common.h"
#include "src/__support/error_or.h"
#include "src/__support/macros/config.h"
@@ -28,10 +28,7 @@ namespace linux_syscalls {
LIBC_INLINE ErrorOr<int> sched_setscheduler(pid_t tid, int policy,
const struct sched_param *param) {
- int ret = syscall_impl<int>(SYS_sched_setscheduler, tid, policy, param);
- if (ret < 0)
- return Error(-ret);
- return ret;
+ return syscall_checked<int>(SYS_sched_setscheduler, tid, policy, param);
}
} // namespace linux_syscalls
diff --git a/libc/src/__support/threads/CMakeLists.txt b/libc/src/__support/threads/CMakeLists.txt
index 0846a78bbf904..cc51b4f239b89 100644
--- a/libc/src/__support/threads/CMakeLists.txt
+++ b/libc/src/__support/threads/CMakeLists.txt
@@ -112,7 +112,9 @@ add_header_library(
thread.h
DEPENDS
libc.hdr.stdint_proxy
+ libc.hdr.types.struct_sched_param
libc.src.__support.common
+ libc.src.__support.error_or
libc.src.__support.CPP.atomic
libc.src.__support.CPP.optional
libc.src.__support.CPP.string_view
diff --git a/libc/src/__support/threads/linux/thread.cpp b/libc/src/__support/threads/linux/thread.cpp
index 4d43f59f8ea9d..704916fff95e6 100644
--- a/libc/src/__support/threads/linux/thread.cpp
+++ b/libc/src/__support/threads/linux/thread.cpp
@@ -493,25 +493,25 @@ int Thread::get_name(cpp::StringStream &name) const {
return 0;
}
-int Thread::setschedparam(int policy, const struct sched_param *param) {
- auto result = linux_syscalls::sched_setscheduler(attrib->tid, policy, param);
+int Thread::setschedparam(SchedParameters params) {
+ auto result = linux_syscalls::sched_setscheduler(attrib->tid, params.policy,
+ ¶ms.param);
if (!result.has_value())
return result.error();
return 0;
}
-int Thread::getschedparam(int *policy, struct sched_param *param) const {
+ErrorOr<SchedParameters> Thread::getschedparam() const {
auto pol_result = linux_syscalls::sched_getscheduler(attrib->tid);
if (!pol_result.has_value())
- return pol_result.error();
+ return Error(pol_result.error());
- auto param_result = linux_syscalls::sched_getparam(attrib->tid, param);
+ struct sched_param param;
+ auto param_result = linux_syscalls::sched_getparam(attrib->tid, ¶m);
if (!param_result.has_value())
- return param_result.error();
+ return Error(param_result.error());
- if (policy != nullptr)
- *policy = pol_result.value();
- return 0;
+ return SchedParameters{pol_result.value(), param};
}
void thread_exit(ThreadReturnValue retval, ThreadStyle style) {
diff --git a/libc/src/__support/threads/thread.h b/libc/src/__support/threads/thread.h
index 9c66db5a15598..94359cd626cd9 100644
--- a/libc/src/__support/threads/thread.h
+++ b/libc/src/__support/threads/thread.h
@@ -23,10 +23,16 @@
#include <stddef.h> // For size_t
-struct sched_param;
+#include "hdr/types/struct_sched_param.h"
+#include "src/__support/error_or.h"
namespace LIBC_NAMESPACE_DECL {
+struct SchedParameters {
+ int policy;
+ struct sched_param param;
+};
+
using ThreadRunnerPosix = void *(void *);
using ThreadRunnerStdc = int(void *);
@@ -235,17 +241,14 @@ struct Thread {
/// Set the scheduling policy and parameters of the thread.
///
- /// \param policy The new scheduling policy.
- /// \param param The new scheduling parameters.
+ /// \param params The new scheduling policy and parameters.
/// \return 0 on success, or an error number on failure.
- int setschedparam(int policy, const struct sched_param *param);
+ int setschedparam(SchedParameters params);
/// Get the scheduling policy and parameters of the thread.
///
- /// \param policy Pointer to store the retrieved policy (can be null).
- /// \param param Pointer to store the retrieved parameters.
- /// \return 0 on success, or an error number on failure.
- int getschedparam(int *policy, struct sched_param *param) const;
+ /// \return SchedParameters on success, or an error number on failure.
+ ErrorOr<SchedParameters> getschedparam() const;
};
LIBC_INLINE_VAR LIBC_THREAD_LOCAL Thread self;
diff --git a/libc/src/pthread/pthread_getschedparam.cpp b/libc/src/pthread/pthread_getschedparam.cpp
index ade50a11af263..31f6a162022d0 100644
--- a/libc/src/pthread/pthread_getschedparam.cpp
+++ b/libc/src/pthread/pthread_getschedparam.cpp
@@ -31,7 +31,13 @@ LLVM_LIBC_FUNCTION(int, pthread_getschedparam,
LIBC_CRASH_ON_NULLPTR(policy);
LIBC_CRASH_ON_NULLPTR(param);
auto *thread = reinterpret_cast<Thread *>(&th);
- return thread->getschedparam(policy, param);
+ auto result = thread->getschedparam();
+ if (!result.has_value())
+ return result.error();
+
+ *policy = result.value().policy;
+ *param = result.value().param;
+ return 0;
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/pthread/pthread_setschedparam.cpp b/libc/src/pthread/pthread_setschedparam.cpp
index c7b29848c58de..9d1b5a5215ecf 100644
--- a/libc/src/pthread/pthread_setschedparam.cpp
+++ b/libc/src/pthread/pthread_setschedparam.cpp
@@ -30,7 +30,7 @@ LLVM_LIBC_FUNCTION(int, pthread_setschedparam,
const struct sched_param *param)) {
LIBC_CRASH_ON_NULLPTR(param);
auto *thread = reinterpret_cast<Thread *>(&th);
- return thread->setschedparam(policy, param);
+ return thread->setschedparam({policy, *param});
}
} // namespace LIBC_NAMESPACE_DECL
More information about the libc-commits
mailing list