1484543d1Sopenharmony_ci/* 2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License. 5484543d1Sopenharmony_ci * You may obtain a copy of the License at 6484543d1Sopenharmony_ci * 7484543d1Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8484543d1Sopenharmony_ci * 9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and 13484543d1Sopenharmony_ci * limitations under the License. 14484543d1Sopenharmony_ci */ 15484543d1Sopenharmony_ci 16484543d1Sopenharmony_ci#include <vector> 17484543d1Sopenharmony_ci#include <mutex> 18484543d1Sopenharmony_ci#include <thread> 19484543d1Sopenharmony_ci#include <condition_variable> 20484543d1Sopenharmony_ci#include <atomic> 21484543d1Sopenharmony_ci 22484543d1Sopenharmony_ci#include <gtest/gtest.h> 23484543d1Sopenharmony_ci 24484543d1Sopenharmony_ci#include "eu/rtg_ioctl.h" 25484543d1Sopenharmony_ci#include "dfx/log/ffrt_log_api.h" 26484543d1Sopenharmony_ci#include "../common.h" 27484543d1Sopenharmony_ci 28484543d1Sopenharmony_ciusing namespace testing; 29484543d1Sopenharmony_ci#ifdef HWTEST_TESTING_EXT_ENABLE 30484543d1Sopenharmony_ciusing namespace testing::ext; 31484543d1Sopenharmony_ci#endif 32484543d1Sopenharmony_ciusing namespace ffrt; 33484543d1Sopenharmony_ci 34484543d1Sopenharmony_ciclass RTGTest : public testing::Test { 35484543d1Sopenharmony_ciprotected: 36484543d1Sopenharmony_ci static void SetUpTestCase() 37484543d1Sopenharmony_ci { 38484543d1Sopenharmony_ci } 39484543d1Sopenharmony_ci 40484543d1Sopenharmony_ci static void TearDownTestCase() 41484543d1Sopenharmony_ci { 42484543d1Sopenharmony_ci } 43484543d1Sopenharmony_ci 44484543d1Sopenharmony_ci virtual void SetUp() 45484543d1Sopenharmony_ci { 46484543d1Sopenharmony_ci } 47484543d1Sopenharmony_ci 48484543d1Sopenharmony_ci virtual void TearDown() 49484543d1Sopenharmony_ci { 50484543d1Sopenharmony_ci } 51484543d1Sopenharmony_ci}; 52484543d1Sopenharmony_ci 53484543d1Sopenharmony_ciHWTEST_F(RTGTest, rtg_init_test, TestSize.Level1) 54484543d1Sopenharmony_ci{ 55484543d1Sopenharmony_ci bool enabled = RTGCtrl::Instance().Enabled(); 56484543d1Sopenharmony_ci FFRT_LOGE("RTGCtrl Init %s", enabled ? "Success" : "Failed"); 57484543d1Sopenharmony_ci} 58484543d1Sopenharmony_ci 59484543d1Sopenharmony_ciHWTEST_F(RTGTest, rtg_get_group_test, TestSize.Level1) 60484543d1Sopenharmony_ci{ 61484543d1Sopenharmony_ci int tgid = RTGCtrl::Instance().GetThreadGroup(); 62484543d1Sopenharmony_ci if (tgid < 0) { 63484543d1Sopenharmony_ci FFRT_LOGE("Failed to Get RTG id %d", tgid); 64484543d1Sopenharmony_ci } 65484543d1Sopenharmony_ci 66484543d1Sopenharmony_ci bool ret = RTGCtrl::Instance().PutThreadGroup(tgid); 67484543d1Sopenharmony_ci if (!ret) { 68484543d1Sopenharmony_ci FFRT_LOGE("Failed to Put RTG id %d", tgid); 69484543d1Sopenharmony_ci } 70484543d1Sopenharmony_ci} 71484543d1Sopenharmony_ci 72484543d1Sopenharmony_ciHWTEST_F(RTGTest, rtg_set_window_size_test, TestSize.Level1) 73484543d1Sopenharmony_ci{ 74484543d1Sopenharmony_ci constexpr int WINDOW_SIZE = 10000; 75484543d1Sopenharmony_ci 76484543d1Sopenharmony_ci int tgid = RTGCtrl::Instance().GetThreadGroup(); 77484543d1Sopenharmony_ci if (tgid < 0) { 78484543d1Sopenharmony_ci FFRT_LOGE("Failed to Get RTG id %d", tgid); 79484543d1Sopenharmony_ci } 80484543d1Sopenharmony_ci 81484543d1Sopenharmony_ci bool ret = RTGCtrl::Instance().SetGroupWindowSize(tgid, WINDOW_SIZE); 82484543d1Sopenharmony_ci if (!ret) { 83484543d1Sopenharmony_ci FFRT_LOGE("Failed to Set Window Size %d", WINDOW_SIZE); 84484543d1Sopenharmony_ci } 85484543d1Sopenharmony_ci 86484543d1Sopenharmony_ci ret = RTGCtrl::Instance().PutThreadGroup(tgid); 87484543d1Sopenharmony_ci if (!ret) { 88484543d1Sopenharmony_ci FFRT_LOGE("Failed to Put RTG id %d", tgid); 89484543d1Sopenharmony_ci } 90484543d1Sopenharmony_ci} 91484543d1Sopenharmony_ci 92484543d1Sopenharmony_ciHWTEST_F(RTGTest, rtg_set_invalid_interval_test, TestSize.Level1) 93484543d1Sopenharmony_ci{ 94484543d1Sopenharmony_ci constexpr int INVALID_INTERVAL = 10; 95484543d1Sopenharmony_ci 96484543d1Sopenharmony_ci int tgid = RTGCtrl::Instance().GetThreadGroup(); 97484543d1Sopenharmony_ci if (tgid < 0) { 98484543d1Sopenharmony_ci FFRT_LOGE("Failed to Get RTG id %d", tgid); 99484543d1Sopenharmony_ci } 100484543d1Sopenharmony_ci 101484543d1Sopenharmony_ci bool ret = RTGCtrl::Instance().SetInvalidInterval(tgid, INVALID_INTERVAL); 102484543d1Sopenharmony_ci if (!ret) { 103484543d1Sopenharmony_ci FFRT_LOGE("Failed to Set Invalid Interval %d", INVALID_INTERVAL); 104484543d1Sopenharmony_ci } 105484543d1Sopenharmony_ci 106484543d1Sopenharmony_ci ret = RTGCtrl::Instance().PutThreadGroup(tgid); 107484543d1Sopenharmony_ci if (!ret) { 108484543d1Sopenharmony_ci FFRT_LOGE("Failed to Put RTG id %d", tgid); 109484543d1Sopenharmony_ci } 110484543d1Sopenharmony_ci} 111484543d1Sopenharmony_ci 112484543d1Sopenharmony_ciHWTEST_F(RTGTest, rtg_set_preferred_cluster_test, TestSize.Level1) 113484543d1Sopenharmony_ci{ 114484543d1Sopenharmony_ci constexpr int CLUSTER_ID = 0; 115484543d1Sopenharmony_ci 116484543d1Sopenharmony_ci int tgid = RTGCtrl::Instance().GetThreadGroup(); 117484543d1Sopenharmony_ci if (tgid < 0) { 118484543d1Sopenharmony_ci FFRT_LOGE("Failed to Get RTG id %d", tgid); 119484543d1Sopenharmony_ci } 120484543d1Sopenharmony_ci 121484543d1Sopenharmony_ci bool ret = RTGCtrl::Instance().SetPreferredCluster(tgid, CLUSTER_ID); 122484543d1Sopenharmony_ci if (!ret) { 123484543d1Sopenharmony_ci FFRT_LOGE("Failed to Set Preferred Cluster %d", CLUSTER_ID); 124484543d1Sopenharmony_ci } 125484543d1Sopenharmony_ci 126484543d1Sopenharmony_ci ret = RTGCtrl::Instance().PutThreadGroup(tgid); 127484543d1Sopenharmony_ci if (!ret) { 128484543d1Sopenharmony_ci FFRT_LOGE("Failed to Put RTG id %d", tgid); 129484543d1Sopenharmony_ci } 130484543d1Sopenharmony_ci} 131484543d1Sopenharmony_ci 132484543d1Sopenharmony_ciHWTEST_F(RTGTest, rtg_begin_end_test, TestSize.Level1) 133484543d1Sopenharmony_ci{ 134484543d1Sopenharmony_ci int tgid = RTGCtrl::Instance().GetThreadGroup(); 135484543d1Sopenharmony_ci if (tgid < 0) { 136484543d1Sopenharmony_ci FFRT_LOGE("Failed to Get RTG id %d", tgid); 137484543d1Sopenharmony_ci } 138484543d1Sopenharmony_ci 139484543d1Sopenharmony_ci bool ret = RTGCtrl::Instance().Begin(tgid); 140484543d1Sopenharmony_ci if (!ret) { 141484543d1Sopenharmony_ci FFRT_LOGE("Failed to Begin"); 142484543d1Sopenharmony_ci } 143484543d1Sopenharmony_ci 144484543d1Sopenharmony_ci ret = RTGCtrl::Instance().End(tgid); 145484543d1Sopenharmony_ci if (!ret) { 146484543d1Sopenharmony_ci FFRT_LOGE("Failed to End"); 147484543d1Sopenharmony_ci } 148484543d1Sopenharmony_ci 149484543d1Sopenharmony_ci ret = RTGCtrl::Instance().PutThreadGroup(tgid); 150484543d1Sopenharmony_ci if (!ret) { 151484543d1Sopenharmony_ci FFRT_LOGE("Failed to Put RTG id %d", tgid); 152484543d1Sopenharmony_ci } 153484543d1Sopenharmony_ci} 154484543d1Sopenharmony_ci 155484543d1Sopenharmony_ciHWTEST_F(RTGTest, rtg_add_tread_test, TestSize.Level1) 156484543d1Sopenharmony_ci{ 157484543d1Sopenharmony_ci constexpr int THREAD_NUM = 8; 158484543d1Sopenharmony_ci bool ret; 159484543d1Sopenharmony_ci int tgid = RTGCtrl::Instance().GetThreadGroup(); 160484543d1Sopenharmony_ci if (tgid < 0) { 161484543d1Sopenharmony_ci FFRT_LOGE("Failed to Get RTG id %d", tgid); 162484543d1Sopenharmony_ci } 163484543d1Sopenharmony_ci 164484543d1Sopenharmony_ci std::vector<std::thread> threads; 165484543d1Sopenharmony_ci 166484543d1Sopenharmony_ci std::mutex tidMutex; 167484543d1Sopenharmony_ci std::vector<pid_t> tids; 168484543d1Sopenharmony_ci 169484543d1Sopenharmony_ci std::mutex condMutex; 170484543d1Sopenharmony_ci std::condition_variable cond; 171484543d1Sopenharmony_ci 172484543d1Sopenharmony_ci auto f = [&]() { 173484543d1Sopenharmony_ci pid_t tid = RTGCtrl::GetTID(); 174484543d1Sopenharmony_ci 175484543d1Sopenharmony_ci { 176484543d1Sopenharmony_ci std::unique_lock lock(tidMutex); 177484543d1Sopenharmony_ci tids.emplace_back(tid); 178484543d1Sopenharmony_ci } 179484543d1Sopenharmony_ci 180484543d1Sopenharmony_ci std::unique_lock lock(condMutex); 181484543d1Sopenharmony_ci cond.wait(lock); 182484543d1Sopenharmony_ci }; 183484543d1Sopenharmony_ci 184484543d1Sopenharmony_ci for (int i = 0; i < THREAD_NUM; ++i) { 185484543d1Sopenharmony_ci threads.emplace_back(std::thread(f)); 186484543d1Sopenharmony_ci } 187484543d1Sopenharmony_ci 188484543d1Sopenharmony_ci while (true) { 189484543d1Sopenharmony_ci std::unique_lock lock(tidMutex); 190484543d1Sopenharmony_ci if (tids.size() >= THREAD_NUM) { 191484543d1Sopenharmony_ci break; 192484543d1Sopenharmony_ci } 193484543d1Sopenharmony_ci } 194484543d1Sopenharmony_ci 195484543d1Sopenharmony_ci for (auto tid : tids) { 196484543d1Sopenharmony_ci ret = RTGCtrl::Instance().JoinThread(tgid, tid); 197484543d1Sopenharmony_ci if (!ret) { 198484543d1Sopenharmony_ci FFRT_LOGE("Failed To Join Thread %d", tid); 199484543d1Sopenharmony_ci } 200484543d1Sopenharmony_ci } 201484543d1Sopenharmony_ci 202484543d1Sopenharmony_ci ret = RTGCtrl::Instance().UpdatePerfFreq(tgid, 960000); 203484543d1Sopenharmony_ci for (auto tid : tids) { 204484543d1Sopenharmony_ci auto [t_load, t_runtime] = RTGCtrl::Instance().UpdateAndGetLoad(tgid, tid); 205484543d1Sopenharmony_ci FFRT_LOGE("Get Load %lu runtime %lu", t_load, t_runtime); 206484543d1Sopenharmony_ci ret = RTGCtrl::Instance().RemoveThread(tgid, tid); 207484543d1Sopenharmony_ci if (!ret) { 208484543d1Sopenharmony_ci FFRT_LOGE("Failed To Leave Thread %d", tid); 209484543d1Sopenharmony_ci } 210484543d1Sopenharmony_ci } 211484543d1Sopenharmony_ci 212484543d1Sopenharmony_ci cond.notify_all(); 213484543d1Sopenharmony_ci for (auto& thread : threads) { 214484543d1Sopenharmony_ci thread.join(); 215484543d1Sopenharmony_ci } 216484543d1Sopenharmony_ci 217484543d1Sopenharmony_ci ret = RTGCtrl::Instance().PutThreadGroup(tgid); 218484543d1Sopenharmony_ci if (!ret) { 219484543d1Sopenharmony_ci FFRT_LOGE("Failed to Put RTG id %d", tgid); 220484543d1Sopenharmony_ci } 221484543d1Sopenharmony_ci} 222484543d1Sopenharmony_ci 223484543d1Sopenharmony_ciHWTEST_F(RTGTest, rtg_update_util_test, TestSize.Level1) 224484543d1Sopenharmony_ci{ 225484543d1Sopenharmony_ci constexpr int THREAD_NUM = 8; 226484543d1Sopenharmony_ci 227484543d1Sopenharmony_ci int tgid = RTGCtrl::Instance().GetThreadGroup(); 228484543d1Sopenharmony_ci if (tgid < 0) { 229484543d1Sopenharmony_ci FFRT_LOGE("Failed to Get RTG id %d", tgid); 230484543d1Sopenharmony_ci } 231484543d1Sopenharmony_ci 232484543d1Sopenharmony_ci std::vector<std::thread> threads; 233484543d1Sopenharmony_ci 234484543d1Sopenharmony_ci std::mutex tidMutex; 235484543d1Sopenharmony_ci std::vector<pid_t> tids; 236484543d1Sopenharmony_ci 237484543d1Sopenharmony_ci std::mutex condMutex; 238484543d1Sopenharmony_ci std::condition_variable cond; 239484543d1Sopenharmony_ci 240484543d1Sopenharmony_ci auto f = [&]() { 241484543d1Sopenharmony_ci pid_t tid = RTGCtrl::GetTID(); 242484543d1Sopenharmony_ci 243484543d1Sopenharmony_ci { 244484543d1Sopenharmony_ci std::unique_lock lock(tidMutex); 245484543d1Sopenharmony_ci tids.emplace_back(tid); 246484543d1Sopenharmony_ci } 247484543d1Sopenharmony_ci 248484543d1Sopenharmony_ci std::unique_lock lock(condMutex); 249484543d1Sopenharmony_ci cond.wait(lock); 250484543d1Sopenharmony_ci }; 251484543d1Sopenharmony_ci 252484543d1Sopenharmony_ci for (int i = 0; i < THREAD_NUM; ++i) { 253484543d1Sopenharmony_ci threads.emplace_back(std::thread(f)); 254484543d1Sopenharmony_ci } 255484543d1Sopenharmony_ci 256484543d1Sopenharmony_ci while (true) { 257484543d1Sopenharmony_ci std::unique_lock lock(tidMutex); 258484543d1Sopenharmony_ci if (tids.size() >= THREAD_NUM) { 259484543d1Sopenharmony_ci break; 260484543d1Sopenharmony_ci } 261484543d1Sopenharmony_ci } 262484543d1Sopenharmony_ci 263484543d1Sopenharmony_ci for (auto tid : tids) { 264484543d1Sopenharmony_ci bool ret = RTGCtrl::Instance().JoinThread(tgid, tid); 265484543d1Sopenharmony_ci if (!ret) { 266484543d1Sopenharmony_ci FFRT_LOGE("Failed To Join Thread %d", tid); 267484543d1Sopenharmony_ci } 268484543d1Sopenharmony_ci } 269484543d1Sopenharmony_ci 270484543d1Sopenharmony_ci bool ret = RTGCtrl::Instance().Begin(tgid); 271484543d1Sopenharmony_ci if (!ret) { 272484543d1Sopenharmony_ci FFRT_LOGE("Failed to Begin"); 273484543d1Sopenharmony_ci } 274484543d1Sopenharmony_ci 275484543d1Sopenharmony_ci for (int util = 8; util <= 1024; util <<= 1) { 276484543d1Sopenharmony_ci auto [load, runtime] = RTGCtrl::Instance().UpdateAndGetLoad(tgid); 277484543d1Sopenharmony_ci FFRT_LOGE("Get Load %lu runtime %lu", load, runtime); 278484543d1Sopenharmony_ci 279484543d1Sopenharmony_ci ret = RTGCtrl::Instance().UpdatePerfUtil(tgid, util); 280484543d1Sopenharmony_ci if (!ret) { 281484543d1Sopenharmony_ci FFRT_LOGE("Failed To Update Util %d", util); 282484543d1Sopenharmony_ci } 283484543d1Sopenharmony_ci } 284484543d1Sopenharmony_ci 285484543d1Sopenharmony_ci for (auto tid : tids) { 286484543d1Sopenharmony_ci ret = RTGCtrl::Instance().RemoveThread(tgid, tid); 287484543d1Sopenharmony_ci if (!ret) { 288484543d1Sopenharmony_ci FFRT_LOGE("Failed To Leave Thread %d", tid); 289484543d1Sopenharmony_ci } 290484543d1Sopenharmony_ci } 291484543d1Sopenharmony_ci 292484543d1Sopenharmony_ci ret = RTGCtrl::Instance().End(tgid); 293484543d1Sopenharmony_ci if (!ret) { 294484543d1Sopenharmony_ci FFRT_LOGE("Failed to End"); 295484543d1Sopenharmony_ci } 296484543d1Sopenharmony_ci 297484543d1Sopenharmony_ci cond.notify_all(); 298484543d1Sopenharmony_ci for (auto& thread : threads) { 299484543d1Sopenharmony_ci thread.join(); 300484543d1Sopenharmony_ci } 301484543d1Sopenharmony_ci 302484543d1Sopenharmony_ci ret = RTGCtrl::Instance().PutThreadGroup(tgid); 303484543d1Sopenharmony_ci if (!ret) { 304484543d1Sopenharmony_ci FFRT_LOGE("Failed to Put RTG id %d", tgid); 305484543d1Sopenharmony_ci } 306484543d1Sopenharmony_ci} 307