• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <gtest/gtest.h>
2 #include <pthread.h>
3 #include <thread>
4 #include <threads.h>
5 
6 using namespace testing::ext;
7 
8 #define TS_PER_T 1000000000
9 constexpr int USLEEP_TIME = 5000;
10 
11 class PthreadCondTest : public testing::Test {
12 protected:
13     pthread_mutex_t mutex_;
14     pthread_cond_t cond_;
15     bool sleepState_ = true;
16     bool accessState_ = true;
17     pthread_t thread_;
18     timespec times_;
19 
WaitingThread()20     void WaitingThread()
21     {
22         sleepState_ = true;
23         pthread_create(&thread_, nullptr, reinterpret_cast<void* (*)(void*)>(WaitThreadSign), this);
24         while (sleepState_) {
25             usleep(USLEEP_TIME);
26         }
27         usleep(USLEEP_TIME);
28     }
29 
WaitThreadSign(PthreadCondTest * arg)30     static void WaitThreadSign(PthreadCondTest* arg)
31     {
32         pthread_mutex_init(&arg->mutex_, nullptr);
33         ASSERT_NE(nullptr, arg);
34         pthread_mutex_lock(&arg->mutex_);
35         arg->sleepState_ = false;
36         arg->accessState_ = true;
37         while (arg->accessState_) {
38             pthread_cond_wait(&arg->cond_, &arg->mutex_);
39         }
40         pthread_mutex_unlock(&arg->mutex_);
41     }
42 
SetUp()43     void SetUp() override {}
TearDown()44     void TearDown() override {}
45 
InitMonotonic(bool monotonic=false)46     void InitMonotonic(bool monotonic = false)
47     {
48         pthread_mutex_init(&mutex_, nullptr);
49         if (monotonic) {
50             pthread_condattr_t condAttr;
51             pthread_condattr_init(&condAttr);
52             EXPECT_EQ(0, pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC));
53             clockid_t clock;
54             EXPECT_EQ(0, pthread_condattr_getclock(&condAttr, &clock));
55             EXPECT_EQ(CLOCK_MONOTONIC, clock);
56             EXPECT_EQ(0, pthread_cond_init(&cond_, &condAttr));
57         } else {
58             EXPECT_EQ(0, pthread_cond_init(&cond_, nullptr));
59         }
60     }
61 
MakeTimeout(clockid_t clock,int (* testWaitFunc)(pthread_cond_t * cond,pthread_mutex_t * mutex,const timespec * timeout))62     void MakeTimeout(
63         clockid_t clock, int (*testWaitFunc)(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* timeout))
64     {
65         pthread_mutex_lock(&mutex_);
66         clock_gettime(clock, &times_);
67         EXPECT_EQ(ETIMEDOUT, testWaitFunc(&cond_, &mutex_, &times_));
68         times_.tv_nsec = -1;
69         EXPECT_EQ(EINVAL, testWaitFunc(&cond_, &mutex_, &times_));
70         pthread_mutex_unlock(&mutex_);
71     }
72 };
73 
74 /**
75  * @tc.name: pthread_cond_signal_001
76  * @tc.desc: Call the wait function to block the thread and determine if the individual thread wakes up successfully
77  * @tc.type: FUNC
78  * */
79 HWTEST_F(PthreadCondTest, pthread_cond_signal_001, TestSize.Level1)
80 {
81     pthread_condattr_t condAttr;
82     pthread_condattr_init(&condAttr);
83     pthread_condattr_setclock(&condAttr, CLOCK_REALTIME);
84     pthread_cond_init(&cond_, &condAttr);
85     pthread_condattr_destroy(&condAttr);
86     WaitingThread();
87     accessState_ = false;
88     EXPECT_EQ(0, pthread_cond_signal(&cond_));
89     pthread_join(thread_, nullptr);
90     pthread_cond_destroy(&cond_);
91 }
92 
93 /**
94  * @tc.name: pthread_cond_broadcast_001
95  * @tc.desc: Set the clock property for the condition, set the waiting thread to determine if the function is
96  *           successful, and then broadcast to wake up the waiting thread
97  * @tc.type: FUNC
98  * */
99 HWTEST_F(PthreadCondTest, pthread_cond_broadcast_001, TestSize.Level1)
100 {
101     pthread_condattr_t condAttr;
102     pthread_condattr_init(&condAttr);
103     pthread_condattr_setclock(&condAttr, CLOCK_REALTIME);
104     pthread_cond_init(&cond_, &condAttr);
105     pthread_condattr_destroy(&condAttr);
106     WaitingThread();
107     accessState_ = false;
108     EXPECT_EQ(0, pthread_cond_broadcast(&cond_));
109     pthread_join(thread_, nullptr);
110     pthread_cond_destroy(&cond_);
111 }
112 
113 /**
114  * @tc.name: pthread_cond_timedwait_001
115  * @tc.desc: Set the negative timeout time of the CLOCK_REALTIME clock as the function to determine whether the return
116  *           is invalid, set the large timeout time of the CLOCK_REALTIME clock as the function to determine whether
117  *           the return is invalid, and set the normal timeout time of the CLOCK_REALTIME clock as the function to
118  *           determine whether the return is successful
119  * @tc.type: FUNC
120  * */
121 HWTEST_F(PthreadCondTest, pthread_cond_timedwait_001, TestSize.Level1)
122 {
123     InitMonotonic();
124     MakeTimeout(CLOCK_REALTIME, pthread_cond_timedwait);
125     pthread_mutex_destroy(&mutex_);
126 }
127 
128 /**
129  * @tc.name: pthread_cond_timedwait_monotonic_np_001
130  * @tc.desc: Set the negative timeout time of the CLOCK_MONOTONIC clock as the function to determine whether the return
131  *           is invalid, set the large timeout time of the CLOCK_MONOTONIC clock as the function to determine whether
132  *           the return is invalid, and set the normal timeout time of the CLOCK_MONOTONIC clock as the function to
133  *           determine whether the return is successful
134  * @tc.type: FUNC
135  * */
136 HWTEST_F(PthreadCondTest, pthread_cond_timedwait_monotonic_np_001, TestSize.Level1)
137 {
138     InitMonotonic();
139     MakeTimeout(CLOCK_MONOTONIC, pthread_cond_timedwait_monotonic_np);
140     InitMonotonic(true);
141     MakeTimeout(CLOCK_MONOTONIC, pthread_cond_timedwait_monotonic_np);
142     pthread_mutex_destroy(&mutex_);
143 }
144 
145 /**
146  * @tc.name: pthread_cond_clockwait_001
147  * @tc.desc: Set the negative timeout time of the CLOCK_MONOTONIC clock as the function to determine whether the return
148  *           is invalid, set the large timeout time of the CLOCK_MONOTONIC clock as the function to determine whether
149  *           the return is invalid, and set the normal timeout time of the CLOCK_MONOTONIC clock as the function to
150  *           determine whether the return is successful
151  * @tc.type: FUNC
152  * */
153 HWTEST_F(PthreadCondTest, pthread_cond_clockwait_001, TestSize.Level1)
154 {
155     InitMonotonic();
__anon0a60de7f0102(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* timeout) 156     MakeTimeout(CLOCK_MONOTONIC, [](pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* timeout) {
157         return pthread_cond_clockwait(cond, mutex, CLOCK_MONOTONIC, timeout);
158     });
159     InitMonotonic(true);
__anon0a60de7f0202(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* timeout) 160     MakeTimeout(CLOCK_MONOTONIC, [](pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* timeout) {
161         return pthread_cond_clockwait(cond, mutex, CLOCK_MONOTONIC, timeout);
162     });
163     pthread_mutex_destroy(&mutex_);
164 }
165 
166 /**
167  * @tc.name: pthread_cond_clockwait_002
168  * @tc.desc: Set the negative timeout time of the CLOCK_REALTIME clock as the function to determine whether the return
169  *           is invalid, set the large timeout time of the CLOCK_REALTIME clock as the function to determine whether
170  *           the return is invalid, and set the normal timeout time of the CLOCK_REALTIME clock as the function to
171  *           determine whether the return is successful
172  * @tc.type: FUNC
173  * */
174 HWTEST_F(PthreadCondTest, pthread_cond_clockwait_002, TestSize.Level1)
175 {
176     InitMonotonic();
__anon0a60de7f0302(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* timeout) 177     MakeTimeout(CLOCK_REALTIME, [](pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* timeout) {
178         return pthread_cond_clockwait(cond, mutex, CLOCK_REALTIME, timeout);
179     });
180     InitMonotonic(true);
__anon0a60de7f0402(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* timeout) 181     MakeTimeout(CLOCK_REALTIME, [](pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* timeout) {
182         return pthread_cond_clockwait(cond, mutex, CLOCK_REALTIME, timeout);
183     });
184     pthread_mutex_destroy(&mutex_);
185 }
186 
187 /**
188  * @tc.name: pthread_cond_clockwait_003
189  * @tc.desc: Set invalid attribute and return corresponding error code
190  * @tc.type: FUNC
191  * */
192 HWTEST_F(PthreadCondTest, pthread_cond_clockwait_003, TestSize.Level1)
193 {
194     pthread_cond_t pthreadCond = PTHREAD_COND_INITIALIZER;
195     pthread_mutex_t pthreadMutex = PTHREAD_MUTEX_INITIALIZER;
196     timespec times;
197     EXPECT_EQ(EINVAL, pthread_cond_clockwait(&pthreadCond, &pthreadMutex, CLOCK_PROCESS_CPUTIME_ID, &times));
198 }
199 
200 /**
201  * @tc.name: pthread_condattr_init_001
202  * @tc.desc: Determine whether the conditional variable sets/obtains clock attribute equality
203  * @tc.type: FUNC
204  * */
205 HWTEST_F(PthreadCondTest, pthread_condattr_init_001, TestSize.Level1)
206 {
207     pthread_condattr_t condAttr;
208     clockid_t clock;
209     pthread_condattr_init(&condAttr);
210     EXPECT_EQ(0, pthread_condattr_getclock(&condAttr, &clock));
211     EXPECT_EQ(CLOCK_REALTIME, clock);
212 }
213 
214 /**
215  * @tc.name: pthread_condattr_setclock_001
216  * @tc.desc: Determine whether the conditional variable sets/obtains clock attribute equality
217  * @tc.type: FUNC
218  * */
219 HWTEST_F(PthreadCondTest, pthread_condattr_setclock_001, TestSize.Level1)
220 {
221     pthread_condattr_t condAttr;
222     clockid_t clock;
223     pthread_condattr_init(&condAttr);
224     EXPECT_EQ(0, pthread_condattr_setclock(&condAttr, CLOCK_REALTIME));
225     EXPECT_EQ(0, pthread_condattr_getclock(&condAttr, &clock));
226     EXPECT_EQ(CLOCK_REALTIME, clock);
227 }
228 
229 /**
230  * @tc.name: pthread_condattr_setclock_002
231  * @tc.desc: Determine whether the conditional variable sets/obtains clock attribute equality
232  * @tc.type: FUNC
233  * */
234 HWTEST_F(PthreadCondTest, pthread_condattr_setclock_002, TestSize.Level1)
235 {
236     pthread_condattr_t condAttr;
237     clockid_t clock;
238     pthread_condattr_init(&condAttr);
239     EXPECT_EQ(0, pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC));
240     EXPECT_EQ(0, pthread_condattr_getclock(&condAttr, &clock));
241     EXPECT_EQ(CLOCK_MONOTONIC, clock);
242 }
243 
244 /**
245  * @tc.name: pthread_condattr_setclock_003
246  * @tc.desc: Determine whether the conditional variable sets/obtains clock attribute equality
247  * @tc.type: FUNC
248  * */
249 HWTEST_F(PthreadCondTest, pthread_condattr_setclock_003, TestSize.Level1)
250 {
251     pthread_condattr_t condAttr;
252     pthread_condattr_init(&condAttr);
253     EXPECT_EQ(EINVAL, pthread_condattr_setclock(&condAttr, CLOCK_THREAD_CPUTIME_ID));
254 }