OpenHarmony开发者论坛
标题:
关于信号量和互斥锁如何运作的两个问题
[打印本页]
作者:
hentaiplus
时间:
2024-4-3 20:57
标题:
关于信号量和互斥锁如何运作的两个问题
1、互斥锁和信号量都通过“许可证”来控制线程对共享资源的访问,书中直接使用了API,那么线程获取“许可证”这一过程过程在它的源码中是怎么实现的呢
2、书中提到互斥锁和信号量的本质是令牌的容器,那么在代码层面上互斥锁和信号量的表现形式是什么呢
作者:
dragon
时间:
2024-4-4 20:50
标题:
关于信号量和互斥锁如何运作的两个问题
kernel\liteos_m\kal\cmsis\cmsis_liteos2.c:
osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout)
{
UINT32 uwRet;
if (mutex_id == NULL) {
return osErrorParameter;
}
if (OS_INT_ACTIVE && (timeout != LOS_NO_WAIT)) {
timeout = 0;
}
uwRet = LOS_MuxPend(((LosMuxCB *)mutex_id)->muxID, timeout);
if (uwRet == LOS_OK) {
return osOK;
} else if (uwRet == LOS_ERRNO_MUX_TIMEOUT) {
return osErrorTimeout;
} else if (uwRet == LOS_ERRNO_MUX_INVALID) {
return osErrorParameter;
} else {
return osErrorResource;
}
}
复制代码
osStatus_t osMutexRelease(osMutexId_t mutex_id)
{
UINT32 uwRet;
if (mutex_id == NULL) {
return osErrorParameter;
}
uwRet = LOS_MuxPost(((LosMuxCB *)mutex_id)->muxID);
if (uwRet == LOS_OK) {
return osOK;
} else {
return osErrorResource;
}
}
复制代码
kernel\liteos_m\kernel\src\los_mux.c:
/*****************************************************************************
Function : LOS_MuxPend
Description : Specify the mutex P operation
Input : muxHandle ------ Mutex operation handleone
: timeOut ------- waiting time
Output : None
Return : LOS_OK on success ,or error code on failure
*****************************************************************************/
LITE_OS_SEC_TEXT UINT32 LOS_MuxPend(UINT32 muxHandle, UINT32 timeout)
{
UINT32 intSave;
LosMuxCB *muxPended = NULL;
UINT32 retErr;
LosTaskCB *runningTask = NULL;
if (muxHandle >= (UINT32)LOSCFG_BASE_IPC_MUX_LIMIT) {
OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID);
}
muxPended = GET_MUX(muxHandle);
intSave = LOS_IntLock();
retErr = OsMuxValidCheck(muxPended);
if (retErr) {
goto ERROR_MUX_PEND;
}
runningTask = (LosTaskCB *)g_losTask.runTask;
if (muxPended->muxCount == 0) {
muxPended->muxCount++;
muxPended->owner = runningTask;
muxPended->priority = runningTask->priority;
LOS_IntRestore(intSave);
return LOS_OK;
}
if (muxPended->owner == runningTask) {
muxPended->muxCount++;
LOS_IntRestore(intSave);
return LOS_OK;
}
if (!timeout) {
retErr = LOS_ERRNO_MUX_UNAVAILABLE;
goto ERROR_MUX_PEND;
}
runningTask->taskMux = (VOID *)muxPended;
if (muxPended->owner->priority > runningTask->priority) {
OsTaskPriModify(muxPended->owner, runningTask->priority);
}
OsTaskWait(&muxPended->muxList, OS_TASK_STATUS_PEND, timeout);
LOS_IntRestore(intSave);
LOS_Schedule();
if (runningTask->taskStatus & OS_TASK_STATUS_TIMEOUT) {
intSave = LOS_IntLock();
runningTask->taskStatus &= (~OS_TASK_STATUS_TIMEOUT);
retErr = LOS_ERRNO_MUX_TIMEOUT;
goto ERROR_MUX_PEND;
}
return LOS_OK;
ERROR_MUX_PEND:
LOS_IntRestore(intSave);
OS_RETURN_ERROR(retErr);
}
复制代码
/*****************************************************************************
Function : LOS_MuxPost
Description : Specify the mutex V operation,
Input : muxHandle ------ Mutex operation handle
Output : None
Return : LOS_OK on success ,or error code on failure
*****************************************************************************/
LITE_OS_SEC_TEXT UINT32 LOS_MuxPost(UINT32 muxHandle)
{
UINT32 intSave;
LosMuxCB *muxPosted = GET_MUX(muxHandle);
LosTaskCB *resumedTask = NULL;
LosTaskCB *runningTask = NULL;
intSave = LOS_IntLock();
if ((muxHandle >= (UINT32)LOSCFG_BASE_IPC_MUX_LIMIT) ||
(muxPosted->muxStat == OS_MUX_UNUSED)) {
LOS_IntRestore(intSave);
OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID);
}
runningTask = (LosTaskCB *)g_losTask.runTask;
if ((muxPosted->muxCount == 0) || (muxPosted->owner != runningTask)) {
LOS_IntRestore(intSave);
OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID);
}
if (--(muxPosted->muxCount) != 0) {
LOS_IntRestore(intSave);
return LOS_OK;
}
if ((muxPosted->owner->priority) != muxPosted->priority) {
OsTaskPriModify(muxPosted->owner, muxPosted->priority);
}
if (!LOS_ListEmpty(&muxPosted->muxList)) {
resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(muxPosted->muxList)));
muxPosted->muxCount = 1;
muxPosted->owner = resumedTask;
muxPosted->priority = resumedTask->priority;
resumedTask->taskMux = NULL;
OsTaskWake(resumedTask, OS_TASK_STATUS_PEND);
LOS_IntRestore(intSave);
LOS_Schedule();
} else {
LOS_IntRestore(intSave);
}
return LOS_OK;
}
复制代码
OH是开源的,可以自己追踪函数调用。
欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/)
Powered by Discuz! X3.5