xref: /llvm-project/libc/src/sched/linux/sched_rr_get_interval.cpp (revision 5ff3ff33ff930e4ec49da7910612d8a41eb068cb)
10432b85dSNoah Goldstein //===-- Implementation of sched_rr_get_interval ---------------------------===//
20432b85dSNoah Goldstein //
30432b85dSNoah Goldstein // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40432b85dSNoah Goldstein // See https://llvm.org/LICENSE.txt for license information.
50432b85dSNoah Goldstein // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60432b85dSNoah Goldstein //
70432b85dSNoah Goldstein //===----------------------------------------------------------------------===//
80432b85dSNoah Goldstein 
90432b85dSNoah Goldstein #include "src/sched/sched_rr_get_interval.h"
100432b85dSNoah Goldstein 
110432b85dSNoah Goldstein #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
120432b85dSNoah Goldstein #include "src/__support/common.h"
13*5ff3ff33SPetr Hosek #include "src/__support/macros/config.h"
140432b85dSNoah Goldstein #include "src/errno/libc_errno.h"
150432b85dSNoah Goldstein 
160432b85dSNoah Goldstein #include <sys/syscall.h> // For syscall numbers.
170432b85dSNoah Goldstein 
1829dec352SMikhail R. Gadelha #ifdef SYS_sched_rr_get_interval_time64
1929dec352SMikhail R. Gadelha #include <linux/time_types.h> // For __kernel_timespec.
2029dec352SMikhail R. Gadelha #endif
2129dec352SMikhail R. Gadelha 
22*5ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL {
230432b85dSNoah Goldstein 
240432b85dSNoah Goldstein LLVM_LIBC_FUNCTION(int, sched_rr_get_interval,
250432b85dSNoah Goldstein                    (pid_t tid, struct timespec *tp)) {
26c9783d2bSMikhail R. Gadelha #ifdef SYS_sched_rr_get_interval
27b6bc9d72SGuillaume Chatelet   int ret =
28b6bc9d72SGuillaume Chatelet       LIBC_NAMESPACE::syscall_impl<int>(SYS_sched_rr_get_interval, tid, tp);
29c9783d2bSMikhail R. Gadelha #elif defined(SYS_sched_rr_get_interval_time64)
30c9783d2bSMikhail R. Gadelha   // The difference between the  and SYS_sched_rr_get_interval
31c9783d2bSMikhail R. Gadelha   // SYS_sched_rr_get_interval_time64 syscalls is the data type used for the
32c9783d2bSMikhail R. Gadelha   // time interval parameter: the latter takes a struct __kernel_timespec
33f0a3954eSMichael Jones   int ret;
34c9783d2bSMikhail R. Gadelha   if (tp) {
35c9783d2bSMikhail R. Gadelha     struct __kernel_timespec ts32;
36b6bc9d72SGuillaume Chatelet     ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_sched_rr_get_interval_time64,
37b6bc9d72SGuillaume Chatelet                                             tid, &ts32);
38c9783d2bSMikhail R. Gadelha     if (ret == 0) {
39c9783d2bSMikhail R. Gadelha       tp->tv_sec = ts32.tv_sec;
408bb4294bSMikhail R. Gadelha       tp->tv_nsec = static_cast<long int>(ts32.tv_nsec);
41c9783d2bSMikhail R. Gadelha     }
42c9783d2bSMikhail R. Gadelha   } else
43c9783d2bSMikhail R. Gadelha     // When tp is a nullptr, we still do the syscall to set ret and errno
44b6bc9d72SGuillaume Chatelet     ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_sched_rr_get_interval_time64,
45b6bc9d72SGuillaume Chatelet                                             tid, nullptr);
46c9783d2bSMikhail R. Gadelha #else
47c9783d2bSMikhail R. Gadelha #error                                                                         \
48c9783d2bSMikhail R. Gadelha     "sched_rr_get_interval and sched_rr_get_interval_time64 syscalls not available."
49c9783d2bSMikhail R. Gadelha #endif
500432b85dSNoah Goldstein   if (ret < 0) {
510432b85dSNoah Goldstein     libc_errno = -ret;
520432b85dSNoah Goldstein     return -1;
530432b85dSNoah Goldstein   }
540432b85dSNoah Goldstein   return 0;
550432b85dSNoah Goldstein }
560432b85dSNoah Goldstein 
57*5ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL
58