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/public-api/dali-core.h>
22 #include <dali/devel-api/threading/mutex.h>
23 #include <dali/devel-api/threading/thread.h>
24 #include <dali-test-suite-utils.h>
29 int UtcDaliMutexSingleThread(void)
31 tet_infoline("Testing Dali::Mutex in a single thread");
35 DALI_TEST_EQUALS( false, mutex1.IsLocked(), TEST_LOCATION );
40 Mutex::ScopedLock lock( mutex2 );
41 DALI_TEST_EQUALS( true, mutex2.IsLocked(), TEST_LOCATION );
46 Mutex::ScopedLock lock( mutex3 );
48 DALI_TEST_EQUALS( false, mutex3.IsLocked(), TEST_LOCATION );
53 namespace // for local variables to avoid name clashes
55 // make all these volatile to pre-empt any optimization screwing up the logic
56 volatile int gGlobalValue = 0;
57 volatile bool gWorkerThreadWait = true;
58 volatile enum ThreadState { INIT, RUN, LOCKING, TERMINATE } gWorkerThreadState = INIT;
59 Mutex* volatile gGlobalValueMutex; // volatile pointer to a mutex object
61 class TestThread : public Thread
65 gWorkerThreadState = RUN;
67 Mutex::ScopedLock lock( *gGlobalValueMutex );
68 gWorkerThreadState = LOCKING;
70 while( gWorkerThreadWait ) // wait till we can exit
72 usleep( 1 ); // 1 microsecond
75 gWorkerThreadState = TERMINATE;
80 int UtcDaliMutexMultiThread(void)
82 tet_infoline("Testing Dali::Mutex multithreaded");
84 gGlobalValueMutex = new Dali::Mutex();
89 gWorkerThreadWait = true;
90 DALI_TEST_EQUALS( INIT, gWorkerThreadState, TEST_LOCATION );
91 DALI_TEST_EQUALS( 0, gGlobalValue, TEST_LOCATION );
92 DALI_TEST_EQUALS( false, gGlobalValueMutex->IsLocked(), TEST_LOCATION );
96 Mutex::ScopedLock lock( *gGlobalValueMutex );
97 DALI_TEST_EQUALS( true, gGlobalValueMutex->IsLocked(), TEST_LOCATION );
99 // wait till the thread is in run state
100 while( RUN != gWorkerThreadState )
102 usleep( 1 ); // 1 microsecond
104 // now the thread is running and mutex is still locked by this thread so value is not changed
105 DALI_TEST_EQUALS( true, gGlobalValueMutex->IsLocked(), TEST_LOCATION );
106 DALI_TEST_EQUALS( 0, gGlobalValue, TEST_LOCATION );
107 // drop out of scope, releases our lock
109 // now child thread is allowed to change the value
110 // wait till the thread is in locking state
111 while( LOCKING != gWorkerThreadState )
113 usleep( 1 ); // 1 microsecond
115 // mutex is locked, but not by us, by the child thread
116 DALI_TEST_EQUALS( true, gGlobalValueMutex->IsLocked(), TEST_LOCATION );
118 DALI_TEST_EQUALS( -1, gGlobalValue, TEST_LOCATION );
120 gWorkerThreadWait = false;
121 // wait till the thread is terminated state
122 while( TERMINATE != gWorkerThreadState )
124 usleep( 1 ); // 1 microsecond
126 DALI_TEST_EQUALS( false, gGlobalValueMutex->IsLocked(), TEST_LOCATION );
132 int UtcDaliMutexNonCopyable(void)
134 // we want to make sure that mutex is not copyable (its copy constructor is not defined)
135 // this test will stop compiling if Mutex has compiler generated copy constructor
136 DALI_COMPILE_TIME_ASSERT( !__has_trivial_copy( Mutex ) );
138 DALI_TEST_CHECK( true );