1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <condition_variable>
17 #include "gtest/gtest.h"
18 #include "os/thread.h"
19
20 namespace panda::os::thread {
21 class ThreadTest : public testing::Test {};
22
23 uint32_t thread_id = 0;
24 bool updated = false;
25 bool operated = false;
26 std::mutex mu;
27 std::condition_variable cv;
28
29 #ifdef PANDA_TARGET_UNIX
30 constexpr int LOWER_PRIOIRITY = 1;
31 #elif defined(PANDA_TARGET_WINDOWS)
32 constexpr int LOWER_PRIOIRITY = -1;
33 #endif
34
ThreadFunc()35 void ThreadFunc()
36 {
37 thread_id = GetCurrentThreadId();
38 {
39 std::lock_guard lk(mu);
40 updated = true;
41 }
42 cv.notify_one();
43 {
44 // wait for the main thread to Set/GetPriority
45 std::unique_lock lk(mu);
46 cv.wait(lk, [] { return operated; });
47 }
48 }
49
50 HWTEST_F(ThreadTest, SetCurrentThreadPriorityTest, testing::ext::TestSize.Level0)
51 {
52 // Since setting higher priority needs "sudo" right, we only test lower one here.
53 auto ret1 = SetPriority(GetCurrentThreadId(), LOWER_PRIOIRITY);
54 auto prio1 = GetPriority(GetCurrentThreadId());
55 ASSERT_EQ(prio1, LOWER_PRIOIRITY);
56
57 auto ret2 = SetPriority(GetCurrentThreadId(), LOWEST_PRIORITY);
58 auto prio2 = GetPriority(GetCurrentThreadId());
59 ASSERT_EQ(prio2, LOWEST_PRIORITY);
60
61 #ifdef PANDA_TARGET_UNIX
62 ASSERT_EQ(ret1, 0);
63 ASSERT_EQ(ret2, 0);
64 #elif defined(PANDA_TARGET_WINDOWS)
65 ASSERT_NE(ret1, 0);
66 ASSERT_NE(ret2, 0);
67 #endif
68 }
69
70 HWTEST_F(ThreadTest, SetOtherThreadPriorityTest, testing::ext::TestSize.Level0)
71 {
72 auto parent_pid = GetCurrentThreadId();
73 auto parent_prio_before = GetPriority(parent_pid);
74
75 auto new_thread = ThreadStart(ThreadFunc);
76 // wait for the new_thread to update thread_id
77 std::unique_lock lk(mu);
__anon8a26ea540202null78 cv.wait(lk, [] { return updated; });
79 auto child_pid = thread_id;
80
81 auto child_prio_before = GetPriority(child_pid);
82 auto ret = SetPriority(child_pid, LOWEST_PRIORITY);
83
84 auto child_prio_after = GetPriority(child_pid);
85 auto parent_prio_after = GetPriority(parent_pid);
86
87 operated = true;
88 lk.unlock();
89 cv.notify_one();
90 void *res;
91 ThreadJoin(new_thread, &res);
92
93 ASSERT_EQ(parent_prio_before, parent_prio_after);
94 #ifdef PANDA_TARGET_UNIX
95 ASSERT_EQ(ret, 0);
96 ASSERT_TRUE(child_prio_before <= child_prio_after);
97 #elif defined(PANDA_TARGET_WINDOWS)
98 ASSERT_NE(ret, 0);
99 ASSERT_TRUE(child_prio_after <= child_prio_before);
100 #endif
101 }
102 } // namespace panda::os::thread
103