Revert "[Tizen] Implement partial update"
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-ConditionalWait.cpp
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 #include <iostream>
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <type_traits>
22 #include <dali-test-suite-utils.h>
23 #include <dali/devel-api/threading/conditional-wait.h>
24 #include <dali/devel-api/threading/thread.h>
25
26 using Dali::ConditionalWait;
27 using Dali::Thread;
28
29 namespace // for local variables to avoid name clashes
30 {
31 volatile int gGlobalValue = 0;
32 volatile bool gWorkerThreadWait = true;
33 enum ThreadState { INIT, RUN, TERMINATE } volatile gWorkerThreadState = INIT;
34 ConditionalWait* volatile gConditionalWait; // volatile pointer to a ConditionalWait object
35
36 class WorkerThreadNotify : public Thread
37 {
38   virtual void Run()
39   {
40     gGlobalValue = -1;
41     while( gWorkerThreadWait ) // wait till we can exit
42     {
43       gWorkerThreadState = RUN;
44       usleep( 1 ); // 1 microseconds
45     }
46     usleep( 200 ); // give other thread time to get to Wait
47     gGlobalValue = 1;
48     gConditionalWait->Notify();
49     gWorkerThreadState = TERMINATE;
50   }
51 };
52
53 volatile int gNotifyCount = 0;
54 class WorkerThreadNotifyN : public Thread
55 {
56   virtual void Run()
57   {
58     while( gNotifyCount > 0 )
59     {
60       gConditionalWait->Notify();
61       usleep( 10 ); // 10 microseconds between each notify
62     }
63   }
64 };
65
66 class WorkerThreadWaitN : public Thread
67 {
68   virtual void Run()
69   {
70     gConditionalWait->Wait();
71   }
72 };
73
74 }
75
76 int UtcConditionalWait1P(void)
77 {
78   tet_infoline("Testing ConditionalWait - scenario:  wait - notify with 2 threads");
79
80   WorkerThreadNotify thread1;
81   // initialize values
82   gConditionalWait = new ConditionalWait();
83   gWorkerThreadWait = true;
84   DALI_TEST_EQUALS( INIT, gWorkerThreadState, TEST_LOCATION );
85   DALI_TEST_EQUALS( 0, gGlobalValue, TEST_LOCATION );
86
87   thread1.Start();
88   // wait till the thread is in run state
89   while( RUN != gWorkerThreadState )
90   {
91     usleep( 1 ); // 1 microsecond
92   }
93   // let worker continue and finish
94   gWorkerThreadWait = false;
95   gConditionalWait->Wait();
96   DALI_TEST_EQUALS( 1, gGlobalValue, TEST_LOCATION );
97   DALI_TEST_EQUALS( 0u, gConditionalWait->GetWaitCount(), TEST_LOCATION );
98
99   // wait till the thread is terminated state
100   while( TERMINATE != gWorkerThreadState )
101   {
102     usleep( 1 ); // 1 microsecond
103   }
104
105   thread1.Join();
106
107   delete gConditionalWait;
108   END_TEST;
109 }
110
111 int UtcConditionalWait2P(void)
112 {
113   tet_infoline("Testing ConditionalWait - scenario: notify without wait");
114
115   ConditionalWait wait;
116   DALI_TEST_EQUALS( 0u, wait.GetWaitCount(), TEST_LOCATION );
117   wait.Notify();
118   DALI_TEST_EQUALS( 0u, wait.GetWaitCount(), TEST_LOCATION );
119
120   END_TEST;
121 }
122
123
124 int UtcConditionalWait3P(void)
125 {
126   tet_infoline("Testing ConditionalWait - scenario: wait - notify N times 2 threads");
127
128   // initialize values
129   gConditionalWait = new ConditionalWait();
130   gNotifyCount = 100;
131
132   WorkerThreadNotifyN thread1;
133   thread1.Start();
134
135   while( gNotifyCount > 0 )
136   {
137     gConditionalWait->Wait();
138     --gNotifyCount;
139     DALI_TEST_EQUALS( 0u, gConditionalWait->GetWaitCount(), TEST_LOCATION );
140     usleep( 10 ); // 10 microseconds between each notify
141   }
142   DALI_TEST_EQUALS( 0u, gConditionalWait->GetWaitCount(), TEST_LOCATION );
143
144   thread1.Join();
145
146   delete gConditionalWait;
147   END_TEST;
148 }
149
150 int UtcConditionalWait4P(void)
151 {
152   tet_infoline("Testing ConditionalWait - scenario:  wait - notify N times from 3 threads");
153
154   // initialize values
155   gConditionalWait = new ConditionalWait();
156   gNotifyCount = 100;
157
158   WorkerThreadNotifyN thread1;
159   thread1.Start();
160   WorkerThreadNotifyN thread2;
161   thread2.Start();
162   WorkerThreadNotifyN thread3;
163   thread3.Start();
164
165   while( gNotifyCount > 0 )
166   {
167     gConditionalWait->Wait();
168     --gNotifyCount;
169     DALI_TEST_EQUALS( 0u, gConditionalWait->GetWaitCount(), TEST_LOCATION );
170     usleep( 10 ); // 10 microseconds between each notify
171   }
172
173   thread1.Join();
174   thread2.Join();
175   thread3.Join();
176
177   delete gConditionalWait;
178   END_TEST;
179 }
180
181 int UtcConditionalWait5P(void)
182 {
183   tet_infoline("Testing ConditionalWait - scenario:  4 threads wait - notify once from 1 thread");
184
185   // initialize values
186   gConditionalWait = new ConditionalWait();
187
188   WorkerThreadWaitN thread1;
189   thread1.Start();
190   WorkerThreadWaitN thread2;
191   thread2.Start();
192   WorkerThreadWaitN thread3;
193   thread3.Start();
194   WorkerThreadWaitN thread4;
195   thread4.Start();
196   // wait till all child threads are waiting
197   while( gConditionalWait->GetWaitCount() < 4 )
198   { }
199
200   // notify once, it will resume all threads
201   gConditionalWait->Notify();
202
203   thread1.Join();
204   thread2.Join();
205   thread3.Join();
206   thread4.Join();
207
208   DALI_TEST_EQUALS( 0u, gConditionalWait->GetWaitCount(), TEST_LOCATION );
209
210   delete gConditionalWait;
211   END_TEST;
212 }
213
214 int UtcConditionalWait6P(void)
215 {
216   tet_infoline("Testing ConditionalWait - scenario:  4 threads wait - notify once from 1 thread");
217
218   // initialize values
219   gConditionalWait = new ConditionalWait();
220
221   WorkerThreadWaitN thread1;
222   thread1.Start();
223   WorkerThreadWaitN thread2;
224   thread2.Start();
225   WorkerThreadWaitN thread3;
226   thread3.Start();
227   WorkerThreadWaitN thread4;
228   thread4.Start();
229   // wait till all child threads are waiting
230   while( gConditionalWait->GetWaitCount() < 4 )
231   { }
232
233   // notify once but with a scoped lock, it will resume all threads
234   {
235     ConditionalWait::ScopedLock lock( *gConditionalWait );
236     gConditionalWait->Notify( lock );
237   }
238
239   thread1.Join();
240   thread2.Join();
241   thread3.Join();
242   thread4.Join();
243
244   DALI_TEST_EQUALS( 0u, gConditionalWait->GetWaitCount(), TEST_LOCATION );
245
246   delete gConditionalWait;
247   END_TEST;
248 }
249
250 int UtcConditionalWaitNonCopyable(void)
251 {
252   // we want to make sure that ConditionalWait is not copyable (its copy constructor is not defined)
253   // this test will stop compiling if ConditionalWait has compiler generated copy constructor
254   static_assert( !__has_trivial_copy( ConditionalWait ), "ConditionalWait should NOT be copyable" );
255
256   DALI_TEST_CHECK( true );
257   END_TEST;
258 }
259
260