@@ -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,9 +1625,21 @@ 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 )
16161629 {
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 )
1638+ {
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 ));
16191645
@@ -1713,9 +1739,47 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
17131739
17141740 return RT_EOK ;
17151741}
1742+
1743+
1744+ /**
1745+ * @brief Release a mutex owned by current thread.
1746+ *
1747+ * @note Resumes first suspended thread if any (requires scheduling).
1748+ * Increases mutex->value if no threads waiting.
1749+ * Must be called by mutex owner with spinlock held.
1750+ *
1751+ * @param mutex Pointer to the mutex object.
1752+ *
1753+ * @return RT_EOK on success, -RT_ERROR if not owner.
1754+ */
1755+ rt_err_t rt_mutex_release (rt_mutex_t mutex )
1756+ {
1757+ return _rt_mutex_release (mutex , RT_FALSE );
1758+ }
17161759RTM_EXPORT (rt_mutex_release );
17171760
17181761
1762+ /**
1763+ * @brief Forcefully release a mutex regardless of ownership or recursive holds.
1764+ *
1765+ * @note This function bypasses all ownership verification and ignores recursive hold counts.
1766+ * It will resume the first suspended thread if available, which may trigger scheduling.
1767+ * If no threads are waiting, the mutex value will be reset.
1768+ *
1769+ * @warning When releasing a mutex not owned by the caller, the original owner thread
1770+ * must have been properly terminated via rt_thread_close and must not be
1771+ * executing any code at all.
1772+ *
1773+ * @param mutex Pointer to the mutex object.
1774+ *
1775+ * @return RT_EOK on success.
1776+ */
1777+ rt_err_t rt_mutex_force_release (rt_mutex_t mutex )
1778+ {
1779+ return _rt_mutex_release (mutex , RT_TRUE );
1780+ }
1781+
1782+
17191783/**
17201784 * @brief This function will set some extra attributions of a mutex object.
17211785 *
@@ -4030,4 +4094,4 @@ RTM_EXPORT(rt_mq_control);
40304094
40314095/**@}*/
40324096#endif /* RT_USING_MESSAGEQUEUE */
4033- /**@}*/
4097+ /**@}*/
0 commit comments