@@ -1578,15 +1578,15 @@ RTM_EXPORT(rt_mutex_trytake);
15781578 * @brief This function will release a mutex. If there is thread suspended on the mutex, the thread will be resumed.
15791579 *
15801580 * @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 .
1581+ * will be resumed.
15821582 * If no threads are suspended on this mutex, the count value mutex->value of this mutex will increase by 1.
1583+ * This operation requires mutex->spinlock to be held.
15831584 *
15841585 * @param mutex is a pointer to a mutex object.
15851586 *
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.
1587+ * @return Return RT_TRUE if scheduling is needed, RT_FALSE otherwise.
15881588 */
1589- rt_err_t rt_mutex_release (rt_mutex_t mutex )
1589+ static rt_bool_t _rt_mutex_release (rt_mutex_t mutex )
15901590{
15911591 rt_sched_lock_level_t slvl ;
15921592 struct rt_thread * thread ;
@@ -1601,25 +1601,14 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
16011601 /* only thread could release mutex because we need test the ownership */
16021602 RT_DEBUG_IN_THREAD_CONTEXT ;
16031603
1604- /* get current thread */
1605- thread = rt_thread_self () ;
1604+ /* get the current owner thread of the mutex */
1605+ thread = mutex -> owner ;
16061606
1607- rt_spin_lock (& (mutex -> spinlock ));
1608-
1609- LOG_D ("mutex_release:current thread %s, hold: %d" ,
1610- thread -> parent .name , mutex -> hold );
1607+ LOG_D ("mutex_release: mutex owner thread %s, hold count: %d" ,
1608+ thread -> parent .name , mutex -> hold );
16111609
16121610 RT_OBJECT_HOOK_CALL (rt_object_put_hook , (& (mutex -> parent .parent )));
16131611
1614- /* mutex only can be released by owner */
1615- if (thread != mutex -> owner )
1616- {
1617- thread -> error = - RT_ERROR ;
1618- rt_spin_unlock (& (mutex -> spinlock ));
1619-
1620- return - RT_ERROR ;
1621- }
1622-
16231612 /* decrease hold */
16241613 mutex -> hold -- ;
16251614 /* if no hold */
@@ -1705,17 +1694,113 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex)
17051694 }
17061695 }
17071696
1697+ return need_schedule ;
1698+ }
1699+
1700+
1701+ /**
1702+ * @brief Release a mutex owned by current thread.
1703+ *
1704+ * @note Resumes first suspended thread if any (requires scheduling).
1705+ * Increases mutex->value if no threads waiting.
1706+ * Must be called by mutex owner with spinlock held.
1707+ *
1708+ * @param mutex Pointer to the mutex object.
1709+ *
1710+ * @return RT_EOK on success, -RT_ERROR if not owner.
1711+ */
1712+ rt_err_t rt_mutex_release (rt_mutex_t mutex )
1713+ {
1714+ struct rt_thread * thread ;
1715+ rt_bool_t need_schedule ;
1716+
1717+ /* parameter check */
1718+ RT_ASSERT (mutex != RT_NULL );
1719+ RT_ASSERT (rt_object_get_type (& mutex -> parent .parent ) == RT_Object_Class_Mutex );
1720+
1721+ need_schedule = RT_FALSE ;
1722+
1723+ /* only thread could release mutex because we need test the ownership */
1724+ RT_DEBUG_IN_THREAD_CONTEXT ;
1725+
1726+ /* get current thread */
1727+ thread = rt_thread_self ();
1728+
1729+ rt_spin_lock (& (mutex -> spinlock ));
1730+
1731+ if (thread != mutex -> owner )
1732+ {
1733+ thread -> error = - RT_ERROR ;
1734+ rt_spin_unlock (& (mutex -> spinlock ));
1735+
1736+ return - RT_ERROR ;
1737+ }
1738+
1739+ need_schedule = _rt_mutex_release (mutex );
1740+
17081741 rt_spin_unlock (& (mutex -> spinlock ));
17091742
17101743 /* perform a schedule */
17111744 if (need_schedule == RT_TRUE )
1745+ {
17121746 rt_schedule ();
1747+ }
17131748
17141749 return RT_EOK ;
17151750}
17161751RTM_EXPORT (rt_mutex_release );
17171752
17181753
1754+ /**
1755+ * @brief Forcefully release a mutex (Internal API).
1756+ *
1757+ * @warning This is an internal function that bypasses normal ownership checks.
1758+ * When called by a thread different from the mutex owner:
1759+ * The owner thread MUST have been closed (rt_thread_close).
1760+ * The owner thread MUST be completely off CPU.
1761+ * Violating these conditions will cause undefined behavior.
1762+ *
1763+ * @note Key differences from rt_mutex_release():
1764+ * Ownership check is skipped (caller can be non-owner).
1765+ * Forces hold count to 1 before release (handles recursive locks).
1766+ * Requires manual validation that owner thread is closed and off CPU
1767+ * when caller is not the owner.
1768+ *
1769+ * @param mutex Pointer to the mutex object to be force-released.
1770+ *
1771+ * @return Operation status (RT_EOK on success, -RT_ERROR on failure).
1772+ */
1773+ rt_err_t rt_mutex_force_release (rt_mutex_t mutex )
1774+ {
1775+ rt_bool_t need_schedule ;
1776+
1777+ /* parameter check */
1778+ RT_ASSERT (mutex != RT_NULL );
1779+ RT_ASSERT (rt_object_get_type (& mutex -> parent .parent ) == RT_Object_Class_Mutex );
1780+
1781+ need_schedule = RT_FALSE ;
1782+
1783+ /* only thread could release mutex because we need test the ownership */
1784+ RT_DEBUG_IN_THREAD_CONTEXT ;
1785+
1786+ rt_spin_lock (& mutex -> spinlock );
1787+
1788+ /* Force set hold=1 to handle recursive mutex */
1789+ mutex -> hold = 1 ;
1790+ need_schedule = _rt_mutex_release (mutex );
1791+
1792+ rt_spin_unlock (& mutex -> spinlock );
1793+
1794+ /* perform a schedule */
1795+ if (need_schedule == RT_TRUE )
1796+ {
1797+ rt_schedule ();
1798+ }
1799+
1800+ return RT_EOK ;
1801+ }
1802+
1803+
17191804/**
17201805 * @brief This function will set some extra attributions of a mutex object.
17211806 *
0 commit comments