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 <gtest/gtest.h> 17#include <cinttypes> 18#include "ffrt_inner.h" 19#include "util.h" 20#include "c/deadline.h" 21#include "c/executor_task.h" 22#include "tm/scpu_task.h" 23#include "dfx/log/ffrt_log_api.h" 24#ifndef WITH_NO_MOCKER 25extern "C" int ffrt_set_cgroup_attr(ffrt_qos_t qos, ffrt_os_sched_attr *attr); 26#endif 27#include "../common.h" 28 29using namespace std; 30using namespace testing; 31#ifdef HWTEST_TESTING_EXT_ENABLE 32using namespace testing::ext; 33#endif 34 35class DependencyTest : public testing::Test { 36protected: 37 static void SetUpTestCase() 38 { 39 } 40 41 static void TearDownTestCase() 42 { 43 } 44 45 virtual void SetUp() 46 { 47 } 48 49 virtual void TearDown() 50 { 51 } 52}; 53 54HWTEST_F(DependencyTest, dependency_success_01, TestSize.Level1) 55{ 56 int x = 0; 57 ffrt::submit([&]() { x = 2; }, {}, {&x}); 58 ffrt::submit([&]() { x = x * 3; }, {&x}, {}); 59 ffrt::wait(); 60 EXPECT_EQ(x, 6); 61} 62 63HWTEST_F(DependencyTest, update_qos_success_02, TestSize.Level1) 64{ 65 int ret = ffrt_task_attr_init(nullptr); 66 EXPECT_EQ(ret, -1); 67 ffrt_task_attr_get_name(nullptr); 68 ffrt_task_attr_set_name(nullptr, "A"); 69 ffrt_task_attr_set_qos(nullptr, static_cast<int>(ffrt::qos_user_initiated)); 70 ffrt_task_attr_get_qos(nullptr); 71 ffrt_task_attr_destroy(nullptr); 72 ffrt_submit_base(nullptr, nullptr, nullptr, nullptr); 73 ffrt_submit_h_base(nullptr, nullptr, nullptr, nullptr); 74 ffrt::submit([] { 75 printf("return %d\n", ffrt::this_task::update_qos(static_cast<int>(ffrt::qos_user_initiated))); 76 printf("id is %" PRIu64 "\n", ffrt::this_task::get_id()); 77 }); 78 ffrt_this_task_get_id(); 79 ffrt::wait(); 80 ffrt_this_task_update_qos(static_cast<int>(ffrt::qos_user_initiated)); 81#ifndef WITH_NO_MOCKER 82 ffrt_set_cgroup_attr(static_cast<int>(ffrt::qos_user_initiated), nullptr); 83#endif 84} 85 86HWTEST_F(DependencyTest, update_qos_success_03, TestSize.Level1) 87{ 88 int ret = ffrt_task_attr_init(nullptr); 89 EXPECT_EQ(ret, -1); 90 ffrt::submit([] { 91 printf("return %d\n", ffrt::this_task::update_qos(static_cast<int>(ffrt::qos_user_initiated))); 92 }); 93 ffrt_restore_qos_config(); 94} 95 96HWTEST_F(DependencyTest, update_qos_success_04, TestSize.Level1) 97{ 98 int ret = ffrt_task_attr_init(nullptr); 99 EXPECT_EQ(ret, -1); 100 ffrt::submit([] { 101 printf("return %d\n", ffrt::this_task::update_qos(static_cast<int>(ffrt::qos_user_initiated))); 102 }); 103} 104 105HWTEST_F(DependencyTest, update_qos_success_05, TestSize.Level1) 106{ 107 int x = 0; 108 int ret = ffrt_task_attr_init(nullptr); 109 EXPECT_EQ(ret, -1); 110 ffrt_task_attr_get_name(nullptr); 111 ffrt_task_attr_set_name(nullptr, "A"); 112 ffrt_task_attr_set_qos(nullptr, static_cast<int>(ffrt::qos_user_initiated)); 113 ffrt_task_attr_get_qos(nullptr); 114 ffrt_task_attr_destroy(nullptr); 115 ffrt_submit_base(nullptr, nullptr, nullptr, nullptr); 116 ffrt_submit_h_base(nullptr, nullptr, nullptr, nullptr); 117 ffrt::submit([&] { 118 x++; 119 printf("return %d\n", ffrt::this_task::update_qos(static_cast<int>(ffrt::qos_user_initiated))); 120 printf("id is %" PRIu64 "\n", ffrt::this_task::get_id()); 121 }); 122 ffrt_this_task_get_id(); 123 ffrt::wait(); 124 ffrt_this_task_update_qos(static_cast<int>(ffrt::qos_user_initiated)); 125#ifndef WITH_NO_MOCKER 126 ffrt_os_sched_attr attr = {100, 10, 99, 99, 9, "2-3"}; 127 ffrt_set_cgroup_attr(static_cast<int>(ffrt::qos_user_initiated), &attr); 128#endif 129 EXPECT_EQ(x, 1); 130} 131 132HWTEST_F(DependencyTest, update_qos_failed_01, TestSize.Level1) 133{ 134 int x = 0; 135 int ret = ffrt_task_attr_init(nullptr); 136 EXPECT_EQ(ret, -1); 137 ffrt_task_attr_get_name(nullptr); 138 ffrt_task_attr_set_name(nullptr, "A"); 139 ffrt_task_attr_set_qos(nullptr, static_cast<int>(ffrt::qos_user_initiated)); 140 ffrt_task_attr_get_qos(nullptr); 141 ffrt_task_attr_destroy(nullptr); 142 ffrt_submit_base(nullptr, nullptr, nullptr, nullptr); 143 ffrt_submit_h_base(nullptr, nullptr, nullptr, nullptr); 144 ffrt::submit([&] { 145 printf("return %d\n", ffrt::this_task::update_qos(static_cast<int>(ffrt::qos_user_initiated))); 146 printf("id is %" PRIu64 "\n", ffrt::this_task::get_id()); 147 int ret1 = ffrt_this_task_update_qos(static_cast<int>(ffrt::qos_default)); 148 EXPECT_EQ(ret1, 0); 149 x++; 150 }); 151 ffrt_this_task_get_id(); 152 ffrt::wait(); 153#ifndef WITH_NO_MOCKER 154 ffrt_set_cgroup_attr(static_cast<int>(ffrt::qos_user_initiated), nullptr); 155#endif 156 EXPECT_EQ(x, 1); 157} 158 159HWTEST_F(DependencyTest, update_qos_failed_02, TestSize.Level1) 160{ 161 int ret = ffrt_task_attr_init(nullptr); 162 EXPECT_EQ(ret, -1); 163 ffrt::submit([] { 164 printf("return %d\n", ffrt::this_task::update_qos(static_cast<int>(ffrt::qos_user_initiated))); 165 }); 166} 167 168HWTEST_F(DependencyTest, executor_task_submit_success_01, TestSize.Level1) 169{ 170 ffrt_task_attr_t attr; 171 static ffrt_executor_task_t work; 172 work.wq[0] = &work.wq; 173 work.wq[1] = &work.wq; 174 work.type = reinterpret_cast<uintptr_t>(&attr); 175 176 ffrt_executor_task_submit(&work, &attr); 177} 178HWTEST_F(DependencyTest, executor_task_submit_nullptr_01, TestSize.Level1) 179{ 180 ffrt_executor_task_submit(nullptr, nullptr); 181} 182 183HWTEST_F(DependencyTest, executor_task_submit_cancel_01, TestSize.Level1) 184{ 185 ffrt_executor_task_cancel(nullptr, static_cast<int>(ffrt::qos_user_initiated)); 186} 187 188HWTEST_F(DependencyTest, executor_task_submit_cancel_02, TestSize.Level1) 189{ 190 ffrt_task_attr_t attr; 191 ffrt_task_attr_init(&attr); 192 ffrt_executor_task_t work; 193 work.type = reinterpret_cast<uintptr_t>(&attr); 194 195 ffrt_task_attr_set_qos(&attr, static_cast<int>(ffrt::qos_user_initiated)); 196 ffrt_executor_task_submit(&work, &attr); 197 usleep(10000); 198 int cancelled = ffrt_executor_task_cancel(&work, static_cast<int>(ffrt::qos_user_initiated)); 199 EXPECT_EQ(cancelled, 0); 200 201 ffrt_task_attr_destroy(&attr); 202} 203 204HWTEST_F(DependencyTest, update_trace_tag_success_02, TestSize.Level1) 205{ 206 ffrt::set_trace_tag("TASK A"); 207 ffrt::clear_trace_tag(); 208} 209 210HWTEST_F(DependencyTest, task_attr_success_02, TestSize.Level1) 211{ 212 ffrt::task_attr tmpTask; 213 tmpTask.name("Task A"); 214 tmpTask.qos(static_cast<int>(ffrt::qos_user_initiated)); 215 tmpTask.name(); 216 tmpTask.qos(); 217} 218 219HWTEST_F(DependencyTest, sample_pingpong_pipe_interval_checkpoint, TestSize.Level1) 220{ 221 int loops = 5; 222 int frame_num = 2; 223 224 if (getenv("LOOP_NUM")) { 225 loops = atoi(getenv("LOOP_NUM")); 226 } 227 if (getenv("FRAME_NUM")) { 228 frame_num = atoi(getenv("FRAME_NUM")); 229 } 230 231 ffrt::submit([&]() { stall_us(10); }, {}, {}); 232 233 auto it = ffrt::qos_interval_create(16, static_cast<int>(ffrt::qos_user_interactive)); 234 for (int loop = 0; loop < loops; loop++) { 235 constexpr int FRAME_NUM = 3; 236 constexpr uint32_t BUFFER_NUM = 2; 237 int x0[FRAME_NUM]; 238 int x1[BUFFER_NUM]; 239 int x2[BUFFER_NUM]; 240 int x3[FRAME_NUM]; 241 242 int stalls[10][4] = { 243 {2000, 6000, 8000, 8000 + 6000 + 2000}, // 0 244 {2125, 6375, 8500, 8500 + 6375 + 2125}, // 1 245 {2222, 6666, 8888, 8888 + 6666 + 2222}, // 2 246 {2250, 6750, 9000, 9000 + 6750 + 2250}, // 3 247 {2375, 7125, 9500, 9500 + 7125 + 2375}, // 4 248 {2500, 7500, 10000, 10000 + 7500 + 2500}, // 5 249 {1875, 5625, 7500, 7500 + 5625 + 1875}, // 6 250 {1750, 5250, 7000, 7000 + 5250 + 1750}, // 7 251 {1625, 4875, 6500, 6500 + 4875 + 1625}, // 8 252 {1500, 4500, 6000, 6000 + 4500 + 1500}, // 9 253 }; 254 255 auto start = std::chrono::system_clock::now(); 256 ffrt::qos_interval_begin(it); 257 for (int i = 0; i < frame_num; i++) { 258 int pingpong = i % BUFFER_NUM; 259 // task A 260 ffrt::submit( 261 [i, loop, stalls]() { 262 FFRT_LOGI("%u", i); 263 }, 264 {x0 + i}, {x1 + pingpong}, ffrt::task_attr().name(("UI" + std::to_string(i)).c_str())); 265 // task B 266 ffrt::submit( 267 [i, loop, stalls]() { 268 FFRT_LOGI("%u", i); 269 }, 270 {x1 + pingpong}, {x2 + pingpong}, ffrt::task_attr().name(("Render" + std::to_string(i)).c_str())); 271 // task C 272 ffrt::submit( 273 [i, loop, stalls]() { 274 FFRT_LOGI("%u", i); 275 }, 276 {x2 + pingpong}, {x3 + i}, ffrt::task_attr().name(("surfaceflinger" + std::to_string(i)).c_str())); 277 } 278 ffrt::wait(); 279 ffrt::qos_interval_end(it); 280 } 281 282 ffrt::qos_interval_destroy(it); 283} 284