| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| //===-- Implementation of sched_get_priority_min --------------------------===// | ||
| // | ||
| // 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_get_priority_min.h" | ||
|
|
||
| #include "src/__support/OSUtil/syscall.h" // For internal syscall function. | ||
| #include "src/__support/common.h" | ||
| #include "src/errno/libc_errno.h" | ||
|
|
||
| #include <sys/syscall.h> // For syscall numbers. | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| LLVM_LIBC_FUNCTION(int, sched_get_priority_min, (int policy)) { | ||
| long ret = __llvm_libc::syscall_impl(SYS_sched_get_priority_min, policy); | ||
| if (ret < 0) { | ||
| libc_errno = -ret; | ||
| return -1; | ||
| } | ||
| return ret; | ||
| } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| //===-- Implementation of sched_getparam ----------------------------------===// | ||
| // | ||
| // 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_getparam.h" | ||
|
|
||
| #include "src/__support/OSUtil/syscall.h" // For internal syscall function. | ||
| #include "src/__support/common.h" | ||
| #include "src/errno/libc_errno.h" | ||
|
|
||
| #include <sys/syscall.h> // For syscall numbers. | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| LLVM_LIBC_FUNCTION(int, sched_getparam, | ||
| (pid_t tid, struct sched_param *param)) { | ||
| long ret = __llvm_libc::syscall_impl(SYS_sched_getparam, tid, param); | ||
| if (ret < 0) { | ||
| libc_errno = -ret; | ||
| return -1; | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| //===-- Implementation of sched_getscheduler ------------------------------===// | ||
| // | ||
| // 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_getscheduler.h" | ||
|
|
||
| #include "src/__support/OSUtil/syscall.h" // For internal syscall function. | ||
| #include "src/__support/common.h" | ||
| #include "src/errno/libc_errno.h" | ||
|
|
||
| #include <sys/syscall.h> // For syscall numbers. | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| LLVM_LIBC_FUNCTION(int, sched_getscheduler, (pid_t tid)) { | ||
| long ret = __llvm_libc::syscall_impl(SYS_sched_getscheduler, tid); | ||
| if (ret < 0) { | ||
| libc_errno = -ret; | ||
| return -1; | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| //===-- Implementation of sched_rr_get_interval ---------------------------===// | ||
| // | ||
| // 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_rr_get_interval.h" | ||
|
|
||
| #include "src/__support/OSUtil/syscall.h" // For internal syscall function. | ||
| #include "src/__support/common.h" | ||
| #include "src/errno/libc_errno.h" | ||
|
|
||
| #include <sys/syscall.h> // For syscall numbers. | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| LLVM_LIBC_FUNCTION(int, sched_rr_get_interval, | ||
| (pid_t tid, struct timespec *tp)) { | ||
| long ret = __llvm_libc::syscall_impl(SYS_sched_rr_get_interval, tid, tp); | ||
| if (ret < 0) { | ||
| libc_errno = -ret; | ||
| return -1; | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| //===-- Implementation of sched_setparam ----------------------------------===// | ||
| // | ||
| // 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_setparam.h" | ||
|
|
||
| #include "src/__support/OSUtil/syscall.h" // For internal syscall function. | ||
| #include "src/__support/common.h" | ||
| #include "src/errno/libc_errno.h" | ||
|
|
||
| #include <sys/syscall.h> // For syscall numbers. | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| LLVM_LIBC_FUNCTION(int, sched_setparam, | ||
| (pid_t tid, const struct sched_param *param)) { | ||
| long ret = __llvm_libc::syscall_impl(SYS_sched_setparam, tid, param); | ||
| if (ret < 0) { | ||
| libc_errno = -ret; | ||
| return -1; | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| //===-- Implementation of sched_setscheduler ------------------------------===// | ||
| // | ||
| // 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_setscheduler.h" | ||
|
|
||
| #include "src/__support/OSUtil/syscall.h" // For internal syscall function. | ||
| #include "src/__support/common.h" | ||
| #include "src/errno/libc_errno.h" | ||
|
|
||
| #include <sys/syscall.h> // For syscall numbers. | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| LLVM_LIBC_FUNCTION(int, sched_setscheduler, | ||
| (pid_t tid, int policy, const struct sched_param *param)) { | ||
| long ret = | ||
| __llvm_libc::syscall_impl(SYS_sched_setscheduler, tid, policy, param); | ||
| if (ret < 0) { | ||
| libc_errno = -ret; | ||
| return -1; | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| } // namespace __llvm_libc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| //===-- Implementation header for sched_get_priority_max ---------*- 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_GET_PRIORITY_MAX_H | ||
| #define LLVM_LIBC_SRC_SCHED_SCHED_GET_PRIORITY_MAX_H | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| int sched_get_priority_max(int policy); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_SCHED_SCHED_GET_PRIORITY_MAX_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| //===-- Implementation header for sched_get_priority_min ---------*- 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_GET_PRIORITY_MIN_H | ||
| #define LLVM_LIBC_SRC_SCHED_SCHED_GET_PRIORITY_MIN_H | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| int sched_get_priority_min(int policy); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_SCHED_SCHED_GET_PRIORITY_MIN_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===-- Implementation header for sched_getparam ----------------*- 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_GETPARAM_H | ||
| #define LLVM_LIBC_SRC_SCHED_SCHED_GETPARAM_H | ||
|
|
||
| #include <sched.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| int sched_getparam(pid_t tid, struct sched_param *param); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_SCHED_SCHED_GETPARAM_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===-- Implementation header for sched_getscheduler -------------*- 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_GETSCHEDULER_H | ||
| #define LLVM_LIBC_SRC_SCHED_SCHED_GETSCHEDULER_H | ||
|
|
||
| #include <sched.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| int sched_getscheduler(pid_t tid); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_SCHED_SCHED_GETSCHEDULER_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===-- Implementation header for sched_rr_get_interval ----------*- 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_RR_GET_INTERVAL_H | ||
| #define LLVM_LIBC_SRC_SCHED_SCHED_RR_GET_INTERVAL_H | ||
|
|
||
| #include <sched.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| int sched_rr_get_interval(pid_t tid, struct timespec *tp); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_SCHED_SCHED_RR_GET_INTERVAL_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===-- Implementation header for sched_setparam ----------------*- 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_SETPARAM_H | ||
| #define LLVM_LIBC_SRC_SCHED_SCHED_SETPARAM_H | ||
|
|
||
| #include <sched.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| int sched_setparam(pid_t tid, const struct sched_param *param); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_SCHED_SCHED_SETPARAM_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //===-- Implementation header for sched_setscheduler -------------*- 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_SETSCHEDULER_H | ||
| #define LLVM_LIBC_SRC_SCHED_SCHED_SETSCHEDULER_H | ||
|
|
||
| #include <sched.h> | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| int sched_setscheduler(pid_t tid, int policy, const struct sched_param *param); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_SCHED_SCHED_SETSCHEDULER_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| //===-- Unittests for sched_get_priority_{min,max} ------------------------===// | ||
| // | ||
| // 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_get_priority_max.h" | ||
| #include "src/sched/sched_get_priority_min.h" | ||
| #include "test/UnitTest/Test.h" | ||
|
|
||
| #include <sched.h> | ||
|
|
||
| TEST(LlvmLibcSchedGetPriorityTest, HandleBadPolicyTest) { | ||
|
|
||
| // Test arbitrary values for which there is no policy. | ||
| { | ||
| int policy = -1; | ||
| int max_priority = __llvm_libc::sched_get_priority_max(policy); | ||
| ASSERT_EQ(max_priority, -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| int min_priority = __llvm_libc::sched_get_priority_min(policy); | ||
| ASSERT_EQ(min_priority, -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| } | ||
|
|
||
| { | ||
| int policy = 30; | ||
| int max_priority = __llvm_libc::sched_get_priority_max(policy); | ||
| ASSERT_EQ(max_priority, -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| int min_priority = __llvm_libc::sched_get_priority_min(policy); | ||
| ASSERT_EQ(min_priority, -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| } | ||
|
|
||
| { | ||
| int policy = 80; | ||
| int max_priority = __llvm_libc::sched_get_priority_max(policy); | ||
| ASSERT_EQ(max_priority, -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| int min_priority = __llvm_libc::sched_get_priority_min(policy); | ||
| ASSERT_EQ(min_priority, -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| } | ||
|
|
||
| { | ||
| int policy = 110; | ||
| int max_priority = __llvm_libc::sched_get_priority_max(policy); | ||
| ASSERT_EQ(max_priority, -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| int min_priority = __llvm_libc::sched_get_priority_min(policy); | ||
| ASSERT_EQ(min_priority, -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| } | ||
| } | ||
|
|
||
| TEST(LlvmLibcSchedGetPriorityTest, SmokeTest) { | ||
| libc_errno = 0; | ||
|
|
||
| // We Test: | ||
| // SCHED_OTHER, SCHED_FIFO, SCHED_RR | ||
| // Linux specific test could also include: | ||
| // SCHED_BATCH, SCHED_ISO, SCHED_IDLE, SCHED_DEADLINE | ||
| { | ||
| int policy = SCHED_OTHER; | ||
| int max_priority = __llvm_libc::sched_get_priority_max(policy); | ||
| ASSERT_GE(max_priority, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
| int min_priority = __llvm_libc::sched_get_priority_min(policy); | ||
| ASSERT_GE(min_priority, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| ASSERT_LE(max_priority, 99); | ||
| ASSERT_GE(min_priority, 0); | ||
| ASSERT_GE(max_priority, min_priority); | ||
| } | ||
|
|
||
| { | ||
| int policy = SCHED_FIFO; | ||
| int max_priority = __llvm_libc::sched_get_priority_max(policy); | ||
| ASSERT_GE(max_priority, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
| int min_priority = __llvm_libc::sched_get_priority_min(policy); | ||
| ASSERT_GE(min_priority, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| ASSERT_LE(max_priority, 99); | ||
| ASSERT_GE(min_priority, 0); | ||
| ASSERT_GE(max_priority, min_priority); | ||
| } | ||
|
|
||
| { | ||
| int policy = SCHED_RR; | ||
| int max_priority = __llvm_libc::sched_get_priority_max(policy); | ||
| ASSERT_GE(max_priority, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
| int min_priority = __llvm_libc::sched_get_priority_min(policy); | ||
| ASSERT_GE(min_priority, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| ASSERT_LE(max_priority, 99); | ||
| ASSERT_GE(min_priority, 0); | ||
| ASSERT_GE(max_priority, min_priority); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,353 @@ | ||
| //===-- Unittests for sched_{set,get}{scheduler,param} --------------------===// | ||
| // | ||
| // 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_get_priority_max.h" | ||
| #include "src/sched/sched_get_priority_min.h" | ||
| #include "src/sched/sched_getparam.h" | ||
| #include "src/sched/sched_getscheduler.h" | ||
| #include "src/sched/sched_setparam.h" | ||
| #include "src/sched/sched_setscheduler.h" | ||
| #include "src/unistd/getuid.h" | ||
| #include "test/UnitTest/Test.h" | ||
|
|
||
| #include <sched.h> | ||
|
|
||
| // We Test: | ||
| // SCHED_OTHER, SCHED_FIFO, SCHED_RR | ||
| // | ||
| // TODO: Missing two tests. | ||
| // 1) Missing permissions -> EPERM. Maybe doable by finding | ||
| // another pid that exists and changing its policy, but that | ||
| // seems risky. Maybe something with fork/clone would work. | ||
| // | ||
| // 2) Unkown pid -> ESRCH. Probably safe to choose a large range | ||
| // number or scanning current pids and getting one that doesn't | ||
| // exist, but again seems like it may risk actually changing | ||
| // sched policy on a running task. | ||
| // | ||
| // Linux specific test could also include: | ||
| // SCHED_BATCH, SCHED_ISO, SCHED_IDLE, SCHED_DEADLINE | ||
|
|
||
| TEST(LlvmLibcSchedParamAndSchedulerTest, SchedOtherTest) { | ||
| libc_errno = 0; | ||
|
|
||
| int policy = SCHED_OTHER; | ||
| bool can_set = true; | ||
|
|
||
| int init_policy = __llvm_libc::sched_getscheduler(0); | ||
| ASSERT_GE(init_policy, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| int max_priority = __llvm_libc::sched_get_priority_max(policy); | ||
| ASSERT_GE(max_priority, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
| int min_priority = __llvm_libc::sched_get_priority_min(policy); | ||
| ASSERT_GE(min_priority, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| struct sched_param param = {min_priority}; | ||
|
|
||
| // Negative pid | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(-1, policy, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| ASSERT_EQ(__llvm_libc::sched_getscheduler(-1), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| // Invalid Policy | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy | 128, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| // Out of bounds priority | ||
| param.sched_priority = min_priority - 1; | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| param.sched_priority = max_priority + 1; | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy, ¶m), -1); | ||
| // A bit hard to test as depending if we are root or not we can run into | ||
| // different issues. | ||
| ASSERT_TRUE(libc_errno == EINVAL || libc_errno == EPERM); | ||
| libc_errno = 0; | ||
|
|
||
| // Some sched policies require permissions, so skip | ||
| param.sched_priority = min_priority; | ||
| // Success / missing permissions. | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy, ¶m), | ||
| can_set ? 0 : -1); | ||
| ASSERT_TRUE(can_set ? (libc_errno == 0) | ||
| : (libc_errno == EINVAL || libc_errno == EPERM)); | ||
| libc_errno = 0; | ||
|
|
||
| ASSERT_EQ(__llvm_libc::sched_getscheduler(0), can_set ? policy : init_policy); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| // Out of bounds priority | ||
| param.sched_priority = -1; | ||
| ASSERT_EQ(__llvm_libc::sched_setparam(0, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| param.sched_priority = max_priority + 1; | ||
| ASSERT_EQ(__llvm_libc::sched_setparam(0, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| for (int priority = min_priority; priority <= max_priority; ++priority) { | ||
| ASSERT_EQ(__llvm_libc::sched_getparam(0, ¶m), 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
| int init_priority = param.sched_priority; | ||
|
|
||
| param.sched_priority = priority; | ||
|
|
||
| // Negative pid | ||
| ASSERT_EQ(__llvm_libc::sched_setparam(-1, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| ASSERT_EQ(__llvm_libc::sched_getparam(-1, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| // Success / missing permissions | ||
| ASSERT_EQ(__llvm_libc::sched_setparam(0, ¶m), can_set ? 0 : -1); | ||
| ASSERT_TRUE(can_set ? (libc_errno == 0) | ||
| : (libc_errno == EINVAL || libc_errno == EPERM)); | ||
| libc_errno = 0; | ||
|
|
||
| ASSERT_EQ(__llvm_libc::sched_getparam(0, ¶m), 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| ASSERT_EQ(param.sched_priority, can_set ? priority : init_priority); | ||
| } | ||
| // Null test | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy, nullptr), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
| } | ||
|
|
||
| TEST(LlvmLibcSchedParamAndSchedulerTest, SchedFIFOTest) { | ||
| libc_errno = 0; | ||
|
|
||
| int policy = SCHED_FIFO; | ||
| bool can_set = __llvm_libc::getuid() == 0; | ||
|
|
||
| int init_policy = __llvm_libc::sched_getscheduler(0); | ||
| ASSERT_GE(init_policy, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| int max_priority = __llvm_libc::sched_get_priority_max(policy); | ||
| ASSERT_GE(max_priority, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
| int min_priority = __llvm_libc::sched_get_priority_min(policy); | ||
| ASSERT_GE(min_priority, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| struct sched_param param = {min_priority}; | ||
|
|
||
| // Negative pid | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(-1, policy, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| ASSERT_EQ(__llvm_libc::sched_getscheduler(-1), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| // Invalid Policy | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy | 128, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| // Out of bounds priority | ||
| param.sched_priority = min_priority - 1; | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| param.sched_priority = max_priority + 1; | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy, ¶m), -1); | ||
| // A bit hard to test as depending if we are root or not we can run into | ||
| // different issues. | ||
| ASSERT_TRUE(libc_errno == EINVAL || libc_errno == EPERM); | ||
| libc_errno = 0; | ||
|
|
||
| // Some sched policies require permissions, so skip | ||
| param.sched_priority = min_priority; | ||
| // Success / missing permissions. | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy, ¶m), | ||
| can_set ? 0 : -1); | ||
| ASSERT_TRUE(can_set ? (libc_errno == 0) | ||
| : (libc_errno == EINVAL || libc_errno == EPERM)); | ||
| libc_errno = 0; | ||
|
|
||
| ASSERT_EQ(__llvm_libc::sched_getscheduler(0), can_set ? policy : init_policy); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| // Out of bounds priority | ||
| param.sched_priority = -1; | ||
| ASSERT_EQ(__llvm_libc::sched_setparam(0, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| param.sched_priority = max_priority + 1; | ||
| ASSERT_EQ(__llvm_libc::sched_setparam(0, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| for (int priority = min_priority; priority <= max_priority; ++priority) { | ||
| ASSERT_EQ(__llvm_libc::sched_getparam(0, ¶m), 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
| int init_priority = param.sched_priority; | ||
|
|
||
| param.sched_priority = priority; | ||
|
|
||
| // Negative pid | ||
| ASSERT_EQ(__llvm_libc::sched_setparam(-1, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| ASSERT_EQ(__llvm_libc::sched_getparam(-1, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| // Success / missing permissions | ||
| ASSERT_EQ(__llvm_libc::sched_setparam(0, ¶m), can_set ? 0 : -1); | ||
| ASSERT_TRUE(can_set ? (libc_errno == 0) | ||
| : (libc_errno == EINVAL || libc_errno == EPERM)); | ||
| libc_errno = 0; | ||
|
|
||
| ASSERT_EQ(__llvm_libc::sched_getparam(0, ¶m), 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| ASSERT_EQ(param.sched_priority, can_set ? priority : init_priority); | ||
| } | ||
| // Null test | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy, nullptr), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
| } | ||
|
|
||
| TEST(LlvmLibcSchedParamAndSchedulerTest, SchedRRTest) { | ||
| libc_errno = 0; | ||
|
|
||
| int policy = SCHED_RR; | ||
| bool can_set = __llvm_libc::getuid() == 0; | ||
|
|
||
| int init_policy = __llvm_libc::sched_getscheduler(0); | ||
| ASSERT_GE(init_policy, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| int max_priority = __llvm_libc::sched_get_priority_max(policy); | ||
| ASSERT_GE(max_priority, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
| int min_priority = __llvm_libc::sched_get_priority_min(policy); | ||
| ASSERT_GE(min_priority, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| struct sched_param param = {min_priority}; | ||
|
|
||
| // Negative pid | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(-1, policy, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| ASSERT_EQ(__llvm_libc::sched_getscheduler(-1), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| // Invalid Policy | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy | 128, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| // Out of bounds priority | ||
| param.sched_priority = min_priority - 1; | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| param.sched_priority = max_priority + 1; | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy, ¶m), -1); | ||
| // A bit hard to test as depending if we are root or not we can run into | ||
| // different issues. | ||
| ASSERT_TRUE(libc_errno == EINVAL || libc_errno == EPERM); | ||
| libc_errno = 0; | ||
|
|
||
| // Some sched policies require permissions, so skip | ||
| param.sched_priority = min_priority; | ||
| // Success / missing permissions. | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy, ¶m), | ||
| can_set ? 0 : -1); | ||
| ASSERT_TRUE(can_set ? (libc_errno == 0) | ||
| : (libc_errno == EINVAL || libc_errno == EPERM)); | ||
| libc_errno = 0; | ||
|
|
||
| ASSERT_EQ(__llvm_libc::sched_getscheduler(0), can_set ? policy : init_policy); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| // Out of bounds priority | ||
| param.sched_priority = -1; | ||
| ASSERT_EQ(__llvm_libc::sched_setparam(0, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| param.sched_priority = max_priority + 1; | ||
| ASSERT_EQ(__llvm_libc::sched_setparam(0, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| for (int priority = min_priority; priority <= max_priority; ++priority) { | ||
| ASSERT_EQ(__llvm_libc::sched_getparam(0, ¶m), 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
| int init_priority = param.sched_priority; | ||
|
|
||
| param.sched_priority = priority; | ||
|
|
||
| // Negative pid | ||
| ASSERT_EQ(__llvm_libc::sched_setparam(-1, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| ASSERT_EQ(__llvm_libc::sched_getparam(-1, ¶m), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| // Success / missing permissions | ||
| ASSERT_EQ(__llvm_libc::sched_setparam(0, ¶m), can_set ? 0 : -1); | ||
| ASSERT_TRUE(can_set ? (libc_errno == 0) | ||
| : (libc_errno == EINVAL || libc_errno == EPERM)); | ||
| libc_errno = 0; | ||
|
|
||
| ASSERT_EQ(__llvm_libc::sched_getparam(0, ¶m), 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| ASSERT_EQ(param.sched_priority, can_set ? priority : init_priority); | ||
| } | ||
| // Null test | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy, nullptr), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
| } | ||
|
|
||
| TEST(LlvmLibcSchedParamAndSchedulerTest, NullParamTest) { | ||
| libc_errno = 0; | ||
|
|
||
| ASSERT_EQ(__llvm_libc::sched_setparam(0, nullptr), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
|
|
||
| ASSERT_EQ(__llvm_libc::sched_getparam(0, nullptr), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| //===-- Unittests for sched_rr_get_interval -------------------------------===// | ||
| // | ||
| // 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_get_priority_min.h" | ||
| #include "src/sched/sched_getscheduler.h" | ||
| #include "src/sched/sched_rr_get_interval.h" | ||
| #include "src/sched/sched_setscheduler.h" | ||
| #include "src/unistd/getuid.h" | ||
| #include "test/UnitTest/Test.h" | ||
|
|
||
| #include <sched.h> | ||
|
|
||
| TEST(LlvmLibcSchedRRGetIntervalTest, SmokeTest) { | ||
| libc_errno = 0; | ||
| auto SetSched = [&](int policy) { | ||
| int min_priority = __llvm_libc::sched_get_priority_min(policy); | ||
| ASSERT_GE(min_priority, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
| struct sched_param param; | ||
| param.sched_priority = min_priority; | ||
| ASSERT_EQ(__llvm_libc::sched_setscheduler(0, policy, ¶m), 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
| }; | ||
|
|
||
| auto TimespecToNs = [](struct timespec t) { | ||
| return t.tv_sec * 1000UL * 1000UL * 1000UL + t.tv_nsec; | ||
| }; | ||
|
|
||
| struct timespec ts; | ||
|
|
||
| // We can only set SCHED_RR with CAP_SYS_ADMIN | ||
| if (__llvm_libc::getuid() == 0) | ||
| SetSched(SCHED_RR); | ||
|
|
||
| int cur_policy = __llvm_libc::sched_getscheduler(0); | ||
| ASSERT_GE(cur_policy, 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| // We can actually run meaningful tests. | ||
| if (cur_policy == SCHED_RR) { | ||
| // Success | ||
| ASSERT_EQ(__llvm_libc::sched_rr_get_interval(0, &ts), 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
|
|
||
| // Check that numbers make sense (liberal bound of 10ns - 30sec) | ||
| ASSERT_GT(TimespecToNs(ts), 10UL); | ||
| ASSERT_LT(TimespecToNs(ts), 30UL * 1000UL * 1000UL * 1000UL); | ||
|
|
||
| // Null timespec | ||
| ASSERT_EQ(__llvm_libc::sched_rr_get_interval(0, nullptr), -1); | ||
| ASSERT_EQ(libc_errno, EFAULT); | ||
| libc_errno = 0; | ||
|
|
||
| // Negative pid | ||
| ASSERT_EQ(__llvm_libc::sched_rr_get_interval(-1, &ts), -1); | ||
| ASSERT_EQ(libc_errno, EINVAL); | ||
| libc_errno = 0; | ||
| } | ||
|
|
||
| // Negative tests don't have SCHED_RR set | ||
| SetSched(SCHED_OTHER); | ||
| ASSERT_EQ(__llvm_libc::sched_rr_get_interval(0, &ts), 0); | ||
| ASSERT_EQ(libc_errno, 0); | ||
| libc_errno = 0; | ||
|
|
||
| // TODO: Missing unkown pid -> ESRCH. This is read only so safe to try a few | ||
| // unlikely values. | ||
| } |