+/* check condition **********************************************************/
+#define TDM_RETURN_IF_FAIL(cond) { \
+ if (!(cond)) { \
+ TDM_ERR("'%s' failed", #cond); \
+ return; \
+ } \
+}
+#define TDM_RETURN_VAL_IF_FAIL(cond, val) { \
+ if (!(cond)) { \
+ TDM_ERR("'%s' failed", #cond); \
+ return val; \
+ } \
+}
+#define TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(cond, error_v, val) { \
+ if (!(cond)) { \
+ TDM_ERR("'%s' failed", #cond); \
+ ret = error_v; \
+ if (error) *error = ret; \
+ return val; \
+ } \
+}
+#define TDM_WARNING_IF_FAIL(cond) { \
+ if (!(cond)) \
+ TDM_WRN("'%s' failed", #cond); \
+}
+#define TDM_GOTO_IF_FAIL(cond, dst) { \
+ if (!(cond)) { \
+ TDM_ERR("'%s' failed", #cond); \
+ goto dst; \
+ } \
+}
+#define TDM_EXIT_IF_FAIL(cond) { \
+ if (!(cond)) { \
+ TDM_ERR("'%s' failed", #cond); \
+ exit(0); \
+ } \
+}
+#define TDM_DBG_RETURN_IF_FAIL(cond) { \
+ if (!(cond)) { \
+ TDM_SNPRINTF(reply, len, "[%s %d] '%s' failed\n", __func__, __LINE__, #cond); \
+ return; \
+ } \
+}
+#define TDM_DBG_RETURN_VAL_IF_FAIL(cond, val) { \
+ if (!(cond)) { \
+ TDM_SNPRINTF(reply, len, "[%s %d] '%s' failed\n", __func__, __LINE__, #cond); \
+ return val; \
+ } \
+}
+#define TDM_DBG_GOTO_IF_FAIL(cond, dst) { \
+ if (!(cond)) { \
+ TDM_SNPRINTF(reply, len, "[%s %d] '%s' failed\n", __func__, __LINE__, #cond); \
+ goto dst; \
+ } \
+}
+
+/* trace ********************************************************************/
+#ifdef HAVE_TTRACE
+#include <ttrace.h>
+#define TDM_TRACE_BEGIN(fmt, ...) traceBegin(TTRACE_TAG_GRAPHICS, fmt, ##__VA_ARGS__)
+#define TDM_TRACE_END() traceEnd(TTRACE_TAG_GRAPHICS)
+#define TDM_TRACE_ASYNC_BEGIN(key, name,...) traceAsyncBegin(TTRACE_TAG_GRAPHICS, key, name, ##__VA_ARGS__)
+#define TDM_TRACE_ASYNC_END(key, name,...) traceAsyncEnd(TTRACE_TAG_GRAPHICS, key, name, ##__VA_ARGS__)
+#define TDM_TRACE_COUNT(count, fmt, ...) traceCounter(TTRACE_TAG_GRAPHICS, count, fmt, ##__VA_ARGS__)
+#define TDM_TRACE_MARK(fmt, ...) traceMark(TTRACE_TAG_GRAPHICS, fmt, ##__VA_ARGS__)
+#else
+#define TDM_TRACE_BEGIN(fmt, ...)
+#define TDM_TRACE_END()
+#define TDM_TRACE_ASYNC_BEGIN(key, name,...)
+#define TDM_TRACE_ASYNC_END(key, name,...)
+#define TDM_TRACE_COUNT(count, fmt, ...)
+#define TDM_TRACE_MARK(fmt, ...)
+#endif
+
+/* display mutex ************************************************************/
+extern pthread_mutex_t tdm_mutex_check_lock;
+extern int tdm_mutex_locked;
+extern const char *tdm_mutex_lock_func;
+extern int tdm_mutex_lock_line;
+extern const char *tdm_mutex_unlock_func;
+extern int tdm_mutex_unlock_line;
+extern int tdm_debug_module;
+
+#define _pthread_mutex_lock(l) \
+ do { \
+ if (tdm_debug_module & TDM_DEBUG_MUTEX) \
+ TDM_INFO("mutex lock"); \
+ pthread_mutex_lock(l); \
+ pthread_mutex_lock(&tdm_mutex_check_lock); \
+ tdm_mutex_locked = 1; \
+ tdm_mutex_lock_func = __FUNCTION__; \
+ tdm_mutex_lock_line = __LINE__; \
+ tdm_mutex_unlock_func = NULL; \
+ tdm_mutex_unlock_line = 0; \
+ pthread_mutex_unlock(&tdm_mutex_check_lock); \
+ } while (0)
+
+#define _pthread_mutex_unlock(l) \
+ do { \
+ if (tdm_debug_module & TDM_DEBUG_MUTEX) \
+ TDM_INFO("mutex unlock"); \
+ pthread_mutex_lock(&tdm_mutex_check_lock); \
+ tdm_mutex_locked = 0; \
+ tdm_mutex_lock_func = NULL; \
+ tdm_mutex_lock_line = 0; \
+ tdm_mutex_unlock_func = __FUNCTION__; \
+ tdm_mutex_unlock_line = __LINE__; \
+ pthread_mutex_unlock(&tdm_mutex_check_lock); \
+ pthread_mutex_unlock(l); \
+ } while (0)
+
+static inline int TDM_MUTEX_IS_LOCKED(void)