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