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.
19 #include <dali/internal/common/mutex-impl.h>
22 #ifdef LOCK_BACKTRACE_ENABLED
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/integration-api/debug.h>
31 #endif // LOCK_BACKTRACE_ENABLED
34 #include <dali/integration-api/debug.h>
38 #ifdef LOCK_BACKTRACE_ENABLED
39 extern std::string Demangle( const char* symbol );
40 #endif // LOCK_BACKTRACE_ENABLED
50 #ifdef LOCK_BACKTRACE_ENABLED
53 const unsigned int MAX_NUM_STACK_FRAMES = 4;
54 const unsigned int MAX_LOCK_SUPPORT = 5;
58 void * frameArray[ MAX_NUM_STACK_FRAMES ]; ///< Stores the frame array where the lock occurred
59 int size; ///< Number of frames in the frame array (can be less than MAX_NUM_STACK_FRAMES)
62 __thread BackTraceInfo gBackTraceInfo[ MAX_LOCK_SUPPORT ]; ///< Thread local storage for the backtrace of the locks
64 #endif // LOCK_BACKTRACE_ENABLED
66 __thread unsigned int gThreadLockCount = 0; ///<
67 } // unnamed namespace
69 void Lock( pthread_mutex_t* mutex )
73 #ifdef LOCK_BACKTRACE_ENABLED
75 if( gThreadLockCount <= MAX_LOCK_SUPPORT )
77 // Store the frame array for this lock
78 int backTraceIndex = gThreadLockCount - 1;
79 gBackTraceInfo[ backTraceIndex ].size = backtrace( gBackTraceInfo[ backTraceIndex ].frameArray, MAX_NUM_STACK_FRAMES );
83 DALI_LOG_ERROR( "Reached Maximum lock backtrace support. Previous Locks:\n" );
86 // If we've got more than one lock, then show a warning with a backtrace for all locks that we currently hold
87 if( gThreadLockCount > 1 )
89 for( unsigned int i = 0; ( i < gThreadLockCount ) && ( i < MAX_LOCK_SUPPORT ); ++i )
91 DALI_LOG_WARNING( "[Lock %d]\n", i+1 );
92 char** symbols = backtrace_symbols( gBackTraceInfo[ i ].frameArray, gBackTraceInfo[ i ].size );
93 for( int j = 1; j < gBackTraceInfo[ i ].size; ++j )
95 std::string demangled_symbol = Demangle( symbols[ j ] );
96 DALI_LOG_WARNING( " [%02d] %s\n", j, demangled_symbol.c_str() );
100 DALI_LOG_WARNING( "====================================\n" );
105 // TODO: Uncomment when locks held per thread at any given time are 1
106 //DALI_ASSERT_DEBUG( gThreadLockCount == 1 );
108 #endif // LOCK_BACKTRACE_ENABLED
110 if( pthread_mutex_lock( mutex ) )
112 DALI_LOG_ERROR( "Error calling pthread_mutex_lock\n" );
116 void Unlock( pthread_mutex_t* mutex )
118 if( pthread_mutex_unlock( mutex ) )
120 DALI_LOG_ERROR( "Error calling pthread_mutex_unlock\n" );
127 } // namespace Internal