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 <gtest/gtest.h> 17484543d1Sopenharmony_ci#include <chrono> 18484543d1Sopenharmony_ci#include "c/thread.h" 19484543d1Sopenharmony_ci#include "ffrt_inner.h" 20484543d1Sopenharmony_ci#include "../common.h" 21484543d1Sopenharmony_ci 22484543d1Sopenharmony_ciusing namespace ffrt; 23484543d1Sopenharmony_ciusing namespace std; 24484543d1Sopenharmony_ciusing namespace testing; 25484543d1Sopenharmony_ci#ifdef HWTEST_TESTING_EXT_ENABLE 26484543d1Sopenharmony_ciusing namespace testing::ext; 27484543d1Sopenharmony_ci#endif 28484543d1Sopenharmony_ci 29484543d1Sopenharmony_ciclass CVTest : public testing::Test { 30484543d1Sopenharmony_ciprotected: 31484543d1Sopenharmony_ci static void SetUpTestCase() 32484543d1Sopenharmony_ci { 33484543d1Sopenharmony_ci } 34484543d1Sopenharmony_ci 35484543d1Sopenharmony_ci static void TearDownTestCase() 36484543d1Sopenharmony_ci { 37484543d1Sopenharmony_ci } 38484543d1Sopenharmony_ci 39484543d1Sopenharmony_ci virtual void SetUp() 40484543d1Sopenharmony_ci { 41484543d1Sopenharmony_ci } 42484543d1Sopenharmony_ci 43484543d1Sopenharmony_ci virtual void TearDown() 44484543d1Sopenharmony_ci { 45484543d1Sopenharmony_ci } 46484543d1Sopenharmony_ci}; 47484543d1Sopenharmony_ci 48484543d1Sopenharmony_ciHWTEST_F(CVTest, conditonV_notify_one_test, TestSize.Level1) 49484543d1Sopenharmony_ci{ 50484543d1Sopenharmony_ci ffrt::condition_variable cond; 51484543d1Sopenharmony_ci int a = 0; 52484543d1Sopenharmony_ci ffrt::mutex lock_; 53484543d1Sopenharmony_ci 54484543d1Sopenharmony_ci ffrt::submit( 55484543d1Sopenharmony_ci [&]() { 56484543d1Sopenharmony_ci std::unique_lock lck(lock_); 57484543d1Sopenharmony_ci cond.wait(lck, [&] { return a == 1; }); 58484543d1Sopenharmony_ci }, 59484543d1Sopenharmony_ci {}, {}); 60484543d1Sopenharmony_ci 61484543d1Sopenharmony_ci ffrt::submit( 62484543d1Sopenharmony_ci [&]() { 63484543d1Sopenharmony_ci std::unique_lock lck(lock_); 64484543d1Sopenharmony_ci a = 1; 65484543d1Sopenharmony_ci cond.notify_one(); 66484543d1Sopenharmony_ci }, 67484543d1Sopenharmony_ci {}, {}); 68484543d1Sopenharmony_ci ffrt::wait(); 69484543d1Sopenharmony_ci} 70484543d1Sopenharmony_ci 71484543d1Sopenharmony_ciHWTEST_F(CVTest, conditonV_notify_all_test, TestSize.Level1) 72484543d1Sopenharmony_ci{ 73484543d1Sopenharmony_ci ffrt::condition_variable cond; 74484543d1Sopenharmony_ci int a = 0; 75484543d1Sopenharmony_ci ffrt::mutex lock_; 76484543d1Sopenharmony_ci 77484543d1Sopenharmony_ci ffrt::submit( 78484543d1Sopenharmony_ci [&]() { 79484543d1Sopenharmony_ci std::unique_lock lck(lock_); 80484543d1Sopenharmony_ci cond.wait(lck, [&] { return a == 1; }); 81484543d1Sopenharmony_ci }, 82484543d1Sopenharmony_ci {}, {}); 83484543d1Sopenharmony_ci ffrt::submit( 84484543d1Sopenharmony_ci [&]() { 85484543d1Sopenharmony_ci std::unique_lock lck(lock_); 86484543d1Sopenharmony_ci cond.wait(lck, [&] { return a == 1; }); 87484543d1Sopenharmony_ci }, 88484543d1Sopenharmony_ci {}, {}); 89484543d1Sopenharmony_ci 90484543d1Sopenharmony_ci ffrt::submit( 91484543d1Sopenharmony_ci [&]() { 92484543d1Sopenharmony_ci std::unique_lock lck(lock_); 93484543d1Sopenharmony_ci a = 1; 94484543d1Sopenharmony_ci cond.notify_all(); 95484543d1Sopenharmony_ci }, 96484543d1Sopenharmony_ci {}, {}); 97484543d1Sopenharmony_ci 98484543d1Sopenharmony_ci ffrt::wait(); 99484543d1Sopenharmony_ci} 100484543d1Sopenharmony_ci 101484543d1Sopenharmony_ciHWTEST_F(CVTest, conditonV_wait_for_test, TestSize.Level1) 102484543d1Sopenharmony_ci{ 103484543d1Sopenharmony_ci ffrt::condition_variable cond; 104484543d1Sopenharmony_ci std::atomic_int a = 0; 105484543d1Sopenharmony_ci ffrt::mutex lock_; 106484543d1Sopenharmony_ci 107484543d1Sopenharmony_ci ffrt::submit( 108484543d1Sopenharmony_ci [&]() { 109484543d1Sopenharmony_ci std::unique_lock lck(lock_); 110484543d1Sopenharmony_ci cond.wait_for(lck, 100ms, [&] { return a == 1; }); 111484543d1Sopenharmony_ci EXPECT_EQ(a, 2); 112484543d1Sopenharmony_ci }, 113484543d1Sopenharmony_ci {}, {}); 114484543d1Sopenharmony_ci 115484543d1Sopenharmony_ci ffrt::submit( 116484543d1Sopenharmony_ci [&]() { 117484543d1Sopenharmony_ci std::unique_lock lck(lock_); 118484543d1Sopenharmony_ci a = 2; 119484543d1Sopenharmony_ci cond.notify_one(); 120484543d1Sopenharmony_ci }, 121484543d1Sopenharmony_ci {}, {}); 122484543d1Sopenharmony_ci 123484543d1Sopenharmony_ci ffrt::wait(); 124484543d1Sopenharmony_ci} 125484543d1Sopenharmony_ci 126484543d1Sopenharmony_ciHWTEST_F(CVTest, conditonV_wait_for_test2, TestSize.Level1) 127484543d1Sopenharmony_ci{ 128484543d1Sopenharmony_ci ffrt::condition_variable cond; 129484543d1Sopenharmony_ci ffrt::mutex lock_; 130484543d1Sopenharmony_ci ffrt::cv_status status; 131484543d1Sopenharmony_ci 132484543d1Sopenharmony_ci ffrt::submit( 133484543d1Sopenharmony_ci [&]() { 134484543d1Sopenharmony_ci std::unique_lock lck(lock_); 135484543d1Sopenharmony_ci status = cond.wait_for(lck, 100ms); 136484543d1Sopenharmony_ci EXPECT_EQ(status, ffrt::cv_status::timeout); 137484543d1Sopenharmony_ci }, 138484543d1Sopenharmony_ci {}, {}); 139484543d1Sopenharmony_ci 140484543d1Sopenharmony_ci ffrt::wait(); 141484543d1Sopenharmony_ci} 142484543d1Sopenharmony_ci 143484543d1Sopenharmony_ciHWTEST_F(CVTest, conditonV_wait_for_test3, TestSize.Level1) 144484543d1Sopenharmony_ci{ 145484543d1Sopenharmony_ci ffrt::condition_variable cond; 146484543d1Sopenharmony_ci ffrt::mutex lock_; 147484543d1Sopenharmony_ci ffrt::cv_status status; 148484543d1Sopenharmony_ci 149484543d1Sopenharmony_ci std::unique_lock lck(lock_); 150484543d1Sopenharmony_ci status = cond.wait_for(lck, 100ms); 151484543d1Sopenharmony_ci EXPECT_EQ(status, ffrt::cv_status::timeout); 152484543d1Sopenharmony_ci} 153484543d1Sopenharmony_ci 154484543d1Sopenharmony_ciHWTEST_F(CVTest, conditonV_nullptr_test, TestSize.Level1) 155484543d1Sopenharmony_ci{ 156484543d1Sopenharmony_ci int ret = 0; 157484543d1Sopenharmony_ci 158484543d1Sopenharmony_ci ret = ffrt_cond_init(nullptr, nullptr); 159484543d1Sopenharmony_ci EXPECT_NE(ret, 0); 160484543d1Sopenharmony_ci ret = ffrt_cond_signal(nullptr); 161484543d1Sopenharmony_ci EXPECT_NE(ret, 0); 162484543d1Sopenharmony_ci ret = ffrt_cond_broadcast(nullptr); 163484543d1Sopenharmony_ci EXPECT_NE(ret, 0); 164484543d1Sopenharmony_ci ret = ffrt_cond_wait(nullptr, nullptr); 165484543d1Sopenharmony_ci EXPECT_NE(ret, 0); 166484543d1Sopenharmony_ci ret = ffrt_cond_timedwait(nullptr, nullptr, nullptr); 167484543d1Sopenharmony_ci EXPECT_NE(ret, 0); 168484543d1Sopenharmony_ci ffrt_cond_destroy(nullptr); 169484543d1Sopenharmony_ci} 170484543d1Sopenharmony_ci 171484543d1Sopenharmony_ciclass MutexTest : public testing::Test { 172484543d1Sopenharmony_ciprotected: 173484543d1Sopenharmony_ci static void SetUpTestCase() 174484543d1Sopenharmony_ci { 175484543d1Sopenharmony_ci } 176484543d1Sopenharmony_ci 177484543d1Sopenharmony_ci static void TearDownTestCase() 178484543d1Sopenharmony_ci { 179484543d1Sopenharmony_ci } 180484543d1Sopenharmony_ci 181484543d1Sopenharmony_ci virtual void SetUp() 182484543d1Sopenharmony_ci { 183484543d1Sopenharmony_ci } 184484543d1Sopenharmony_ci 185484543d1Sopenharmony_ci virtual void TearDown() 186484543d1Sopenharmony_ci { 187484543d1Sopenharmony_ci } 188484543d1Sopenharmony_ci}; 189484543d1Sopenharmony_ci 190484543d1Sopenharmony_ciHWTEST_F(MutexTest, try_lock_test, TestSize.Level1) 191484543d1Sopenharmony_ci{ 192484543d1Sopenharmony_ci int val = -1; 193484543d1Sopenharmony_ci ffrt::mutex lock; 194484543d1Sopenharmony_ci lock.lock(); 195484543d1Sopenharmony_ci val = lock.try_lock(); 196484543d1Sopenharmony_ci EXPECT_EQ(val, 0); 197484543d1Sopenharmony_ci lock.unlock(); 198484543d1Sopenharmony_ci val = lock.try_lock(); 199484543d1Sopenharmony_ci EXPECT_EQ(val, 1); 200484543d1Sopenharmony_ci lock.unlock(); 201484543d1Sopenharmony_ci lock.unlock(); 202484543d1Sopenharmony_ci} 203484543d1Sopenharmony_ci 204484543d1Sopenharmony_ciHWTEST_F(MutexTest, lock_stress_test, TestSize.Level1) 205484543d1Sopenharmony_ci{ 206484543d1Sopenharmony_ci // trigger lazy init 207484543d1Sopenharmony_ci ffrt::submit([&]() {}, {}, {}); 208484543d1Sopenharmony_ci ffrt::wait(); 209484543d1Sopenharmony_ci 210484543d1Sopenharmony_ci const int N = 10; 211484543d1Sopenharmony_ci const int M = 10; 212484543d1Sopenharmony_ci const int J = 10; 213484543d1Sopenharmony_ci ffrt::mutex lock; 214484543d1Sopenharmony_ci // std::mutex lock; 215484543d1Sopenharmony_ci int acc = 0; 216484543d1Sopenharmony_ci for (int i = 0; i < N; ++i) { 217484543d1Sopenharmony_ci ffrt::submit( 218484543d1Sopenharmony_ci [&]() { 219484543d1Sopenharmony_ci for (int j = 0; j < M; ++j) { 220484543d1Sopenharmony_ci lock.lock(); 221484543d1Sopenharmony_ci acc++; 222484543d1Sopenharmony_ci lock.unlock(); 223484543d1Sopenharmony_ci } 224484543d1Sopenharmony_ci }, 225484543d1Sopenharmony_ci {}, {}); 226484543d1Sopenharmony_ci } 227484543d1Sopenharmony_ci 228484543d1Sopenharmony_ci for (int j = 0; j < J; ++j) { 229484543d1Sopenharmony_ci lock.lock(); 230484543d1Sopenharmony_ci acc++; 231484543d1Sopenharmony_ci lock.unlock(); 232484543d1Sopenharmony_ci } 233484543d1Sopenharmony_ci 234484543d1Sopenharmony_ci ffrt::wait(); 235484543d1Sopenharmony_ci EXPECT_EQ(acc, (M * N + J)); 236484543d1Sopenharmony_ci} 237484543d1Sopenharmony_ci 238484543d1Sopenharmony_ciclass SleepTest : public testing::Test { 239484543d1Sopenharmony_ciprotected: 240484543d1Sopenharmony_ci static void SetUpTestCase() 241484543d1Sopenharmony_ci { 242484543d1Sopenharmony_ci } 243484543d1Sopenharmony_ci 244484543d1Sopenharmony_ci static void TearDownTestCase() 245484543d1Sopenharmony_ci { 246484543d1Sopenharmony_ci } 247484543d1Sopenharmony_ci 248484543d1Sopenharmony_ci virtual void SetUp() 249484543d1Sopenharmony_ci { 250484543d1Sopenharmony_ci } 251484543d1Sopenharmony_ci 252484543d1Sopenharmony_ci virtual void TearDown() 253484543d1Sopenharmony_ci { 254484543d1Sopenharmony_ci } 255484543d1Sopenharmony_ci}; 256484543d1Sopenharmony_ci 257484543d1Sopenharmony_ciHWTEST_F(SleepTest, yield_test, TestSize.Level1) 258484543d1Sopenharmony_ci{ 259484543d1Sopenharmony_ci int a = 0; 260484543d1Sopenharmony_ci 261484543d1Sopenharmony_ci this_task::yield(); 262484543d1Sopenharmony_ci 263484543d1Sopenharmony_ci EXPECT_EQ(a, 0); 264484543d1Sopenharmony_ci} 265484543d1Sopenharmony_ci 266484543d1Sopenharmony_ciHWTEST_F(SleepTest, sleep_for_test1, TestSize.Level1) 267484543d1Sopenharmony_ci{ 268484543d1Sopenharmony_ci int a = 0; 269484543d1Sopenharmony_ci 270484543d1Sopenharmony_ci this_task::sleep_for(10ms); 271484543d1Sopenharmony_ci 272484543d1Sopenharmony_ci EXPECT_EQ(a, 0); 273484543d1Sopenharmony_ci} 274484543d1Sopenharmony_ci 275484543d1Sopenharmony_ciHWTEST_F(SleepTest, sleep_for_test2, TestSize.Level1) 276484543d1Sopenharmony_ci{ 277484543d1Sopenharmony_ci int a = 0; 278484543d1Sopenharmony_ci 279484543d1Sopenharmony_ci submit([&]() { 280484543d1Sopenharmony_ci this_task::sleep_for(5us); 281484543d1Sopenharmony_ci a = 2; 282484543d1Sopenharmony_ci }, {}, {}); 283484543d1Sopenharmony_ci 284484543d1Sopenharmony_ci wait(); 285484543d1Sopenharmony_ci 286484543d1Sopenharmony_ci EXPECT_EQ(a, 2); 287484543d1Sopenharmony_ci} 288484543d1Sopenharmony_ci 289484543d1Sopenharmony_civoid* thd_func(void *arg) 290484543d1Sopenharmony_ci{ 291484543d1Sopenharmony_ci int *counter = (int *)arg; 292484543d1Sopenharmony_ci (*counter)++; 293484543d1Sopenharmony_ci return arg; 294484543d1Sopenharmony_ci} 295484543d1Sopenharmony_ci 296484543d1Sopenharmony_ciHWTEST_F(SleepTest, thread_test, TestSize.Level1) 297484543d1Sopenharmony_ci{ 298484543d1Sopenharmony_ci int a = 0; 299484543d1Sopenharmony_ci ffrt_thread_t thread; 300484543d1Sopenharmony_ci ffrt_thread_create(&thread, nullptr, thd_func, &a); 301484543d1Sopenharmony_ci void* result = nullptr; 302484543d1Sopenharmony_ci ffrt_thread_join(thread, &result); 303484543d1Sopenharmony_ci EXPECT_EQ(1, a); 304484543d1Sopenharmony_ci EXPECT_EQ(&a, result); 305484543d1Sopenharmony_ci} 306