1 | //===-- Unittests for sched_rr_get_interval -------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "src/errno/libc_errno.h" |
10 | #include "src/sched/sched_get_priority_min.h" |
11 | #include "src/sched/sched_getscheduler.h" |
12 | #include "src/sched/sched_rr_get_interval.h" |
13 | #include "src/sched/sched_setscheduler.h" |
14 | #include "src/unistd/getuid.h" |
15 | #include "test/UnitTest/Test.h" |
16 | |
17 | #include <sched.h> |
18 | |
19 | TEST(LlvmLibcSchedRRGetIntervalTest, SmokeTest) { |
20 | LIBC_NAMESPACE::libc_errno = 0; |
21 | auto SetSched = [&](int policy) { |
22 | int min_priority = LIBC_NAMESPACE::sched_get_priority_min(policy); |
23 | ASSERT_GE(min_priority, 0); |
24 | ASSERT_ERRNO_SUCCESS(); |
25 | struct sched_param param; |
26 | param.sched_priority = min_priority; |
27 | ASSERT_EQ(LIBC_NAMESPACE::sched_setscheduler(0, policy, ¶m), 0); |
28 | ASSERT_ERRNO_SUCCESS(); |
29 | }; |
30 | |
31 | auto TimespecToNs = [](struct timespec t) { |
32 | return static_cast<uint64_t>(t.tv_sec * 1000UL * 1000UL * 1000UL + |
33 | t.tv_nsec); |
34 | }; |
35 | |
36 | struct timespec ts; |
37 | |
38 | // We can only set SCHED_RR with CAP_SYS_ADMIN |
39 | if (LIBC_NAMESPACE::getuid() == 0) |
40 | SetSched(SCHED_RR); |
41 | |
42 | int cur_policy = LIBC_NAMESPACE::sched_getscheduler(tid: 0); |
43 | ASSERT_GE(cur_policy, 0); |
44 | ASSERT_ERRNO_SUCCESS(); |
45 | |
46 | // We can actually run meaningful tests. |
47 | if (cur_policy == SCHED_RR) { |
48 | // Success |
49 | ASSERT_EQ(LIBC_NAMESPACE::sched_rr_get_interval(0, &ts), 0); |
50 | ASSERT_ERRNO_SUCCESS(); |
51 | |
52 | // Check that numbers make sense (liberal bound of 10ns - 30sec) |
53 | constexpr uint64_t tenNs = 10UL; |
54 | ASSERT_GT(TimespecToNs(ts), tenNs); |
55 | constexpr uint64_t thirstyS = 30UL * 1000UL * 1000UL * 1000UL; |
56 | ASSERT_LT(TimespecToNs(ts), thirstyS); |
57 | |
58 | // Null timespec |
59 | ASSERT_EQ(LIBC_NAMESPACE::sched_rr_get_interval(0, nullptr), -1); |
60 | ASSERT_ERRNO_EQ(EFAULT); |
61 | LIBC_NAMESPACE::libc_errno = 0; |
62 | |
63 | // Negative pid |
64 | ASSERT_EQ(LIBC_NAMESPACE::sched_rr_get_interval(-1, &ts), -1); |
65 | ASSERT_ERRNO_EQ(EINVAL); |
66 | LIBC_NAMESPACE::libc_errno = 0; |
67 | } |
68 | |
69 | // Negative tests don't have SCHED_RR set |
70 | SetSched(SCHED_OTHER); |
71 | ASSERT_EQ(LIBC_NAMESPACE::sched_rr_get_interval(0, &ts), 0); |
72 | ASSERT_ERRNO_SUCCESS(); |
73 | LIBC_NAMESPACE::libc_errno = 0; |
74 | |
75 | // TODO: Missing unkown pid -> ESRCH. This is read only so safe to try a few |
76 | // unlikely values. |
77 | } |
78 | |