@@ -979,6 +979,25 @@ static void _mutex_before_delete_detach(rt_mutex_t mutex)
979
979
* @addtogroup mutex
980
980
* @{
981
981
*/
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
+ }
982
1001
983
1002
/**
984
1003
* @brief Initialize a static mutex object.
@@ -995,9 +1014,11 @@ static void _mutex_before_delete_detach(rt_mutex_t mutex)
995
1014
*
996
1015
* @param name is a pointer to the name that given to the mutex.
997
1016
*
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
1001
1022
*
1002
1023
* @return Return the operation status. When the return value is RT_EOK, the initialization is successful.
1003
1024
* 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)
1006
1027
*/
1007
1028
rt_err_t rt_mutex_init (rt_mutex_t mutex , const char * name , rt_uint8_t flag )
1008
1029
{
1009
- /* flag parameter has been obsoleted */
1010
- RT_UNUSED (flag );
1011
-
1012
1030
/* parameter check */
1013
1031
RT_ASSERT (mutex != RT_NULL );
1014
1032
1015
1033
/* initialize object */
1016
1034
rt_object_init (& (mutex -> parent .parent ), RT_Object_Class_Mutex , name );
1017
1035
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 );
1030
1037
1031
1038
return RT_EOK ;
1032
1039
}
@@ -1222,9 +1229,11 @@ RTM_EXPORT(rt_mutex_getprioceiling);
1222
1229
*
1223
1230
* @param name is a pointer to the name that given to the mutex.
1224
1231
*
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
1228
1237
*
1229
1238
* @return Return a pointer to the mutex object. When the return value is RT_NULL, it means the creation failed.
1230
1239
*
@@ -1234,28 +1243,14 @@ rt_mutex_t rt_mutex_create(const char *name, rt_uint8_t flag)
1234
1243
{
1235
1244
struct rt_mutex * mutex ;
1236
1245
1237
- /* flag parameter has been obsoleted */
1238
- RT_UNUSED (flag );
1239
-
1240
1246
RT_DEBUG_NOT_IN_INTERRUPT ;
1241
1247
1242
1248
/* allocate object */
1243
1249
mutex = (rt_mutex_t )rt_object_allocate (RT_Object_Class_Mutex , name );
1244
1250
if (mutex == RT_NULL )
1245
1251
return mutex ;
1246
1252
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 );
1259
1254
1260
1255
return mutex ;
1261
1256
}
@@ -1351,7 +1346,8 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend
1351
1346
1352
1347
if (mutex -> owner == thread )
1353
1348
{
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 )
1355
1351
{
1356
1352
/* it's the same thread */
1357
1353
mutex -> hold ++ ;
0 commit comments