提交 c884ada0 编写于 作者: 星e雨's avatar 星e雨

Solve the static problem of user mode locking under high concurrency.

上级 aa407d37
...@@ -465,41 +465,29 @@ STATIC INT32 OsFindAndInsertToHash(FutexNode *node) ...@@ -465,41 +465,29 @@ STATIC INT32 OsFindAndInsertToHash(FutexNode *node)
return ret; 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; UINTPTR futexKey = (UINTPTR)userVaddr;
UINT32 lockVal;
INT32 ret;
if (OS_INT_ACTIVE) { if (OS_INT_ACTIVE) {
return LOS_EINTR; return LOS_EINTR;
} }
if (flags) { 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; return LOS_EINVAL;
} }
if ((futexKey % sizeof(INT32)) || (futexKey < OS_FUTEX_KEY_BASE) || (futexKey >= OS_FUTEX_KEY_MAX)) { 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; return LOS_EINVAL;
} }
if (!absTime) { 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; return LOS_EINVAL;
} }
if (lockVal != val) {
return LOS_EBADF;
}
return LOS_OK; return LOS_OK;
} }
...@@ -542,10 +530,10 @@ STATIC INT32 OsFutexInserTaskToHash(LosTaskCB **taskCB, FutexNode **node, const ...@@ -542,10 +530,10 @@ STATIC INT32 OsFutexInserTaskToHash(LosTaskCB **taskCB, FutexNode **node, const
return LOS_OK; 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; INT32 futexRet;
UINT32 intSave; UINT32 intSave, lockVal;
LosTaskCB *taskCB = NULL; LosTaskCB *taskCB = NULL;
FutexNode *node = NULL; FutexNode *node = NULL;
UINTPTR futexKey = (UINTPTR)userVaddr; UINTPTR futexKey = (UINTPTR)userVaddr;
...@@ -556,7 +544,19 @@ STATIC INT32 OsFutexWaitTask(const UINT32 timeOut, const UINT32 *userVaddr) ...@@ -556,7 +544,19 @@ STATIC INT32 OsFutexWaitTask(const UINT32 timeOut, const UINT32 *userVaddr)
return LOS_EINVAL; 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)) { if (OsFutexInserTaskToHash(&taskCB, &node, futexKey)) {
futexRet = LOS_NOK;
goto EXIT_ERR; goto EXIT_ERR;
} }
SCHEDULER_LOCK(intSave); SCHEDULER_LOCK(intSave);
...@@ -564,10 +564,6 @@ STATIC INT32 OsFutexWaitTask(const UINT32 timeOut, const UINT32 *userVaddr) ...@@ -564,10 +564,6 @@ STATIC INT32 OsFutexWaitTask(const UINT32 timeOut, const UINT32 *userVaddr)
OsPercpuGet()->taskLockCnt++; OsPercpuGet()->taskLockCnt++;
LOS_SpinUnlock(&g_taskSpin); LOS_SpinUnlock(&g_taskSpin);
#ifdef LOS_FUTEX_DEBUG
OsFutexHashShow();
#endif
futexRet = OsFutexUnlock(&hashNode->listLock); futexRet = OsFutexUnlock(&hashNode->listLock);
if (futexRet) { if (futexRet) {
OsPercpuGet()->taskLockCnt--; OsPercpuGet()->taskLockCnt--;
...@@ -594,12 +590,9 @@ STATIC INT32 OsFutexWaitTask(const UINT32 timeOut, const UINT32 *userVaddr) ...@@ -594,12 +590,9 @@ STATIC INT32 OsFutexWaitTask(const UINT32 timeOut, const UINT32 *userVaddr)
return LOS_OK; return LOS_OK;
EXIT_ERR: EXIT_ERR:
futexRet = OsFutexUnlock(&hashNode->listLock); (VOID)OsFutexUnlock(&hashNode->listLock);
EXIT_UNLOCK_ERR: EXIT_UNLOCK_ERR:
if (futexRet) { return futexRet;
return futexRet;
}
return LOS_NOK;
} }
INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absTime) 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 ...@@ -607,7 +600,7 @@ INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absT
INT32 ret; INT32 ret;
UINT32 timeOut = LOS_WAIT_FOREVER; UINT32 timeOut = LOS_WAIT_FOREVER;
ret = OsFutexWaitParmaCheck(userVaddr, flags, val, absTime); ret = OsFutexWaitParamCheck(userVaddr, flags, absTime);
if (ret) { if (ret) {
return ret; return ret;
} }
...@@ -615,7 +608,7 @@ INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absT ...@@ -615,7 +608,7 @@ INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absT
timeOut = OsFutexGetTick(absTime); timeOut = OsFutexGetTick(absTime);
} }
return OsFutexWaitTask(timeOut, userVaddr); return OsFutexWaitTask(timeOut, userVaddr, val);
} }
/* Check to see if the task to be awakened has timed out /* Check to see if the task to be awakened has timed out
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册