2 * Copyright (c) 2015 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.
21 #include <dali-test-suite-utils.h>
22 #include <dali/devel-api/threading/conditional-wait.h>
23 #include <dali/devel-api/threading/thread.h>
25 using Dali::ConditionalWait;
28 namespace // for local variables to avoid name clashes
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
35 class WorkerThreadNotify : public Thread
40 while( gWorkerThreadWait ) // wait till we can exit
42 gWorkerThreadState = RUN;
43 usleep( 1 ); // 1 microseconds
45 usleep( 200 ); // give other thread time to get to Wait
47 gConditionalWait->Notify();
48 gWorkerThreadState = TERMINATE;
52 volatile int gNotifyCount = 0;
53 class WorkerThreadNotifyN : public Thread
57 while( gNotifyCount > 0 )
59 gConditionalWait->Notify();
60 usleep( 10 ); // 10 microseconds between each notify
65 class WorkerThreadWaitN : public Thread
69 gConditionalWait->Wait();
75 int UtcConditionalWait1P(void)
77 tet_infoline("Testing ConditionalWait - scenario: wait - notify with 2 threads");
79 WorkerThreadNotify thread1;
81 gConditionalWait = new ConditionalWait();
82 gWorkerThreadWait = true;
83 DALI_TEST_EQUALS( INIT, gWorkerThreadState, TEST_LOCATION );
84 DALI_TEST_EQUALS( 0, gGlobalValue, TEST_LOCATION );
87 // wait till the thread is in run state
88 while( RUN != gWorkerThreadState )
90 usleep( 1 ); // 1 microsecond
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 );
98 // wait till the thread is terminated state
99 while( TERMINATE != gWorkerThreadState )
101 usleep( 1 ); // 1 microsecond
106 delete gConditionalWait;
110 int UtcConditionalWait2P(void)
112 tet_infoline("Testing ConditionalWait - scenario: notify without wait");
114 ConditionalWait wait;
115 DALI_TEST_EQUALS( 0u, wait.GetWaitCount(), TEST_LOCATION );
117 DALI_TEST_EQUALS( 0u, wait.GetWaitCount(), TEST_LOCATION );
123 int UtcConditionalWait3P(void)
125 tet_infoline("Testing ConditionalWait - scenario: wait - notify N times 2 threads");
128 gConditionalWait = new ConditionalWait();
131 WorkerThreadNotifyN thread1;
134 while( gNotifyCount > 0 )
136 gConditionalWait->Wait();
138 DALI_TEST_EQUALS( 0u, gConditionalWait->GetWaitCount(), TEST_LOCATION );
139 usleep( 10 ); // 10 microseconds between each notify
141 DALI_TEST_EQUALS( 0u, gConditionalWait->GetWaitCount(), TEST_LOCATION );
145 delete gConditionalWait;
149 int UtcConditionalWait4P(void)
151 tet_infoline("Testing ConditionalWait - scenario: wait - notify N times from 3 threads");
154 gConditionalWait = new ConditionalWait();
157 WorkerThreadNotifyN thread1;
159 WorkerThreadNotifyN thread2;
161 WorkerThreadNotifyN thread3;
164 while( gNotifyCount > 0 )
166 gConditionalWait->Wait();
168 DALI_TEST_EQUALS( 0u, gConditionalWait->GetWaitCount(), TEST_LOCATION );
169 usleep( 10 ); // 10 microseconds between each notify
176 delete gConditionalWait;
180 int UtcConditionalWait5P(void)
182 tet_infoline("Testing ConditionalWait - scenario: 4 threads wait - notify once from 1 thread");
185 gConditionalWait = new ConditionalWait();
187 WorkerThreadWaitN thread1;
189 WorkerThreadWaitN thread2;
191 WorkerThreadWaitN thread3;
193 WorkerThreadWaitN thread4;
195 // wait till all child threads are waiting
196 while( gConditionalWait->GetWaitCount() < 4 )
199 // notify once, it will resume all threads
200 gConditionalWait->Notify();
207 DALI_TEST_EQUALS( 0u, gConditionalWait->GetWaitCount(), TEST_LOCATION );
209 delete gConditionalWait;
213 int UtcConditionalWait6P(void)
215 tet_infoline("Testing ConditionalWait - scenario: 4 threads wait - notify once from 1 thread");
218 gConditionalWait = new ConditionalWait();
220 WorkerThreadWaitN thread1;
222 WorkerThreadWaitN thread2;
224 WorkerThreadWaitN thread3;
226 WorkerThreadWaitN thread4;
228 // wait till all child threads are waiting
229 while( gConditionalWait->GetWaitCount() < 4 )
232 // notify once but with a scoped lock, it will resume all threads
234 ConditionalWait::ScopedLock lock( *gConditionalWait );
235 gConditionalWait->Notify( lock );
243 DALI_TEST_EQUALS( 0u, gConditionalWait->GetWaitCount(), TEST_LOCATION );
245 delete gConditionalWait;
249 int UtcConditionalWaitNonCopyable(void)
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 ) );
255 DALI_TEST_CHECK( true );