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