• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <vector>
17 #include <mutex>
18 #include <thread>
19 #include <condition_variable>
20 #include <atomic>
21 
22 #include <gtest/gtest.h>
23 
24 #include "eu/rtg_ioctl.h"
25 #include "dfx/log/ffrt_log_api.h"
26 #include "../common.h"
27 
28 using namespace testing;
29 #ifdef HWTEST_TESTING_EXT_ENABLE
30 using namespace testing::ext;
31 #endif
32 using namespace ffrt;
33 
34 class RTGTest : public testing::Test {
35 protected:
SetUpTestCase()36     static void SetUpTestCase()
37     {
38     }
39 
TearDownTestCase()40     static void TearDownTestCase()
41     {
42     }
43 
SetUp()44     void SetUp() override
45     {
46     }
47 
TearDown()48     void TearDown() override
49     {
50     }
51 };
52 
53 HWTEST_F(RTGTest, rtg_init_test, TestSize.Level1)
54 {
55     bool enabled = RTGCtrl::Instance().Enabled();
56     FFRT_LOGE("RTGCtrl Init %s", enabled ? "Success" : "Failed");
57     EXPECT_EQ(enabled, false);
58 }
59 
60 HWTEST_F(RTGTest, rtg_get_group_test, TestSize.Level1)
61 {
62     int tgid = RTGCtrl::Instance().GetThreadGroup();
63     if (tgid < 0) {
64         FFRT_LOGE("Failed to Get RTG id %d", tgid);
65     }
66     EXPECT_LE(tgid, 0);
67 
68     bool ret = RTGCtrl::Instance().PutThreadGroup(tgid);
69     if (!ret) {
70         FFRT_LOGE("Failed to Put RTG id %d", tgid);
71     }
72     EXPECT_EQ(ret, false);
73 }
74 
75 HWTEST_F(RTGTest, rtg_set_window_size_test, TestSize.Level1)
76 {
77     constexpr int WINDOW_SIZE = 10000;
78 
79     int tgid = RTGCtrl::Instance().GetThreadGroup();
80     if (tgid < 0) {
81         FFRT_LOGE("Failed to Get RTG id %d", tgid);
82     }
83     EXPECT_LE(tgid, 0);
84 
85     bool ret = RTGCtrl::Instance().SetGroupWindowSize(tgid, WINDOW_SIZE);
86     if (!ret) {
87         FFRT_LOGE("Failed to Set Window Size %d", WINDOW_SIZE);
88     }
89     EXPECT_EQ(ret, false);
90 
91     ret = RTGCtrl::Instance().PutThreadGroup(tgid);
92     if (!ret) {
93         FFRT_LOGE("Failed to Put RTG id %d", tgid);
94     }
95     EXPECT_EQ(ret, false);
96 }
97 
98 HWTEST_F(RTGTest, rtg_set_invalid_interval_test, TestSize.Level1)
99 {
100     constexpr int INVALID_INTERVAL = 10;
101 
102     int tgid = RTGCtrl::Instance().GetThreadGroup();
103     if (tgid < 0) {
104         FFRT_LOGE("Failed to Get RTG id %d", tgid);
105     }
106     EXPECT_LE(tgid, 0);
107 
108     bool ret = RTGCtrl::Instance().SetInvalidInterval(tgid, INVALID_INTERVAL);
109     if (!ret) {
110         FFRT_LOGE("Failed to Set Invalid Interval %d", INVALID_INTERVAL);
111     }
112     EXPECT_EQ(ret, false);
113 
114     ret = RTGCtrl::Instance().PutThreadGroup(tgid);
115     if (!ret) {
116         FFRT_LOGE("Failed to Put RTG id %d", tgid);
117     }
118     EXPECT_EQ(ret, false);
119 }
120 
121 HWTEST_F(RTGTest, rtg_set_preferred_cluster_test, TestSize.Level1)
122 {
123     constexpr int CLUSTER_ID = 0;
124 
125     int tgid = RTGCtrl::Instance().GetThreadGroup();
126     if (tgid < 0) {
127         FFRT_LOGE("Failed to Get RTG id %d", tgid);
128     }
129     EXPECT_LE(tgid, 0);
130 
131     bool ret = RTGCtrl::Instance().SetPreferredCluster(tgid, CLUSTER_ID);
132     if (!ret) {
133         FFRT_LOGE("Failed to Set Preferred Cluster %d", CLUSTER_ID);
134     }
135     EXPECT_EQ(ret, false);
136 
137     ret = RTGCtrl::Instance().PutThreadGroup(tgid);
138     if (!ret) {
139         FFRT_LOGE("Failed to Put RTG id %d", tgid);
140     }
141     EXPECT_EQ(ret, false);
142 }
143 
144 HWTEST_F(RTGTest, rtg_begin_end_test, TestSize.Level1)
145 {
146     int tgid = RTGCtrl::Instance().GetThreadGroup();
147     if (tgid < 0) {
148         FFRT_LOGE("Failed to Get RTG id %d", tgid);
149     }
150     EXPECT_LE(tgid, 0);
151 
152     bool ret = RTGCtrl::Instance().Begin(tgid);
153     if (!ret) {
154         FFRT_LOGE("Failed to Begin");
155     }
156     EXPECT_EQ(ret, false);
157 
158     ret = RTGCtrl::Instance().End(tgid);
159     if (!ret) {
160         FFRT_LOGE("Failed to End");
161     }
162     EXPECT_EQ(ret, false);
163 
164     ret = RTGCtrl::Instance().PutThreadGroup(tgid);
165     if (!ret) {
166         FFRT_LOGE("Failed to Put RTG id %d", tgid);
167     }
168     EXPECT_EQ(ret, false);
169 }
170 
171 HWTEST_F(RTGTest, rtg_add_tread_test, TestSize.Level1)
172 {
173     constexpr int THREAD_NUM = 8;
174     bool ret;
175     int tgid = RTGCtrl::Instance().GetThreadGroup();
176     if (tgid < 0) {
177         FFRT_LOGE("Failed to Get RTG id %d", tgid);
178     }
179 
180     std::vector<std::thread> threads;
181 
182     std::mutex tidMutex;
183     std::vector<pid_t> tids;
184 
185     std::mutex condMutex;
186     std::condition_variable cond;
187 
__anon9aa99a8c0102() 188     auto f = [&]() {
189         pid_t tid = RTGCtrl::GetTID();
190 
191         {
192             std::unique_lock lock(tidMutex);
193             tids.emplace_back(tid);
194         }
195 
196         std::unique_lock lock(condMutex);
197         cond.wait(lock);
198     };
199 
200     for (int i = 0; i < THREAD_NUM; ++i) {
201         threads.emplace_back(std::thread(f));
202     }
203 
204     while (true) {
205         std::unique_lock lock(tidMutex);
206         if (tids.size() >= THREAD_NUM) {
207             break;
208         }
209     }
210 
211     for (auto tid : tids) {
212         ret = RTGCtrl::Instance().JoinThread(tgid, tid);
213         if (!ret) {
214             FFRT_LOGE("Failed To Join Thread %d", tid);
215         }
216     }
217 
218     ret = RTGCtrl::Instance().UpdatePerfFreq(tgid, 960000);
219     for (auto tid : tids) {
220         auto [t_load, t_runtime] = RTGCtrl::Instance().UpdateAndGetLoad(tgid, tid);
221         FFRT_LOGE("Get Load %lu runtime %lu", t_load, t_runtime);
222         ret = RTGCtrl::Instance().RemoveThread(tgid, tid);
223         if (!ret) {
224             FFRT_LOGE("Failed To Leave Thread %d", tid);
225         }
226     }
227 
228     cond.notify_all();
229     for (auto& thread : threads) {
230         thread.join();
231     }
232 
233     ret = RTGCtrl::Instance().PutThreadGroup(tgid);
234     if (!ret) {
235         FFRT_LOGE("Failed to Put RTG id %d", tgid);
236     }
237 }
238 
239 HWTEST_F(RTGTest, rtg_update_util_test, TestSize.Level1)
240 {
241     constexpr int THREAD_NUM = 8;
242 
243     int tgid = RTGCtrl::Instance().GetThreadGroup();
244     if (tgid < 0) {
245         FFRT_LOGE("Failed to Get RTG id %d", tgid);
246     }
247 
248     std::vector<std::thread> threads;
249 
250     std::mutex tidMutex;
251     std::vector<pid_t> tids;
252 
253     std::mutex condMutex;
254     std::condition_variable cond;
255 
__anon9aa99a8c0202() 256     auto f = [&]() {
257         pid_t tid = RTGCtrl::GetTID();
258 
259         {
260             std::unique_lock lock(tidMutex);
261             tids.emplace_back(tid);
262         }
263 
264         std::unique_lock lock(condMutex);
265         cond.wait(lock);
266     };
267 
268     for (int i = 0; i < THREAD_NUM; ++i) {
269         threads.emplace_back(std::thread(f));
270     }
271 
272     while (true) {
273         std::unique_lock lock(tidMutex);
274         if (tids.size() >= THREAD_NUM) {
275             break;
276         }
277     }
278 
279     for (auto tid : tids) {
280         bool ret = RTGCtrl::Instance().JoinThread(tgid, tid);
281         if (!ret) {
282             FFRT_LOGE("Failed To Join Thread %d", tid);
283         }
284     }
285 
286     bool ret = RTGCtrl::Instance().Begin(tgid);
287     if (!ret) {
288         FFRT_LOGE("Failed to Begin");
289     }
290 
291     for (int util = 8; util <= 1024; util <<= 1) {
292         auto [load, runtime] = RTGCtrl::Instance().UpdateAndGetLoad(tgid);
293         FFRT_LOGE("Get Load %lu runtime %lu", load, runtime);
294 
295         ret = RTGCtrl::Instance().UpdatePerfUtil(tgid, util);
296         if (!ret) {
297             FFRT_LOGE("Failed To Update Util %d", util);
298         }
299     }
300 
301     for (auto tid : tids) {
302         ret = RTGCtrl::Instance().RemoveThread(tgid, tid);
303         if (!ret) {
304             FFRT_LOGE("Failed To Leave Thread %d", tid);
305         }
306     }
307 
308     ret = RTGCtrl::Instance().End(tgid);
309     if (!ret) {
310         FFRT_LOGE("Failed to End");
311     }
312 
313     cond.notify_all();
314     for (auto& thread : threads) {
315         thread.join();
316     }
317 
318     ret = RTGCtrl::Instance().PutThreadGroup(tgid);
319     if (!ret) {
320         FFRT_LOGE("Failed to Put RTG id %d", tgid);
321     }
322 }
323