• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }