| 78 | |
| 79 | #ifdef RT_USING_MUTEX |
| 80 | static void _thread_detach_from_mutex(rt_thread_t thread) |
| 81 | { |
| 82 | rt_list_t *node; |
| 83 | rt_list_t *tmp_list; |
| 84 | struct rt_mutex *mutex; |
| 85 | rt_base_t level; |
| 86 | |
| 87 | level = rt_spin_lock_irqsave(&thread->spinlock); |
| 88 | |
| 89 | /* check if thread is waiting on a mutex */ |
| 90 | if ((thread->pending_object) && |
| 91 | (rt_object_get_type(thread->pending_object) == RT_Object_Class_Mutex)) |
| 92 | { |
| 93 | /* remove it from its waiting list */ |
| 94 | struct rt_mutex *mutex = (struct rt_mutex*)thread->pending_object; |
| 95 | rt_mutex_drop_thread(mutex, thread); |
| 96 | thread->pending_object = RT_NULL; |
| 97 | } |
| 98 | |
| 99 | /* free taken mutex after detaching from waiting, so we don't lost mutex just got */ |
| 100 | rt_list_for_each_safe(node, tmp_list, &(thread->taken_object_list)) |
| 101 | { |
| 102 | mutex = rt_list_entry(node, struct rt_mutex, taken_list); |
| 103 | LOG_D("Thread [%s] exits while holding mutex [%s].\n", thread->parent.name, mutex->parent.parent.name); |
| 104 | /* recursively take */ |
| 105 | mutex->hold = 1; |
| 106 | rt_mutex_release(mutex); |
| 107 | } |
| 108 | |
| 109 | rt_spin_unlock_irqrestore(&thread->spinlock, level); |
| 110 | } |
| 111 | |
| 112 | #else |
| 113 |
no test coverage detected