* @brief Dequeue a thread from suspended list and set it to ready. The 2 are * taken as an atomic operation, so if a thread is returned, it's * resumed by us, not any other threads or async events. This is useful * if a consumer may be resumed by timeout, signals... besides its * producer. * * @param susp_list the list thread dequeued from. RT_NULL if
| 103 | * @return struct rt_thread * RT_NULL if failed, otherwise the thread resumed |
| 104 | */ |
| 105 | struct rt_thread *rt_susp_list_dequeue(rt_list_t *susp_list, rt_err_t thread_error) |
| 106 | { |
| 107 | rt_sched_lock_level_t slvl; |
| 108 | rt_thread_t thread; |
| 109 | rt_err_t error; |
| 110 | |
| 111 | RT_SCHED_DEBUG_IS_UNLOCKED; |
| 112 | RT_ASSERT(susp_list != RT_NULL); |
| 113 | |
| 114 | rt_sched_lock(&slvl); |
| 115 | if (!rt_list_isempty(susp_list)) |
| 116 | { |
| 117 | thread = RT_THREAD_LIST_NODE_ENTRY(susp_list->next); |
| 118 | error = rt_sched_thread_ready(thread); |
| 119 | |
| 120 | if (error) |
| 121 | { |
| 122 | LOG_D("%s [error:%d] failed to resume thread:%p from suspended list", |
| 123 | __func__, error, thread); |
| 124 | |
| 125 | thread = RT_NULL; |
| 126 | } |
| 127 | else |
| 128 | { |
| 129 | /* thread error should not be a negative value */ |
| 130 | if (thread_error >= 0) |
| 131 | { |
| 132 | /* set thread error code to notified resuming thread */ |
| 133 | thread->error = thread_error; |
| 134 | } |
| 135 | } |
| 136 | } |
| 137 | else |
| 138 | { |
| 139 | thread = RT_NULL; |
| 140 | } |
| 141 | rt_sched_unlock(slvl); |
| 142 | |
| 143 | LOG_D("resume thread:%s\n", thread->parent.name); |
| 144 | |
| 145 | return thread; |
| 146 | } |
| 147 | |
| 148 | |
| 149 | /** |
no test coverage detected