• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 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 "gtest/gtest.h"
17 #include "os/thread.h"
18 #include "os/mutex.h"
19 
20 namespace ark::os::thread {
21 class ThreadTest : public testing::Test {};
22 
23 uint32_t g_curThreadId = 0;
24 bool g_updated = false;
25 bool g_operated = false;
26 // NOLINTNEXTLINE(fuchsia-statically-constructed-objects)
27 os::memory::Mutex g_mu;
28 // NOLINTNEXTLINE(fuchsia-statically-constructed-objects)
29 os::memory::ConditionVariable g_cv;
30 
31 #ifdef PANDA_TARGET_UNIX
32 constexpr int LOWER_PRIOIRITY = 1;
33 #elif defined(PANDA_TARGET_WINDOWS)
34 constexpr int LOWER_PRIOIRITY = -1;
35 #endif
36 
ThreadFunc()37 void ThreadFunc()
38 {
39     g_curThreadId = GetCurrentThreadId();
40     {
41         os::memory::LockHolder lk(g_mu);
42         g_updated = true;
43     }
44     g_cv.Signal();
45     {
46         // wait for the main thread to Set/GetPriority
47         os::memory::LockHolder lk(g_mu);
48         while (!g_operated) {
49             g_cv.Wait(&g_mu);
50         }
51     }
52 }
53 
TEST_F(ThreadTest,SetCurrentThreadPriorityTest)54 TEST_F(ThreadTest, SetCurrentThreadPriorityTest)
55 {
56     // Since setting higher priority needs "sudo" right, we only test lower one here.
57     auto ret1 = SetPriority(GetCurrentThreadId(), LOWER_PRIOIRITY);
58     auto prio1 = GetPriority(GetCurrentThreadId());
59     ASSERT_EQ(prio1, LOWER_PRIOIRITY);
60 
61     auto ret2 = SetPriority(GetCurrentThreadId(), LOWEST_PRIORITY);
62     auto prio2 = GetPriority(GetCurrentThreadId());
63     ASSERT_EQ(prio2, LOWEST_PRIORITY);
64 
65 #ifdef PANDA_TARGET_UNIX
66     ASSERT_EQ(ret1, 0U);
67     ASSERT_EQ(ret2, 0U);
68 #elif defined(PANDA_TARGET_WINDOWS)
69     ASSERT_NE(ret1, 0U);
70     ASSERT_NE(ret2, 0U);
71 #endif
72 }
73 
TEST_F(ThreadTest,SetOtherThreadPriorityTest)74 TEST_F(ThreadTest, SetOtherThreadPriorityTest)
75 {
76     auto parentPid = GetCurrentThreadId();
77     auto parentPrioBefore = GetPriority(parentPid);
78 
79     auto newThread = ThreadStart(ThreadFunc);
80     // wait for the new_thread to update CUR_THREAD_ID
81     g_mu.Lock();
82     while (!g_updated) {
83         g_cv.Wait(&g_mu);
84     }
85     auto childPid = g_curThreadId;
86 
87     auto childPrioBefore = GetPriority(childPid);
88     (void)childPrioBefore;
89     auto ret = SetPriority(childPid, LOWEST_PRIORITY);
90 
91     auto childPrioAfter = GetPriority(childPid);
92     (void)childPrioAfter;
93     auto parentPrioAfter = GetPriority(parentPid);
94 
95     g_operated = true;
96     g_mu.Unlock();
97     g_cv.Signal();
98     void *res;
99     ThreadJoin(newThread, &res);
100 
101     ASSERT_EQ(parentPrioBefore, parentPrioAfter);
102 #ifdef PANDA_TARGET_UNIX
103     ASSERT_EQ(ret, 0U);
104     ASSERT(childPrioBefore <= childPrioAfter);
105 #elif defined(PANDA_TARGET_WINDOWS)
106     ASSERT_NE(ret, 0U);
107     ASSERT(childPrioAfter <= childPrioBefore);
108 #endif
109 }
110 }  // namespace ark::os::thread
111