OpenHarmony开发者论坛
标题:
如何在信息量中实现令牌获取的插队?
[打印本页]
作者:
desert
时间:
2024-4-4 21:32
标题:
如何在信息量中实现令牌获取的插队?
比如说在某些特殊情况下,需要让几个特定的线程优先获取令牌(tokens),应该如何实现?
作者:
dragon
时间:
2024-4-5 13:27
标题:
如何在信息量中实现令牌获取的插队?
对于OH轻量系统来说,CMSIS-RTOS2的osSemaphoreAcquire()函数是这样实现的:
osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout)
{
UINT32 uwRet;
if (semaphore_id == NULL) {
return osErrorParameter;
}
if (OS_INT_ACTIVE && (timeout != LOS_NO_WAIT)) {
return osErrorISR;
}
uwRet = LOS_SemPend(((LosSemCB *)semaphore_id)->semID, timeout);
if (uwRet == LOS_OK) {
return osOK;
} else if (uwRet == LOS_ERRNO_SEM_TIMEOUT) {
return osErrorTimeout;
} else if (uwRet == LOS_ERRNO_SEM_INVALID) {
return osErrorParameter;
} else if (uwRet == LOS_ERRNO_SEM_PEND_INTERR) {
return osErrorISR;
} else {
return osErrorResource;
}
}
复制代码
其中的关键函数LOS_SemPend()定义如下:
/*****************************************************************************
Function : LOS_SemPend
Description : Specified semaphore P operation
Input : semHandle --------- semaphore operation handle
: timeout --------- waitting time
Output : None
Return : LOS_OK on success or error code on failure
*****************************************************************************/
LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout)
{
UINT32 intSave;
LosSemCB *semPended = NULL;
UINT32 retErr;
LosTaskCB *runningTask = NULL;
if (semHandle >= (UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) {
OS_RETURN_ERROR(LOS_ERRNO_SEM_INVALID);
}
semPended = GET_SEM(semHandle);
intSave = LOS_IntLock();
retErr = OsSemValidCheck(semPended);
if (retErr) {
goto ERROR_SEM_PEND;
}
if (semPended->semCount > 0) {
semPended->semCount--;
LOS_IntRestore(intSave);
return LOS_OK;
}
if (!timeout) {
retErr = LOS_ERRNO_SEM_UNAVAILABLE;
goto ERROR_SEM_PEND;
}
runningTask = (LosTaskCB *)g_losTask.runTask;
runningTask->taskSem = (VOID *)semPended;
OsTaskWait(&semPended->semList, 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_SEM_TIMEOUT;
goto ERROR_SEM_PEND;
}
return LOS_OK;
ERROR_SEM_PEND:
LOS_IntRestore(intSave);
OS_RETURN_ERROR(retErr);
}
复制代码
其中调用了OsTaskWait:
/**************************************************************************
Function : OsTaskWait
Description : pend the running task in a list
Input : pendingList -- The pending list
taskStatus -- The status need to be converted to
timeout -- Expiry time
Output : None
Return : None
**************************************************************************/
VOID OsTaskWait(LOS_DL_LIST *pendingList, UINT32 taskStatus, UINT32 timeout)
{
LosTaskCB *runTask = NULL;
LOS_DL_LIST *pendObj = NULL;
runTask = g_losTask.runTask;
OsPriqueueDequeue(&runTask->pendList);
runTask->taskStatus &= (~OS_TASK_STATUS_READY);
pendObj = &runTask->pendList;
runTask->taskStatus |= taskStatus;
LOS_ListTailInsert(pendingList, pendObj);
if (timeout != LOS_WAIT_FOREVER) {
runTask->taskStatus |= OS_TASK_STATUS_TIMEOUT;
OsTaskAdd2TimerList((LosTaskCB *)runTask, timeout);
}
}
复制代码
可以看到是排到队尾的。线程调度的时候看线程优先级。
欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/)
Powered by Discuz! X3.5