* @brief This function will take a mutex, if the mutex is unavailable, the thread shall wait for * the mutex up to a specified time. * * @note When this function is called, the count value of the mutex->value will decrease 1 until it is equal to 0. * When the mutex->value is 0, it means that the mutex is unavailable. At this time, it will suspend the * thr
| 1325 | * @warning This function can ONLY be called in the thread context. It MUST NOT BE called in interrupt context. |
| 1326 | */ |
| 1327 | static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend_flag) |
| 1328 | { |
| 1329 | struct rt_thread *thread; |
| 1330 | rt_err_t ret; |
| 1331 | |
| 1332 | /* this function must not be used in interrupt even if time = 0 */ |
| 1333 | /* current context checking */ |
| 1334 | RT_DEBUG_SCHEDULER_AVAILABLE(RT_TRUE); |
| 1335 | |
| 1336 | /* parameter check */ |
| 1337 | RT_ASSERT(mutex != RT_NULL); |
| 1338 | RT_ASSERT(rt_object_get_type(&mutex->parent.parent) == RT_Object_Class_Mutex); |
| 1339 | |
| 1340 | /* get current thread */ |
| 1341 | thread = rt_thread_self(); |
| 1342 | |
| 1343 | rt_spin_lock(&(mutex->spinlock)); |
| 1344 | |
| 1345 | RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(mutex->parent.parent))); |
| 1346 | |
| 1347 | LOG_D("mutex_take: current thread %s, hold: %d", |
| 1348 | thread->parent.name, mutex->hold); |
| 1349 | |
| 1350 | /* reset thread error */ |
| 1351 | thread->error = RT_EOK; |
| 1352 | |
| 1353 | if (mutex->owner == thread) |
| 1354 | { |
| 1355 | if (mutex->hold < RT_MUTEX_HOLD_MAX) |
| 1356 | { |
| 1357 | /* it's the same thread */ |
| 1358 | mutex->hold ++; |
| 1359 | } |
| 1360 | else |
| 1361 | { |
| 1362 | rt_spin_unlock(&(mutex->spinlock)); |
| 1363 | return -RT_EFULL; /* value overflowed */ |
| 1364 | } |
| 1365 | } |
| 1366 | else |
| 1367 | { |
| 1368 | /* whether the mutex has owner thread. */ |
| 1369 | if (mutex->owner == RT_NULL) |
| 1370 | { |
| 1371 | /* set mutex owner and original priority */ |
| 1372 | mutex->owner = thread; |
| 1373 | mutex->priority = 0xff; |
| 1374 | mutex->hold = 1; |
| 1375 | |
| 1376 | if (mutex->ceiling_priority != 0xFF) |
| 1377 | { |
| 1378 | /* set the priority of thread to the ceiling priority */ |
| 1379 | if (mutex->ceiling_priority < rt_sched_thread_get_curr_prio(mutex->owner)) |
| 1380 | _thread_update_priority(mutex->owner, mutex->ceiling_priority, suspend_flag); |
| 1381 | } |
| 1382 | |
| 1383 | /* insert mutex to thread's taken object list */ |
| 1384 | rt_list_insert_after(&thread->taken_object_list, &mutex->taken_list); |
no test coverage detected