brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 57eb598 Raw
158 lines · cpp
1//===-- Unittests for sched_{set,get}{scheduler,param} --------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "src/__support/libc_errno.h"10#include "src/sched/sched_get_priority_max.h"11#include "src/sched/sched_get_priority_min.h"12#include "src/sched/sched_getparam.h"13#include "src/sched/sched_getscheduler.h"14#include "src/sched/sched_setparam.h"15#include "src/sched/sched_setscheduler.h"16#include "src/unistd/getuid.h"17#include "test/UnitTest/ErrnoCheckingTest.h"18#include "test/UnitTest/Test.h"19 20#include "hdr/sched_macros.h"21#include "hdr/types/struct_sched_param.h"22 23// We Test:24// SCHED_OTHER, SCHED_FIFO, SCHED_RR25//26// TODO: Missing two tests.27//       1) Missing permissions -> EPERM. Maybe doable by finding28//          another pid that exists and changing its policy, but that29//          seems risky. Maybe something with fork/clone would work.30//31//       2) Unkown pid -> ESRCH. Probably safe to choose a large range32//          number or scanning current pids and getting one that doesn't33//          exist, but again seems like it may risk actually changing34//          sched policy on a running task.35//36//       Linux specific test could also include:37//          SCHED_ISO, SCHED_DEADLINE38 39class SchedTest : public LIBC_NAMESPACE::testing::ErrnoCheckingTest {40public:41  void testSched(int policy, bool is_mandatory) {42    int init_policy = LIBC_NAMESPACE::sched_getscheduler(0);43    ASSERT_GE(init_policy, 0);44    ASSERT_ERRNO_SUCCESS();45 46    int max_priority = LIBC_NAMESPACE::sched_get_priority_max(policy);47    ASSERT_GE(max_priority, 0);48    ASSERT_ERRNO_SUCCESS();49    int min_priority = LIBC_NAMESPACE::sched_get_priority_min(policy);50    ASSERT_GE(min_priority, 0);51    ASSERT_ERRNO_SUCCESS();52 53    struct sched_param param = {min_priority};54 55    // Negative pid56    ASSERT_EQ(LIBC_NAMESPACE::sched_setscheduler(-1, policy, &param), -1);57    ASSERT_ERRNO_EQ(EINVAL);58 59    ASSERT_EQ(LIBC_NAMESPACE::sched_getscheduler(-1), -1);60    ASSERT_ERRNO_EQ(EINVAL);61 62    // Invalid Policy63    ASSERT_EQ(LIBC_NAMESPACE::sched_setscheduler(0, policy | 128, &param), -1);64    ASSERT_ERRNO_EQ(EINVAL);65 66    // Out of bounds priority67    param.sched_priority = min_priority - 1;68    ASSERT_EQ(LIBC_NAMESPACE::sched_setscheduler(0, policy, &param), -1);69    ASSERT_ERRNO_EQ(EINVAL);70 71    param.sched_priority = max_priority + 1;72    ASSERT_EQ(LIBC_NAMESPACE::sched_setscheduler(0, policy, &param), -1);73    // A bit hard to test as depending on user privileges we can run into74    // different issues.75    ASSERT_TRUE(libc_errno == EINVAL || libc_errno == EPERM);76    libc_errno = 0;77 78    param.sched_priority = min_priority;79    // Success/unsupported policy/missing permissions.80    int setscheduler_result =81        LIBC_NAMESPACE::sched_setscheduler(0, policy, &param);82    ASSERT_TRUE(setscheduler_result == 0 || setscheduler_result == -1);83    ASSERT_TRUE(84        setscheduler_result != -185            ? (libc_errno == 0)86            : ((!is_mandatory && libc_errno == EINVAL) || libc_errno == EPERM));87    libc_errno = 0;88 89    ASSERT_EQ(LIBC_NAMESPACE::sched_getscheduler(0),90              setscheduler_result != -1 ? policy : init_policy);91    ASSERT_ERRNO_SUCCESS();92 93    // Out of bounds priority94    param.sched_priority = -1;95    ASSERT_EQ(LIBC_NAMESPACE::sched_setparam(0, &param), -1);96    ASSERT_ERRNO_EQ(EINVAL);97 98    param.sched_priority = max_priority + 1;99    ASSERT_EQ(LIBC_NAMESPACE::sched_setparam(0, &param), -1);100    ASSERT_ERRNO_EQ(EINVAL);101 102    for (int priority = min_priority; priority <= max_priority; ++priority) {103      ASSERT_EQ(LIBC_NAMESPACE::sched_getparam(0, &param), 0);104      ASSERT_ERRNO_SUCCESS();105      int init_priority = param.sched_priority;106 107      param.sched_priority = priority;108 109      // Negative pid110      ASSERT_EQ(LIBC_NAMESPACE::sched_setparam(-1, &param), -1);111      ASSERT_ERRNO_EQ(EINVAL);112 113      ASSERT_EQ(LIBC_NAMESPACE::sched_getparam(-1, &param), -1);114      ASSERT_ERRNO_EQ(EINVAL);115 116      // Success/unsupported policy/missing permissions117      int setparam_result = LIBC_NAMESPACE::sched_setparam(0, &param);118      ASSERT_TRUE(setparam_result == 0 || setparam_result == -1);119      ASSERT_TRUE(setparam_result != -1120                      ? (libc_errno == 0)121                      : ((setscheduler_result == -1 && libc_errno == EINVAL) ||122                         libc_errno == EPERM));123      libc_errno = 0;124 125      ASSERT_EQ(LIBC_NAMESPACE::sched_getparam(0, &param), 0);126      ASSERT_ERRNO_SUCCESS();127 128      ASSERT_EQ(param.sched_priority,129                setparam_result != -1 ? priority : init_priority);130    }131 132    // Null test133    ASSERT_EQ(LIBC_NAMESPACE::sched_setscheduler(0, policy, nullptr), -1);134    ASSERT_ERRNO_EQ(EINVAL);135  }136};137 138#define LIST_SCHED_TESTS(policy, can_set)                                      \139  using LlvmLibcSchedTest = SchedTest;                                         \140  TEST_F(LlvmLibcSchedTest, Sched_##policy) { testSched(policy, can_set); }141 142// Mandated by POSIX.143LIST_SCHED_TESTS(SCHED_OTHER, true)144LIST_SCHED_TESTS(SCHED_FIFO, true)145LIST_SCHED_TESTS(SCHED_RR, true)146 147// Linux extensions.148LIST_SCHED_TESTS(SCHED_BATCH, true)149LIST_SCHED_TESTS(SCHED_IDLE, true)150 151TEST(LlvmLibcSchedParamAndSchedulerTest, NullParamTest) {152  ASSERT_EQ(LIBC_NAMESPACE::sched_setparam(0, nullptr), -1);153  ASSERT_ERRNO_EQ(EINVAL);154 155  ASSERT_EQ(LIBC_NAMESPACE::sched_getparam(0, nullptr), -1);156  ASSERT_ERRNO_EQ(EINVAL);157}158