!12 解决用户态锁在高并发场景下的静态问题

Merge pull request !12 from zhushengle/master
This commit is contained in:
openharmony_ci 2020-09-28 14:24:09 +08:00 committed by Gitee
commit e5ef0f25ba
1 changed files with 22 additions and 29 deletions

View File

@ -465,41 +465,29 @@ STATIC INT32 OsFindAndInsertToHash(FutexNode *node)
return ret;
}
STATIC INT32 OsFutexWaitParmaCheck(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absTime)
STATIC INT32 OsFutexWaitParamCheck(const UINT32 *userVaddr, UINT32 flags, UINT32 absTime)
{
UINTPTR futexKey = (UINTPTR)userVaddr;
UINT32 lockVal;
INT32 ret;
if (OS_INT_ACTIVE) {
return LOS_EINTR;
}
if (flags) {
PRINT_ERR("Futex wait parma check failed! error flags: 0x%x\n", flags);
PRINT_ERR("Futex wait param check failed! error flags: 0x%x\n", flags);
return LOS_EINVAL;
}
if ((futexKey % sizeof(INT32)) || (futexKey < OS_FUTEX_KEY_BASE) || (futexKey >= OS_FUTEX_KEY_MAX)) {
PRINT_ERR("Futex wait parma check failed! error futex key: 0x%x\n", futexKey);
PRINT_ERR("Futex wait param check failed! error futex key: 0x%x\n", futexKey);
return LOS_EINVAL;
}
if (!absTime) {
PRINT_ERR("Futex wait parma check failed! error absTime: %u\n", absTime);
PRINT_ERR("Futex wait param check failed! error absTime: %u\n", absTime);
return LOS_EINVAL;
}
ret = LOS_ArchCopyFromUser(&lockVal, userVaddr, sizeof(UINT32));
if (ret) {
PRINT_ERR("Futex wait parma check failed! copy from user failed!\n");
return LOS_EINVAL;
}
if (lockVal != val) {
return LOS_EBADF;
}
return LOS_OK;
}
@ -542,10 +530,10 @@ STATIC INT32 OsFutexInserTaskToHash(LosTaskCB **taskCB, FutexNode **node, const
return LOS_OK;
}
STATIC INT32 OsFutexWaitTask(const UINT32 timeOut, const UINT32 *userVaddr)
STATIC INT32 OsFutexWaitTask(const UINT32 timeOut, const UINT32 *userVaddr, UINT32 val)
{
INT32 futexRet;
UINT32 intSave;
UINT32 intSave, lockVal;
LosTaskCB *taskCB = NULL;
FutexNode *node = NULL;
UINTPTR futexKey = (UINTPTR)userVaddr;
@ -556,7 +544,19 @@ STATIC INT32 OsFutexWaitTask(const UINT32 timeOut, const UINT32 *userVaddr)
return LOS_EINVAL;
}
if (LOS_ArchCopyFromUser(&lockVal, userVaddr, sizeof(UINT32))) {
PRINT_ERR("Futex wait param check failed! copy from user failed!\n");
futexRet = LOS_EINVAL;
goto EXIT_ERR;
}
if (lockVal != val) {
futexRet = LOS_EBADF;
goto EXIT_ERR;
}
if (OsFutexInserTaskToHash(&taskCB, &node, futexKey)) {
futexRet = LOS_NOK;
goto EXIT_ERR;
}
SCHEDULER_LOCK(intSave);
@ -564,10 +564,6 @@ STATIC INT32 OsFutexWaitTask(const UINT32 timeOut, const UINT32 *userVaddr)
OsPercpuGet()->taskLockCnt++;
LOS_SpinUnlock(&g_taskSpin);
#ifdef LOS_FUTEX_DEBUG
OsFutexHashShow();
#endif
futexRet = OsFutexUnlock(&hashNode->listLock);
if (futexRet) {
OsPercpuGet()->taskLockCnt--;
@ -594,12 +590,9 @@ STATIC INT32 OsFutexWaitTask(const UINT32 timeOut, const UINT32 *userVaddr)
return LOS_OK;
EXIT_ERR:
futexRet = OsFutexUnlock(&hashNode->listLock);
(VOID)OsFutexUnlock(&hashNode->listLock);
EXIT_UNLOCK_ERR:
if (futexRet) {
return futexRet;
}
return LOS_NOK;
return futexRet;
}
INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absTime)
@ -607,7 +600,7 @@ INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absT
INT32 ret;
UINT32 timeOut = LOS_WAIT_FOREVER;
ret = OsFutexWaitParmaCheck(userVaddr, flags, val, absTime);
ret = OsFutexWaitParamCheck(userVaddr, flags, absTime);
if (ret) {
return ret;
}
@ -615,7 +608,7 @@ INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absT
timeOut = OsFutexGetTick(absTime);
}
return OsFutexWaitTask(timeOut, userVaddr);
return OsFutexWaitTask(timeOut, userVaddr, val);
}
/* Check to see if the task to be awakened has timed out