2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <dali-test-suite-utils.h>
19 #include <dali/devel-api/threading/conditional-wait.h>
20 #include <dali/devel-api/threading/thread.h>
25 #include <type_traits>
27 using Dali::ConditionalWait;
30 namespace // for local variables to avoid name clashes
32 volatile int gGlobalValue = 0;
33 volatile bool gWorkerThreadWait = true;
39 } volatile gWorkerThreadState = INIT;
40 ConditionalWait* volatile gConditionalWait; // volatile pointer to a ConditionalWait object
42 class WorkerThreadNotify : public Thread
47 while(gWorkerThreadWait) // wait till we can exit
49 gWorkerThreadState = RUN;
50 usleep(1); // 1 microseconds
52 usleep(200); // give other thread time to get to Wait
54 gConditionalWait->Notify();
55 gWorkerThreadState = TERMINATE;
59 volatile int gNotifyCount = 0;
60 class WorkerThreadNotifyN : public Thread
64 while(gNotifyCount > 0)
66 gConditionalWait->Notify();
67 usleep(10); // 10 microseconds between each notify
72 class WorkerThreadWaitN : public Thread
76 gConditionalWait->Wait();
82 int UtcConditionalWait1P(void)
84 tet_infoline("Testing ConditionalWait - scenario: wait - notify with 2 threads");
86 WorkerThreadNotify thread1;
88 gConditionalWait = new ConditionalWait();
89 gWorkerThreadWait = true;
90 DALI_TEST_EQUALS(INIT, gWorkerThreadState, TEST_LOCATION);
91 DALI_TEST_EQUALS(0, gGlobalValue, TEST_LOCATION);
94 // wait till the thread is in run state
95 while(RUN != gWorkerThreadState)
97 usleep(1); // 1 microsecond
99 // let worker continue and finish
100 gWorkerThreadWait = false;
101 gConditionalWait->Wait();
102 DALI_TEST_EQUALS(1, gGlobalValue, TEST_LOCATION);
103 DALI_TEST_EQUALS(0u, gConditionalWait->GetWaitCount(), TEST_LOCATION);
105 // wait till the thread is terminated state
106 while(TERMINATE != gWorkerThreadState)
108 usleep(1); // 1 microsecond
113 delete gConditionalWait;
117 int UtcConditionalWait2P(void)
119 tet_infoline("Testing ConditionalWait - scenario: notify without wait");
121 ConditionalWait wait;
122 DALI_TEST_EQUALS(0u, wait.GetWaitCount(), TEST_LOCATION);
124 DALI_TEST_EQUALS(0u, wait.GetWaitCount(), TEST_LOCATION);
129 int UtcConditionalWait3P(void)
131 tet_infoline("Testing ConditionalWait - scenario: wait - notify N times 2 threads");
134 gConditionalWait = new ConditionalWait();
137 WorkerThreadNotifyN thread1;
140 while(gNotifyCount > 0)
142 gConditionalWait->Wait();
144 DALI_TEST_EQUALS(0u, gConditionalWait->GetWaitCount(), TEST_LOCATION);
145 usleep(10); // 10 microseconds between each notify
147 DALI_TEST_EQUALS(0u, gConditionalWait->GetWaitCount(), TEST_LOCATION);
151 delete gConditionalWait;
155 int UtcConditionalWait4P(void)
157 tet_infoline("Testing ConditionalWait - scenario: wait - notify N times from 3 threads");
160 gConditionalWait = new ConditionalWait();
163 WorkerThreadNotifyN thread1;
165 WorkerThreadNotifyN thread2;
167 WorkerThreadNotifyN thread3;
170 while(gNotifyCount > 0)
172 gConditionalWait->Wait();
174 DALI_TEST_EQUALS(0u, gConditionalWait->GetWaitCount(), TEST_LOCATION);
175 usleep(10); // 10 microseconds between each notify
182 delete gConditionalWait;
186 int UtcConditionalWait5P(void)
188 tet_infoline("Testing ConditionalWait - scenario: 4 threads wait - notify once from 1 thread");
191 gConditionalWait = new ConditionalWait();
193 WorkerThreadWaitN thread1;
195 WorkerThreadWaitN thread2;
197 WorkerThreadWaitN thread3;
199 WorkerThreadWaitN thread4;
201 // wait till all child threads are waiting
202 while(gConditionalWait->GetWaitCount() < 4)
206 // notify once, it will resume all threads
207 gConditionalWait->Notify();
214 DALI_TEST_EQUALS(0u, gConditionalWait->GetWaitCount(), TEST_LOCATION);
216 delete gConditionalWait;
220 int UtcConditionalWait6P(void)
222 tet_infoline("Testing ConditionalWait - scenario: 4 threads wait - notify once from 1 thread");
225 gConditionalWait = new ConditionalWait();
227 WorkerThreadWaitN thread1;
229 WorkerThreadWaitN thread2;
231 WorkerThreadWaitN thread3;
233 WorkerThreadWaitN thread4;
235 // wait till all child threads are waiting
236 while(gConditionalWait->GetWaitCount() < 4)
240 // notify once but with a scoped lock, it will resume all threads
242 ConditionalWait::ScopedLock lock(*gConditionalWait);
243 gConditionalWait->Notify(lock);
251 DALI_TEST_EQUALS(0u, gConditionalWait->GetWaitCount(), TEST_LOCATION);
253 delete gConditionalWait;
257 int UtcConditionalWaitNonCopyable(void)
259 // we want to make sure that ConditionalWait is not copyable (its copy constructor is not defined)
260 // this test will stop compiling if ConditionalWait has compiler generated copy constructor
261 static_assert(!__has_trivial_copy(ConditionalWait), "ConditionalWait should NOT be copyable");
263 DALI_TEST_CHECK(true);