[libc-commits] [libc] [libc] Implement pthread_setschedparam and getschedparam (PR #205770)

Jeff Bailey via libc-commits libc-commits at lists.llvm.org
Thu Jun 25 03:49:35 PDT 2026


https://github.com/kaladron updated https://github.com/llvm/llvm-project/pull/205770

>From 28b1175f777315afd9537e9be70d09a172ffa781 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] [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 599ae32a35073..ea5b23af08afd 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1060,6 +1060,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
@@ -1104,6 +1105,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 ef2d13e6d6f9e..1cf0380ba2386 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1193,6 +1193,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
@@ -1237,6 +1238,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 8046679785e68..2e004f25b3240 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1252,6 +1252,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
@@ -1299,6 +1300,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 f3282c315d9a9..22e2f1d0f5247 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -25,6 +25,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 8344c6c0462a3..21a551d15557a 100644
--- a/libc/src/__support/threads/linux/CMakeLists.txt
+++ b/libc/src/__support/threads/linux/CMakeLists.txt
@@ -45,6 +45,9 @@ add_object_library(
     libc.src.__support.OSUtil.linux.syscall_wrappers.mprotect
     libc.src.__support.OSUtil.linux.syscall_wrappers.munmap
     libc.src.__support.OSUtil.linux.syscall_wrappers.open
+    libc.src.__support.OSUtil.linux.syscall_wrappers.sched_setscheduler
+    libc.src.__support.OSUtil.linux.syscall_wrappers.sched_getscheduler
+    libc.src.__support.OSUtil.linux.syscall_wrappers.sched_getparam
     libc.src.__support.threads.thread_common
   COMPILE_OPTIONS
     ${libc_opt_high_flag}
diff --git a/libc/src/__support/threads/linux/thread.cpp b/libc/src/__support/threads/linux/thread.cpp
index 64e043862ff74..d1e7ad37a2670 100644
--- a/libc/src/__support/threads/linux/thread.cpp
+++ b/libc/src/__support/threads/linux/thread.cpp
@@ -15,6 +15,9 @@
 #include "src/__support/OSUtil/linux/syscall_wrappers/mprotect.h"
 #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/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/syscall.h" // For syscall functions.
 #include "src/__support/common.h"
 #include "src/__support/error_or.h"
@@ -486,6 +489,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 7901d5ce67a5e..2d0b4a7b5bcf3 100644
--- a/libc/src/pthread/CMakeLists.txt
+++ b/libc/src/pthread/CMakeLists.txt
@@ -940,3 +940,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, &param),
+            0);
+
+  // 2. Test setschedparam on self (Success)
+  param.sched_priority = 0;
+  ASSERT_EQ(
+      LIBC_NAMESPACE::pthread_setschedparam(main_thread, SCHED_OTHER, &param),
+      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, &param),
+            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, &param),
+      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, &param), 0);
+
+  // Set child's sched param (Success)
+  param.sched_priority = 0;
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_setschedparam(th, SCHED_OTHER, &param), 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, &param), EINVAL);
+
+  // Set child's sched param (Failure - Invalid Priority)
+  param.sched_priority = 1;
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_setschedparam(th, SCHED_OTHER, &param),
+            EINVAL);
+
+  void *retval;
+  ASSERT_EQ(LIBC_NAMESPACE::pthread_join(th, &retval), 0);
+
+  return 0;
+}



More information about the libc-commits mailing list