Dali 3D User Interface Engine
utc-Dali-ConditionalWait.cpp
Go to the documentation of this file.
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>
24 
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;
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  {
43  usleep( 1 ); // 1 microseconds
44  }
45  usleep( 200 ); // give other thread time to get to Wait
46  gGlobalValue = 1;
47  gConditionalWait->Notify();
49  }
50 };
51 
52 volatile int gNotifyCount = 0;
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 
76 {
77  tet_infoline("Testing ConditionalWait - scenario: wait - notify with 2 threads");
78 
79  WorkerThreadNotify thread1;
80  // initialize values
82  gWorkerThreadWait = true;
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;
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 
111 {
112  tet_infoline("Testing ConditionalWait - scenario: notify without wait");
113 
114  ConditionalWait wait;
116  wait.Notify();
118 
119  END_TEST;
120 }
121 
122 
124 {
125  tet_infoline("Testing ConditionalWait - scenario: wait - notify N times 2 threads");
126 
127  // initialize values
129  gNotifyCount = 100;
130 
131  WorkerThreadNotifyN thread1;
132  thread1.Start();
133 
134  while( gNotifyCount > 0 )
135  {
137  --gNotifyCount;
139  usleep( 10 ); // 10 microseconds between each notify
140  }
142 
143  thread1.Join();
144 
145  delete gConditionalWait;
146  END_TEST;
147 }
148 
150 {
151  tet_infoline("Testing ConditionalWait - scenario: wait - notify N times from 3 threads");
152 
153  // initialize values
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  {
167  --gNotifyCount;
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 
181 {
182  tet_infoline("Testing ConditionalWait - scenario: 4 threads wait - notify once from 1 thread");
183 
184  // initialize values
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
201 
202  thread1.Join();
203  thread2.Join();
204  thread3.Join();
205  thread4.Join();
206 
208 
209  delete gConditionalWait;
210  END_TEST;
211 }
212 
214 {
215  tet_infoline("Testing ConditionalWait - scenario: 4 threads wait - notify once from 1 thread");
216 
217  // initialize values
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 
244 
245  delete gConditionalWait;
246  END_TEST;
247 }
248 
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 
Dali Docs Home
Read more about Dali