| 17 | #include "lwp_internal.h" |
| 18 | |
| 19 | static rt_err_t _mutex_take_safe(rt_mutex_t mtx, rt_int32_t timeout, int flags) |
| 20 | { |
| 21 | LWP_DEF_RETURN_CODE(rc); |
| 22 | int retry; |
| 23 | rt_int32_t effect_timeout; |
| 24 | |
| 25 | #ifdef LWP_DEBUG |
| 26 | rt_thread_t thread = rt_thread_self(); |
| 27 | #endif |
| 28 | |
| 29 | if (mtx) |
| 30 | { |
| 31 | effect_timeout = timeout; |
| 32 | #if DBG_LVL == DBG_LOG && defined(LWP_DEBUG) |
| 33 | int exception; |
| 34 | rt_list_t *node = RT_NULL; |
| 35 | struct rt_mutex *tak_obj = RT_NULL; |
| 36 | if (!rt_list_isempty(&(thread->taken_object_list)) && timeout == RT_WAITING_FOREVER) |
| 37 | { |
| 38 | exception = 1; |
| 39 | effect_timeout = 0; |
| 40 | } |
| 41 | else |
| 42 | { |
| 43 | exception = 0; |
| 44 | } |
| 45 | #endif /* DBG_LOG && defined(LWP_DEBUG) */ |
| 46 | |
| 47 | do { |
| 48 | retry = 0; |
| 49 | if (flags & LWP_MTX_FLAGS_INTR) |
| 50 | rc = rt_mutex_take_interruptible(mtx, effect_timeout); |
| 51 | else |
| 52 | rc = rt_mutex_take_killable(mtx, effect_timeout); |
| 53 | |
| 54 | #ifdef LWP_DEBUG |
| 55 | if (rc == RT_EOK) |
| 56 | { |
| 57 | if (!(flags & LWP_MTX_FALGS_NESTED) && rt_mutex_get_hold(mtx) > 1) |
| 58 | { |
| 59 | LOG_W("Already hold the lock"); |
| 60 | rt_backtrace(); |
| 61 | } |
| 62 | } |
| 63 | else if (rc == -RT_ETIMEOUT) |
| 64 | { |
| 65 | #if DBG_LVL == DBG_LOG |
| 66 | if (exception) |
| 67 | { |
| 68 | rt_list_for_each(node, &(thread->taken_object_list)) |
| 69 | { |
| 70 | tak_obj = rt_list_entry(node, struct rt_mutex, taken_list); |
| 71 | if (rt_mutex_get_owner(tak_obj)->stat & RT_THREAD_SUSPEND_MASK) |
| 72 | LOG_D("Potential dead lock - Taken: %s, Try take: %s", |
| 73 | tak_obj->parent.parent.name, mtx->parent.parent.name); |
| 74 | } |
| 75 | rt_backtrace(); |
| 76 | retry = 1; |
no test coverage detected