更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
Mutex
Mutex 的协作图:

结构体

struct  OsMux
 

类型定义

typedef struct OsMux LosMux
 

函数

UINT32 LOS_MuxInit (LosMux *mutex, const LosMuxAttr *attr)
 Init a mutex. 更多...
 
UINT32 LOS_MuxDestroy (LosMux *mutex)
 Destroy a mutex. 更多...
 
UINT32 LOS_MuxLock (LosMux *mutex, UINT32 timeout)
 Wait to lock a mutex. 更多...
 
UINT32 LOS_MuxTrylock (LosMux *mutex)
 Try wait to lock a mutex. 更多...
 
UINT32 LOS_MuxUnlock (LosMux *mutex)
 Release a mutex. 更多...
 

详细描述

类型定义说明

◆ LosMux

typedef struct OsMux LosMux

Mutex object.

函数说明

◆ LOS_MuxDestroy()

UINT32 LOS_MuxDestroy ( LosMux mutex)

Destroy a mutex.

Description:
This API is used to delete a specified mutex. Return LOS_OK on deleting successfully, return specific error code otherwise.
注意
  • The specific mutex should be created firstly.
  • The mutex can be deleted successfully only if no other tasks pend on it.
参数
mutex[IN] Handle of the mutex to be deleted.
返回值
#LOS_EINVALThe mutex pointer is NULL.
#LOS_EBUSYTasks pended on this mutex.
#LOS_EBADFThe lock has been destroyed or broken.
#LOS_OKThe mutex is successfully deleted.
Dependency:
  • los_mux.h: the header file that contains the API declaration.
参见
LOS_MuxInit

Destroy a mutex.

在文件 los_mux.c289 行定义.

290{
291 UINT32 intSave;
292
293 if (mutex == NULL) {
294 return LOS_EINVAL;
295 }
296
297 SCHEDULER_LOCK(intSave); //保存调度自旋锁
298 if (mutex->magic != OS_MUX_MAGIC) {
299 SCHEDULER_UNLOCK(intSave);//释放调度自旋锁
300 return LOS_EBADF;
301 }
302
303 if (mutex->muxCount != 0) {
304 SCHEDULER_UNLOCK(intSave);//释放调度自旋锁
305 return LOS_EBUSY;
306 }
307
308 (VOID)memset_s(mutex, sizeof(LosMux), 0, sizeof(LosMux));//很简单,全部清0处理.
309 SCHEDULER_UNLOCK(intSave); //释放调度自旋锁
310 return LOS_OK;
311}
struct OsMux LosMux
unsigned int UINT32
Definition: los_typedef.h:57
Definition: los_mux.h:73
UINT32 magic
Definition: los_mux.h:74
UINT16 muxCount
Definition: los_mux.h:79
这是这个函数的调用关系图:

◆ LOS_MuxInit()

UINT32 LOS_MuxInit ( LosMux mutex,
const LosMuxAttr attr 
)

Init a mutex.

Description:
This API is used to Init a mutex. A mutex handle is assigned to muxHandle when the mutex is init successfully. Return LOS_OK on creating successful, return specific error code otherwise.
注意
  • The total number of mutexes is pre-configured. If there are no available mutexes, the mutex creation fails.
参数
mutex[IN] Handle pointer of the successfully init mutex.
attr[IN] The mutex attribute.
返回值
#LOS_EINVALThe mutex pointer is NULL.
#LOS_OKThe mutex is successfully created.
Dependency:
  • los_mux.h: the header file that contains the API declaration.
参见
LOS_MuxDestroy

Init a mutex.

在文件 los_mux.c262 行定义.

263{
264 UINT32 intSave;
265
266 if (mutex == NULL) {
267 return LOS_EINVAL;
268 }
269
270 if (attr == NULL) {
271 (VOID)LOS_MuxAttrInit(&mutex->attr);//属性初始化
272 } else {
273 (VOID)memcpy_s(&mutex->attr, sizeof(LosMuxAttr), attr, sizeof(LosMuxAttr));//把attr 拷贝到 mutex->attr
274 }
275
276 if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) {//检查属性
277 return LOS_EINVAL;
278 }
279
280 SCHEDULER_LOCK(intSave); //拿到调度自旋锁
281 mutex->muxCount = 0; //锁定互斥量的次数
282 mutex->owner = NULL; //谁持有该锁
283 LOS_ListInit(&mutex->muxList); //互斥量双循环链表
284 mutex->magic = OS_MUX_MAGIC; //固定标识,互斥锁的魔法数字
285 SCHEDULER_UNLOCK(intSave); //释放调度自旋锁
286 return LOS_OK;
287}
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
Definition: los_list.h:104
STATIC UINT32 OsCheckMutexAttr(const LosMuxAttr *attr)
检查互斥锁属性是否OK,否则 no ok :|)
Definition: los_mux.c:248
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrInit(LosMuxAttr *attr)
互斥属性初始化
Definition: los_mux.c:97
VOID * owner
Definition: los_mux.h:78
LOS_DL_LIST muxList
Definition: los_mux.h:77
LosMuxAttr attr
Definition: los_mux.h:75
函数调用图:
这是这个函数的调用关系图:

◆ LOS_MuxLock()

UINT32 LOS_MuxLock ( LosMux mutex,
UINT32  timeout 
)

Wait to lock a mutex.

Description:
This API is used to wait for a specified period of time to lock a mutex.
注意
  • The specific mutex should be created firstly.
  • The function fails if the mutex that is waited on is already locked by another thread when the task scheduling is disabled.
  • Do not wait on a mutex during an interrupt.
  • The priority inheritance protocol is supported. If a higher-priority thread is waiting on a mutex, it changes the priority of the thread that owns the mutex to avoid priority inversion.
  • A recursive mutex can be locked more than once by the same thread.
  • Do not call this API in software timer callback.
参数
mutex[IN] Handle of the mutex to be waited on.
timeout[IN] Waiting time. The value range is [0, LOS_WAIT_FOREVER](unit: Tick).
返回值
#LOS_EINVALThe mutex pointer is NULL, The timeout is zero or Lock status error.
#LOS_EINTRThe mutex is being locked during an interrupt.
#LOS_EBUSYTasks pended on this mutex.
#LOS_EBADFThe lock has been destroyed or broken.
#LOS_EDEADLKMutex error check failed or System locked task scheduling.
#LOS_ETIMEDOUTThe mutex waiting times out.
#LOS_OKThe mutex is successfully locked.
Dependency:
  • los_mux.h: the header file that contains the API declaration.
参见
LOS_MuxInit | LOS_MuxUnlock

Wait to lock a mutex.

在文件 los_mux.c437 行定义.

438{
439 LosTaskCB *runTask = NULL;
440 UINT32 intSave;
441 UINT32 ret;
442
443 if (mutex == NULL) {
444 return LOS_EINVAL;
445 }
446
447 if (OS_INT_ACTIVE) {
448 return LOS_EINTR;
449 }
450
451 runTask = (LosTaskCB *)OsCurrTaskGet();//获取当前任务
452 /* DO NOT Call blocking API in system tasks */
453 if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {//不要在内核任务里用mux锁
454 PRINTK("Warning: DO NOT call %s in system tasks.\n", __FUNCTION__);
455 OsBackTrace();//打印task信息
456 }
457
458 SCHEDULER_LOCK(intSave);//调度自旋锁
459 ret = OsMuxLockUnsafe(mutex, timeout);//如果任务没拿到锁,将进入阻塞队列一直等待,直到timeout或者持锁任务释放锁时唤醒它
460 SCHEDULER_UNLOCK(intSave);
461 return ret;
462}
VOID OsBackTrace(VOID)
Kernel backtrace function.
Definition: los_exc.c:1025
UINT32 OsMuxLockUnsafe(LosMux *mutex, UINT32 timeout)
Definition: los_mux.c:398
STATIC INLINE LosTaskCB * OsCurrTaskGet(VOID)
UINT16 taskStatus
函数调用图:

◆ LOS_MuxTrylock()

UINT32 LOS_MuxTrylock ( LosMux mutex)

Try wait to lock a mutex.

Description:
This API is used to wait for a specified period of time to lock a mutex.
注意
  • The specific mutex should be created firstly.
  • The function fails if the mutex that is waited on is already locked by another thread when the task scheduling is disabled.
  • Do not wait on a mutex during an interrupt.
  • The priority inheritance protocol is supported. If a higher-priority thread is waiting on a mutex, it changes the priority of the thread that owns the mutex to avoid priority inversion.
  • A recursive mutex can be locked more than once by the same thread.
  • Do not call this API in software timer callback.
参数
mutex[IN] Handle of the mutex to be waited on.
返回值
#LOS_EINVALThe mutex pointer is NULL or Lock status error.
#LOS_EINTRThe mutex is being locked during an interrupt.
#LOS_EBUSYTasks pended on this mutex.
#LOS_EBADFThe lock has been destroyed or broken.
#LOS_EDEADLKMutex error check failed or System locked task scheduling.
#LOS_ETIMEDOUTThe mutex waiting times out.
#LOS_OKThe mutex is successfully locked.
Dependency:
  • los_mux.h: the header file that contains the API declaration.
参见
LOS_MuxInit | LOS_MuxUnlock

Try wait to lock a mutex.

在文件 los_mux.c464 行定义.

465{
466 LosTaskCB *runTask = NULL;
467 UINT32 intSave;
468 UINT32 ret;
469
470 if (mutex == NULL) {
471 return LOS_EINVAL;
472 }
473
474 if (OS_INT_ACTIVE) {
475 return LOS_EINTR;
476 }
477
478 runTask = (LosTaskCB *)OsCurrTaskGet();//获取当前执行的任务
479 /* DO NOT Call blocking API in system tasks */
480 if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {//系统任务不能
481 PRINTK("Warning: DO NOT call %s in system tasks.\n", __FUNCTION__);
482 OsBackTrace();
483 }
484
485 SCHEDULER_LOCK(intSave);
486 ret = OsMuxTrylockUnsafe(mutex, 0);//timeout = 0,不等待,没拿到锁就算了
487 SCHEDULER_UNLOCK(intSave);
488 return ret;
489}
UINT32 OsMuxTrylockUnsafe(LosMux *mutex, UINT32 timeout)
尝试加锁,
Definition: los_mux.c:417
函数调用图:
这是这个函数的调用关系图:

◆ LOS_MuxUnlock()

UINT32 LOS_MuxUnlock ( LosMux mutex)

Release a mutex.

Description:
This API is used to release a specified mutex.
注意
  • The specific mutex should be created firstly.
  • Do not release a mutex during an interrupt.
  • If a recursive mutex is locked for many times, it must be unlocked for the same times to be released.
参数
mutex[IN] Handle of the mutex to be released.
返回值
#LOS_EINVALThe mutex pointer is NULL, The timeout is zero or Lock status error.
#LOS_EINTRThe mutex is being locked during an interrupt.
#LOS_EBUSYTasks pended on this mutex.
#LOS_EBADFThe lock has been destroyed or broken.
#LOS_EDEADLKMutex error check failed or System locked task scheduling.
#LOS_ETIMEDOUTThe mutex waiting times out.
#LOS_OKThe mutex is successfully locked.
Dependency:
  • los_mux.h: the header file that contains the API declaration.
参见
LOS_MuxInit | LOS_MuxLock

Release a mutex.

在文件 los_mux.c559 行定义.

560{
561 LosTaskCB *runTask = NULL;
562 BOOL needSched = FALSE;
563 UINT32 intSave;
564 UINT32 ret;
565
566 if (mutex == NULL) {
567 return LOS_EINVAL;
568 }
569
570 if (OS_INT_ACTIVE) {
571 return LOS_EINTR;
572 }
573
574 runTask = (LosTaskCB *)OsCurrTaskGet();//获取当前任务
575 /* DO NOT Call blocking API in system tasks */
576 if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {//不能在系统任务里调用,因为很容易让系统任务发生死锁
577 PRINTK("Warning: DO NOT call %s in system tasks.\n", __FUNCTION__);
578 OsBackTrace();
579 }
580
581 SCHEDULER_LOCK(intSave);
582 ret = OsMuxUnlockUnsafe(runTask, mutex, &needSched);
583 SCHEDULER_UNLOCK(intSave);
584 if (needSched == TRUE) {//需要调度的情况
585 LOS_MpSchedule(OS_MP_CPU_ALL);//向所有CPU发送调度指令
586 LOS_Schedule();//发起调度
587 }
588 return ret;
589}
VOID LOS_Schedule(VOID)
Trigger active task scheduling.
Definition: los_sched.c:469
VOID LOS_MpSchedule(UINT32 target)
Definition: los_mp.c:76
UINT32 OsMuxUnlockUnsafe(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched)
Definition: los_mux.c:527
size_t BOOL
Definition: los_typedef.h:88
函数调用图: