2 * Copyright (c) 2017 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 <type_traits>
22 #include <dali/public-api/dali-core.h>
23 #include <dali/devel-api/threading/mutex.h>
24 #include <dali/devel-api/threading/thread.h>
25 #include <dali-test-suite-utils.h>
30 int UtcDaliMutexSingleThread(void)
32 tet_infoline("Testing Dali::Mutex in a single thread");
36 DALI_TEST_EQUALS( false, mutex1.IsLocked(), TEST_LOCATION );
41 Mutex::ScopedLock lock( mutex2 );
42 DALI_TEST_EQUALS( true, mutex2.IsLocked(), TEST_LOCATION );
47 Mutex::ScopedLock lock( mutex3 );
49 DALI_TEST_EQUALS( false, mutex3.IsLocked(), TEST_LOCATION );
54 namespace // for local variables to avoid name clashes
56 // make all these volatile to pre-empt any optimization screwing up the logic
57 volatile int gGlobalValue = 0;
58 volatile bool gWorkerThreadWait = true;
59 volatile enum ThreadState { INIT, RUN, LOCKING, TERMINATE } gWorkerThreadState = INIT;
60 Mutex* volatile gGlobalValueMutex; // volatile pointer to a mutex object
62 class TestThread : public Thread
66 gWorkerThreadState = RUN;
68 Mutex::ScopedLock lock( *gGlobalValueMutex );
69 gWorkerThreadState = LOCKING;
71 while( gWorkerThreadWait ) // wait till we can exit
73 usleep( 1 ); // 1 microsecond
76 gWorkerThreadState = TERMINATE;
81 int UtcDaliMutexMultiThread(void)
83 tet_infoline("Testing Dali::Mutex multithreaded");
85 gGlobalValueMutex = new Dali::Mutex();
90 gWorkerThreadWait = true;
91 DALI_TEST_EQUALS( INIT, gWorkerThreadState, TEST_LOCATION );
92 DALI_TEST_EQUALS( 0, gGlobalValue, TEST_LOCATION );
93 DALI_TEST_EQUALS( false, gGlobalValueMutex->IsLocked(), TEST_LOCATION );
97 Mutex::ScopedLock lock( *gGlobalValueMutex );
98 DALI_TEST_EQUALS( true, gGlobalValueMutex->IsLocked(), TEST_LOCATION );
100 // wait till the thread is in run state
101 while( RUN != gWorkerThreadState )
103 usleep( 1 ); // 1 microsecond
105 // now the thread is running and mutex is still locked by this thread so value is not changed
106 DALI_TEST_EQUALS( true, gGlobalValueMutex->IsLocked(), TEST_LOCATION );
107 DALI_TEST_EQUALS( 0, gGlobalValue, TEST_LOCATION );
108 // drop out of scope, releases our lock
110 // now child thread is allowed to change the value
111 // wait till the thread is in locking state
112 while( LOCKING != gWorkerThreadState )
114 usleep( 1 ); // 1 microsecond
116 // mutex is locked, but not by us, by the child thread
117 DALI_TEST_EQUALS( true, gGlobalValueMutex->IsLocked(), TEST_LOCATION );
119 DALI_TEST_EQUALS( -1, gGlobalValue, TEST_LOCATION );
121 gWorkerThreadWait = false;
122 // wait till the thread is terminated state
123 while( TERMINATE != gWorkerThreadState )
125 usleep( 1 ); // 1 microsecond
127 DALI_TEST_EQUALS( false, gGlobalValueMutex->IsLocked(), TEST_LOCATION );
133 int UtcDaliMutexNonCopyable(void)
135 // we want to make sure that mutex is not copyable (its copy constructor is not defined)
136 // this test will stop compiling if Mutex has compiler generated copy constructor
137 static_assert( !__has_trivial_copy( Mutex ), "Mutex should NOT be copyable" );
139 DALI_TEST_CHECK( true );