1 #include <gtest/gtest.h> 2 #include <thread> 3 #include <threads.h> 4 5 using namespace testing::ext; 6 7 class ThreadCndTest : public testing::Test { 8 protected: 9 mtx_t threadMtx; 10 cnd_t threadCnd; 11 SetUp()12 void SetUp() override 13 { 14 EXPECT_EQ(thrd_success, mtx_init(&threadMtx, mtx_plain)); 15 EXPECT_EQ(thrd_success, cnd_init(&threadCnd)); 16 } TearDown()17 void TearDown() override 18 { 19 mtx_destroy(&threadMtx); 20 cnd_destroy(&threadCnd); 21 } 22 }; 23 24 class WaitThread { 25 public: WaitThread(mtx_t * threadMtx,cnd_t * threadCnd,int * threadIndex)26 WaitThread(mtx_t* threadMtx, cnd_t* threadCnd, int* threadIndex) 27 { 28 mtx_ = threadMtx; 29 cnd_ = threadCnd; 30 index_ = threadIndex; 31 }; 32 ~WaitThread()33 ~WaitThread() {}; 34 WaitrBroadCast()35 void WaitrBroadCast() 36 { 37 EXPECT_EQ(thrd_success, mtx_lock(this->mtx_)); 38 while (*index_ != 1) { 39 EXPECT_EQ(thrd_success, cnd_wait(this->cnd_, this->mtx_)); 40 } 41 EXPECT_EQ(thrd_success, mtx_unlock(this->mtx_)); 42 }; 43 WaitrSignal()44 void WaitrSignal() 45 { 46 EXPECT_EQ(thrd_success, mtx_lock(this->mtx_)); 47 EXPECT_EQ(thrd_success, cnd_wait(this->cnd_, this->mtx_)); 48 EXPECT_EQ(thrd_success, mtx_unlock(this->mtx_)); 49 (*index_)++; 50 }; 51 ChangeInit()52 void ChangeInit() 53 { 54 EXPECT_EQ(thrd_success, mtx_lock(mtx_)); 55 (*index_)++; 56 EXPECT_EQ(thrd_success, mtx_unlock(mtx_)); 57 }; 58 59 private: 60 mtx_t* mtx_; 61 cnd_t* cnd_; 62 int* index_; 63 }; 64 65 /** 66 * @tc.name: cnd_broadcast_001 67 * @tc.desc: Testing whether calling cnd_broadcast to wake up all blocked threads can succeed in multithreading 68 * situations 69 * @tc.type: FUNC 70 * */ 71 HWTEST_F(ThreadCndTest, cnd_broadcast_001, TestSize.Level1) 72 { 73 int threadIndex = 0; 74 75 WaitThread wt(&threadMtx, &threadCnd, &threadIndex); 76 __anond145133f0102() 77 std::thread thread1([&]() { wt.WaitrBroadCast(); }); __anond145133f0202() 78 std::thread thread2([&]() { wt.WaitrBroadCast(); }); 79 80 wt.ChangeInit(); 81 82 EXPECT_EQ(thrd_success, cnd_broadcast(&threadCnd)); 83 thread1.join(); 84 thread2.join(); 85 } 86 87 /** 88 * @tc.name: cnd_signal_001 89 * @tc.desc: Testing whether calling cnd_signal to wake up all blocked threads can succeed in multithreading situations 90 * @tc.type: FUNC 91 * */ 92 HWTEST_F(ThreadCndTest, cnd_signal_001, TestSize.Level1) 93 { 94 int count = 0; 95 WaitThread wt(&threadMtx, &threadCnd, &count); 96 __anond145133f0302() 97 std::thread thread1([&]() { wt.WaitrSignal(); }); __anond145133f0402() 98 std::thread thread2([&]() { wt.WaitrSignal(); }); 99 100 usleep(10000); 101 EXPECT_EQ(thrd_success, cnd_signal(&threadCnd)); 102 while (count == 0) { 103 } 104 usleep(10000); 105 EXPECT_EQ(thrd_success, cnd_signal(&threadCnd)); 106 while (count == 1) { 107 } 108 thread1.join(); 109 thread2.join(); 110 } 111 112 /** 113 * @tc.name: cnd_timedwait_001 114 * @tc.desc: Test whether calling a function returns a timeout without setting a conditional wait time 115 * @tc.type: FUNC 116 * */ 117 HWTEST_F(ThreadCndTest, cnd_timedwait_001, TestSize.Level1) 118 { 119 cnd_t threadCnd; 120 timespec ts = {}; 121 mtx_lock(&threadMtx); 122 cnd_init(&threadCnd); 123 EXPECT_EQ(thrd_timedout, cnd_timedwait(&threadCnd, &threadMtx, &ts)); 124 }