@@ -979,6 +979,25 @@ static void _mutex_before_delete_detach(rt_mutex_t mutex)
979979 * @addtogroup mutex
980980 * @{
981981 */
982+ #define LEGAL_CTRL_FLAGS (RT_MTX_CTRL_FLAG_NO_RECUR | RT_IPC_FLAG_PRIO | RT_IPC_FLAG_FIFO)
983+ static void _mutex_init (rt_mutex_t mutex , rt_uint8_t ctrl_flags )
984+ {
985+ RT_ASSERT (!(LEGAL_CTRL_FLAGS & ~ctrl_flags ));
986+
987+ /* initialize ipc object */
988+ _ipc_object_init (& (mutex -> parent ));
989+
990+ mutex -> owner = RT_NULL ;
991+ mutex -> priority = 0xFF ;
992+ mutex -> hold = 0 ;
993+ mutex -> ceiling_priority = 0xFF ;
994+ mutex -> ctrl_flags = ctrl_flags ;
995+ rt_list_init (& (mutex -> taken_list ));
996+
997+ /* flag can only be RT_IPC_FLAG_PRIO. RT_IPC_FLAG_FIFO cannot solve the unbounded priority inversion problem */
998+ mutex -> parent .parent .flag = RT_IPC_FLAG_PRIO ;
999+ rt_spin_lock_init (& (mutex -> spinlock ));
1000+ }
9821001
9831002/**
9841003 * @brief Initialize a static mutex object.
@@ -995,9 +1014,11 @@ static void _mutex_before_delete_detach(rt_mutex_t mutex)
9951014 *
9961015 * @param name is a pointer to the name that given to the mutex.
9971016 *
998- * @param flag is the mutex flag, which determines the queuing way of how multiple threads wait
999- * when the mutex is not available.
1000- * NOTE: This parameter has been obsoleted. It can be RT_IPC_FLAG_PRIO, RT_IPC_FLAG_FIFO or RT_NULL.
1017+ * @param flag is the mutex flag, which determines specified behaviors:
1018+ * - RT_MTX_CTRL_FLAG_DEFAULT create a mutex with default behavior
1019+ * - RT_MTX_CTRL_FLAG_NO_RECUR create a mutex without recursive taken
1020+ * - [[obsoleted]] RT_IPC_FLAG_PRIO
1021+ * - [[obsoleted]] RT_IPC_FLAG_FIFO
10011022 *
10021023 * @return Return the operation status. When the return value is RT_EOK, the initialization is successful.
10031024 * If the return value is any other values, it represents the initialization failed.
@@ -1006,27 +1027,13 @@ static void _mutex_before_delete_detach(rt_mutex_t mutex)
10061027 */
10071028rt_err_t rt_mutex_init (rt_mutex_t mutex , const char * name , rt_uint8_t flag )
10081029{
1009- /* flag parameter has been obsoleted */
1010- RT_UNUSED (flag );
1011-
10121030 /* parameter check */
10131031 RT_ASSERT (mutex != RT_NULL );
10141032
10151033 /* initialize object */
10161034 rt_object_init (& (mutex -> parent .parent ), RT_Object_Class_Mutex , name );
10171035
1018- /* initialize ipc object */
1019- _ipc_object_init (& (mutex -> parent ));
1020-
1021- mutex -> owner = RT_NULL ;
1022- mutex -> priority = 0xFF ;
1023- mutex -> hold = 0 ;
1024- mutex -> ceiling_priority = 0xFF ;
1025- rt_list_init (& (mutex -> taken_list ));
1026-
1027- /* flag can only be RT_IPC_FLAG_PRIO. RT_IPC_FLAG_FIFO cannot solve the unbounded priority inversion problem */
1028- mutex -> parent .parent .flag = RT_IPC_FLAG_PRIO ;
1029- rt_spin_lock_init (& (mutex -> spinlock ));
1036+ _mutex_init (mutex , flag );
10301037
10311038 return RT_EOK ;
10321039}
@@ -1222,9 +1229,11 @@ RTM_EXPORT(rt_mutex_getprioceiling);
12221229 *
12231230 * @param name is a pointer to the name that given to the mutex.
12241231 *
1225- * @param flag is the mutex flag, which determines the queuing way of how multiple threads wait
1226- * when the mutex is not available.
1227- * NOTE: This parameter has been obsoleted. It can be RT_IPC_FLAG_PRIO, RT_IPC_FLAG_FIFO or RT_NULL.
1232+ * @param flag is the mutex flag, which determines specified behaviors:
1233+ * - RT_MTX_CTRL_FLAG_DEFAULT create a mutex with default behavior
1234+ * - RT_MTX_CTRL_FLAG_NO_RECUR create a mutex without recursive taken
1235+ * - [[obsoleted]] RT_IPC_FLAG_PRIO
1236+ * - [[obsoleted]] RT_IPC_FLAG_FIFO
12281237 *
12291238 * @return Return a pointer to the mutex object. When the return value is RT_NULL, it means the creation failed.
12301239 *
@@ -1234,28 +1243,14 @@ rt_mutex_t rt_mutex_create(const char *name, rt_uint8_t flag)
12341243{
12351244 struct rt_mutex * mutex ;
12361245
1237- /* flag parameter has been obsoleted */
1238- RT_UNUSED (flag );
1239-
12401246 RT_DEBUG_NOT_IN_INTERRUPT ;
12411247
12421248 /* allocate object */
12431249 mutex = (rt_mutex_t )rt_object_allocate (RT_Object_Class_Mutex , name );
12441250 if (mutex == RT_NULL )
12451251 return mutex ;
12461252
1247- /* initialize ipc object */
1248- _ipc_object_init (& (mutex -> parent ));
1249-
1250- mutex -> owner = RT_NULL ;
1251- mutex -> priority = 0xFF ;
1252- mutex -> hold = 0 ;
1253- mutex -> ceiling_priority = 0xFF ;
1254- rt_list_init (& (mutex -> taken_list ));
1255-
1256- /* flag can only be RT_IPC_FLAG_PRIO. RT_IPC_FLAG_FIFO cannot solve the unbounded priority inversion problem */
1257- mutex -> parent .parent .flag = RT_IPC_FLAG_PRIO ;
1258- rt_spin_lock_init (& (mutex -> spinlock ));
1253+ _mutex_init (mutex , flag );
12591254
12601255 return mutex ;
12611256}
@@ -1351,7 +1346,8 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
13511346
13521347 if (mutex -> owner == thread )
13531348 {
1354- if (mutex -> hold < RT_MUTEX_HOLD_MAX )
1349+ if (!(mutex -> ctrl_flags & RT_MTX_CTRL_FLAG_NO_RECUR ) &&
1350+ mutex -> hold < RT_MUTEX_HOLD_MAX )
13551351 {
13561352 /* it's the same thread */
13571353 mutex -> hold ++ ;
0 commit comments