11/*
2- * Copyright (c) 2006-2022 , RT-Thread Development Team
2+ * Copyright (c) 2006-2025 , RT-Thread Development Team
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 *
@@ -1575,18 +1575,32 @@ RTM_EXPORT(rt_mutex_trytake);
15751575
15761576
15771577/**
1578- * @brief This function will release a mutex. If there is thread suspended on the mutex, the thread will be resumed.
1579- *
1580- * @note If there are threads suspended on this mutex, the first thread in the list of this mutex object
1581- * will be resumed, and a thread scheduling (rt_schedule) will be executed.
1582- * If no threads are suspended on this mutex, the count value mutex->value of this mutex will increase by 1.
1583- *
1584- * @param mutex is a pointer to a mutex object.
1585- *
1586- * @return Return the operation status. When the return value is RT_EOK, the operation is successful.
1587- * If the return value is any other values, it means that the mutex release failed.
1578+ * @brief Release a mutex, optionally forcing the release even if the current thread is not the owner.
1579+ * If threads are suspended on the mutex, the highest-priority thread will be resumed.
1580+ *
1581+ * @note This function provides two distinct release modes:
1582+ * Standard mode enforces normal ownership rules where only the owning thread
1583+ * may release the mutex. Force mode bypasses ownership checks and directly
1584+ * modifies the hold count to enable release by any thread.
1585+ *
1586+ * In both modes, if threads are suspended on the mutex, the highest priority
1587+ * waiting thread will be resumed, potentially triggering thread scheduling.
1588+ * When no threads are waiting, the mutex owner and hold count are reset.
1589+ *
1590+ * @param mutex Pointer to the mutex object.
1591+ * @param is_force If RT_TRUE, bypass ownership check and force release.
1592+ * If RT_FALSE, enforce standard owner-only release.
1593+ *
1594+ * @return Operation status:
1595+ * RT_EOK: Success.
1596+ * -RT_ERROR: Failed (non-force mode and current thread is not owner).
1597+ *
1598+ * @warning Forced release (is_force=RT_TRUE) should only be used when:
1599+ * The caller is not the mutex owner and the original owner thread
1600+ * is guaranteed to be closed (rt_thread_close) and no longer executing any code,
1601+ * or the caller is the current mutex owner.
15881602 */
1589- rt_err_t rt_mutex_release (rt_mutex_t mutex )
1603+ static rt_err_t _rt_mutex_release (rt_mutex_t mutex , rt_bool_t is_force )
15901604{
15911605 rt_sched_lock_level_t slvl ;
15921606 struct rt_thread * thread ;
@@ -1611,12 +1625,23 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
16111625
16121626 RT_OBJECT_HOOK_CALL (rt_object_put_hook , (& (mutex -> parent .parent )));
16131627
1614- /* mutex only can be released by owner */
1615- if (thread != mutex -> owner )
1628+ if (is_force )
1629+ {
1630+ /*
1631+ * Force release mode:
1632+ * Bypass ownership check and prepare for release by
1633+ * setting hold count to 1 before decrement
1634+ */
1635+ mutex -> hold = 1 ;
1636+ }
1637+ else if (thread != mutex -> owner )
16161638 {
1639+ /*
1640+ * Standard release mode:
1641+ * Reject non-owner thread's release attempt
1642+ */
16171643 thread -> error = - RT_ERROR ;
16181644 rt_spin_unlock (& (mutex -> spinlock ));
1619-
16201645 return - RT_ERROR ;
16211646 }
16221647
@@ -1713,9 +1738,47 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
17131738
17141739 return RT_EOK ;
17151740}
1741+
1742+
1743+ /**
1744+ * @brief Release a mutex owned by current thread.
1745+ *
1746+ * @note Resumes first suspended thread if any (requires scheduling).
1747+ * Increases mutex->value if no threads waiting.
1748+ * Must be called by mutex owner with spinlock held.
1749+ *
1750+ * @param mutex Pointer to the mutex object.
1751+ *
1752+ * @return RT_EOK on success, -RT_ERROR if not owner.
1753+ */
1754+ rt_err_t rt_mutex_release (rt_mutex_t mutex )
1755+ {
1756+ return _rt_mutex_release (mutex , RT_FALSE );
1757+ }
17161758RTM_EXPORT (rt_mutex_release );
17171759
17181760
1761+ /**
1762+ * @brief Forcefully release a mutex regardless of ownership or recursive holds.
1763+ *
1764+ * @note This function bypasses all ownership verification and ignores recursive hold counts.
1765+ * It will resume the first suspended thread if available, which may trigger scheduling.
1766+ * If no threads are waiting, the mutex value will be reset.
1767+ *
1768+ * @warning When releasing a mutex not owned by the caller, the original owner thread
1769+ * must have been properly terminated via rt_thread_close and must not be
1770+ * executing any code at all.
1771+ *
1772+ * @param mutex Pointer to the mutex object.
1773+ *
1774+ * @return RT_EOK on success.
1775+ */
1776+ rt_err_t rt_mutex_force_release (rt_mutex_t mutex )
1777+ {
1778+ return _rt_mutex_release (mutex , RT_TRUE );
1779+ }
1780+
1781+
17191782/**
17201783 * @brief This function will set some extra attributions of a mutex object.
17211784 *
@@ -2043,6 +2106,7 @@ rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set)
20432106 need_schedule = RT_TRUE ;
20442107 }
20452108 }
2109+
20462110 if (need_clear_set )
20472111 {
20482112 event -> set &= ~need_clear_set ;
@@ -3514,6 +3578,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq,
35143578 msg -> next = node ;
35153579 break ;
35163580 }
3581+
35173582 if (node -> next == RT_NULL )
35183583 {
35193584 if (node != msg )
@@ -4031,3 +4096,4 @@ RTM_EXPORT(rt_mq_control);
40314096/**@}*/
40324097#endif /* RT_USING_MESSAGEQUEUE */
40334098/**@}*/
4099+
0 commit comments