• Lv0
    粉丝0

积分6 / 贡献0

提问3答案被采纳0文章0

关于信号量和互斥锁如何运作的两个问题

hentaiplus 来自手机 显示全部楼层 发表于 2024-4-3 20:57:13
1、互斥锁和信号量都通过“许可证”来控制线程对共享资源的访问,书中直接使用了API,那么线程获取“许可证”这一过程过程在它的源码中是怎么实现的呢
2、书中提到互斥锁和信号量的本质是令牌的容器,那么在代码层面上互斥锁和信号量的表现形式是什么呢

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

精彩评论1

dragon

沙发 发表于 2024-4-4 20:50:44

关于信号量和互斥锁如何运作的两个问题

kernel\liteos_m\kal\cmsis\cmsis_liteos2.c:

  1. osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout)
  2. {
  3.     UINT32 uwRet;

  4.     if (mutex_id == NULL) {
  5.         return osErrorParameter;
  6.     }

  7.     if (OS_INT_ACTIVE && (timeout != LOS_NO_WAIT)) {
  8.         timeout = 0;
  9.     }

  10.     uwRet = LOS_MuxPend(((LosMuxCB *)mutex_id)->muxID, timeout);
  11.     if (uwRet == LOS_OK) {
  12.         return osOK;
  13.     } else if (uwRet == LOS_ERRNO_MUX_TIMEOUT) {
  14.         return osErrorTimeout;
  15.     } else if (uwRet == LOS_ERRNO_MUX_INVALID) {
  16.         return osErrorParameter;
  17.     } else {
  18.         return osErrorResource;
  19.     }
  20. }
复制代码
  1. osStatus_t osMutexRelease(osMutexId_t mutex_id)
  2. {
  3.     UINT32 uwRet;

  4.     if (mutex_id == NULL) {
  5.         return osErrorParameter;
  6.     }

  7.     uwRet = LOS_MuxPost(((LosMuxCB *)mutex_id)->muxID);
  8.     if (uwRet == LOS_OK) {
  9.         return osOK;
  10.     } else {
  11.         return osErrorResource;
  12.     }
  13. }
复制代码

kernel\liteos_m\kernel\src\los_mux.c:
  1. /*****************************************************************************
  2. Function     : LOS_MuxPend
  3. Description  : Specify the mutex P operation
  4. Input        : muxHandle ------ Mutex operation handleone
  5.               : timeOut   ------- waiting time
  6. Output       : None
  7. Return       : LOS_OK on success ,or error code on failure
  8. *****************************************************************************/
  9. LITE_OS_SEC_TEXT UINT32 LOS_MuxPend(UINT32 muxHandle, UINT32 timeout)
  10. {
  11.     UINT32 intSave;
  12.     LosMuxCB *muxPended = NULL;
  13.     UINT32 retErr;
  14.     LosTaskCB *runningTask = NULL;

  15.     if (muxHandle >= (UINT32)LOSCFG_BASE_IPC_MUX_LIMIT) {
  16.         OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID);
  17.     }

  18.     muxPended = GET_MUX(muxHandle);
  19.     intSave = LOS_IntLock();
  20.     retErr = OsMuxValidCheck(muxPended);
  21.     if (retErr) {
  22.         goto ERROR_MUX_PEND;
  23.     }

  24.     runningTask = (LosTaskCB *)g_losTask.runTask;
  25.     if (muxPended->muxCount == 0) {
  26.         muxPended->muxCount++;
  27.         muxPended->owner = runningTask;
  28.         muxPended->priority = runningTask->priority;
  29.         LOS_IntRestore(intSave);
  30.         return LOS_OK;
  31.     }

  32.     if (muxPended->owner == runningTask) {
  33.         muxPended->muxCount++;
  34.         LOS_IntRestore(intSave);
  35.         return LOS_OK;
  36.     }

  37.     if (!timeout) {
  38.         retErr = LOS_ERRNO_MUX_UNAVAILABLE;
  39.         goto ERROR_MUX_PEND;
  40.     }

  41.     runningTask->taskMux = (VOID *)muxPended;

  42.     if (muxPended->owner->priority > runningTask->priority) {
  43.         OsTaskPriModify(muxPended->owner, runningTask->priority);
  44.     }

  45.     OsTaskWait(&muxPended->muxList, OS_TASK_STATUS_PEND, timeout);

  46.     LOS_IntRestore(intSave);
  47.     LOS_Schedule();

  48.     if (runningTask->taskStatus & OS_TASK_STATUS_TIMEOUT) {
  49.         intSave = LOS_IntLock();
  50.         runningTask->taskStatus &= (~OS_TASK_STATUS_TIMEOUT);
  51.         retErr = LOS_ERRNO_MUX_TIMEOUT;
  52.         goto ERROR_MUX_PEND;
  53.     }

  54.     return LOS_OK;

  55. ERROR_MUX_PEND:
  56.     LOS_IntRestore(intSave);
  57.     OS_RETURN_ERROR(retErr);
  58. }
复制代码
  1. /*****************************************************************************
  2. Function     : LOS_MuxPost
  3. Description  : Specify the mutex V operation,
  4. Input        : muxHandle ------ Mutex operation handle
  5. Output       : None
  6. Return       : LOS_OK on success ,or error code on failure
  7. *****************************************************************************/
  8. LITE_OS_SEC_TEXT UINT32 LOS_MuxPost(UINT32 muxHandle)
  9. {
  10.     UINT32 intSave;
  11.     LosMuxCB *muxPosted = GET_MUX(muxHandle);
  12.     LosTaskCB *resumedTask = NULL;
  13.     LosTaskCB *runningTask = NULL;

  14.     intSave = LOS_IntLock();

  15.     if ((muxHandle >= (UINT32)LOSCFG_BASE_IPC_MUX_LIMIT) ||
  16.         (muxPosted->muxStat == OS_MUX_UNUSED)) {
  17.         LOS_IntRestore(intSave);
  18.         OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID);
  19.     }

  20.     runningTask = (LosTaskCB *)g_losTask.runTask;
  21.     if ((muxPosted->muxCount == 0) || (muxPosted->owner != runningTask)) {
  22.         LOS_IntRestore(intSave);
  23.         OS_RETURN_ERROR(LOS_ERRNO_MUX_INVALID);
  24.     }

  25.     if (--(muxPosted->muxCount) != 0) {
  26.         LOS_IntRestore(intSave);
  27.         return LOS_OK;
  28.     }

  29.     if ((muxPosted->owner->priority) != muxPosted->priority) {
  30.         OsTaskPriModify(muxPosted->owner, muxPosted->priority);
  31.     }

  32.     if (!LOS_ListEmpty(&muxPosted->muxList)) {
  33.         resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(muxPosted->muxList)));

  34.         muxPosted->muxCount = 1;
  35.         muxPosted->owner = resumedTask;
  36.         muxPosted->priority = resumedTask->priority;
  37.         resumedTask->taskMux = NULL;

  38.         OsTaskWake(resumedTask, OS_TASK_STATUS_PEND);

  39.         LOS_IntRestore(intSave);
  40.         LOS_Schedule();
  41.     } else {
  42.         LOS_IntRestore(intSave);
  43.     }

  44.     return LOS_OK;
  45. }
复制代码

OH是开源的,可以自己追踪函数调用。

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部