summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorHanhui <sylixos@gmail.com>2019-07-30 13:14:26 (GMT)
committer Hanhui <sylixos@gmail.com>2019-07-15 14:38:53 (GMT)
commit0c7a4d0f4e368ecbcd85efb75e81a9454b5b9f15 (patch)
tree1ea4be87f3a2d2fa7fcd06073a0e45995a214459
parent2f1b3e6647fa4d786e77e088c0bd9fdc6eacd3d3 (diff)
downloadAIC-OS-0c7a4d0f4e368ecbcd85efb75e81a9454b5b9f15.zip
Fixed schedule affinity current thread bug.
-rw-r--r--SylixOS/kernel/core/_EventSetBlock.c1
-rw-r--r--SylixOS/kernel/core/_ReadyRing.c2
-rw-r--r--SylixOS/kernel/core/_ThreadAffinity.c63
-rw-r--r--SylixOS/kernel/include/k_internal.h2
-rw-r--r--SylixOS/kernel/include/k_kernel.h2
-rw-r--r--SylixOS/kernel/interface/CpuPerf.c3
-rw-r--r--SylixOS/kernel/interface/RmsPeriod.c1
-rw-r--r--SylixOS/kernel/interface/ThreadAffinity.c37
-rw-r--r--SylixOS/loader/src/loader_vpthread.c28
9 files changed, 77 insertions, 62 deletions
diff --git a/SylixOS/kernel/core/_EventSetBlock.c b/SylixOS/kernel/core/_EventSetBlock.c
index d63efbe..62d735f 100644
--- a/SylixOS/kernel/core/_EventSetBlock.c
+++ b/SylixOS/kernel/core/_EventSetBlock.c
@@ -72,7 +72,6 @@ VOID _EventSetBlock (PLW_CLASS_EVENTSET pes,
_List_Line_Add_Ahead(&pesn->EVENTSETNODE_lineManage, &pes->EVENTSET_plineWaitList);
ppcb = _GetPcb(ptcbCur);
-
__DEL_FROM_READY_RING(ptcbCur, ppcb); /* 从就绪环中删除 */
}
diff --git a/SylixOS/kernel/core/_ReadyRing.c b/SylixOS/kernel/core/_ReadyRing.c
index 85efeb4..47a4470 100644
--- a/SylixOS/kernel/core/_ReadyRing.c
+++ b/SylixOS/kernel/core/_ReadyRing.c
@@ -64,8 +64,6 @@ VOID _AddTCBToReadyRing (PLW_CLASS_TCB ptcb, PLW_CLASS_PCB ppcb, BOOL bIsHea
}
break;
}
-
- return;
}
/*********************************************************************************************************
** 函数名称: _DelTCBFromReadyRing
diff --git a/SylixOS/kernel/core/_ThreadAffinity.c b/SylixOS/kernel/core/_ThreadAffinity.c
index 702431d..4b80fbb 100644
--- a/SylixOS/kernel/core/_ThreadAffinity.c
+++ b/SylixOS/kernel/core/_ThreadAffinity.c
@@ -28,43 +28,80 @@
#if LW_CFG_SMP_EN > 0
/*********************************************************************************************************
** 函数名称: _ThreadSetAffinity
-** 功能描述: 将线程锁定到指定的 CPU 运行. (进入内核被调用且目标任务已经被停止)
+** 功能描述: 将线程锁定到指定的 CPU 运行. (进入内核被调用)
** 输 入 : ptcb 线程控制块
** stSize CPU 掩码集内存大小
** pcpuset CPU 掩码
-** 输 出 : NONE
+** 输 出 : ERROR CODE
** 全局变量:
** 调用模块:
** 注 意 : LW_CPU_ZERO(pcpuset) 可以解除 CPU 锁定.
*********************************************************************************************************/
-VOID _ThreadSetAffinity (PLW_CLASS_TCB ptcb, size_t stSize, const PLW_CLASS_CPUSET pcpuset)
+ULONG _ThreadSetAffinity (PLW_CLASS_TCB ptcb, size_t stSize, const PLW_CLASS_CPUSET pcpuset)
{
- ULONG i;
- ULONG ulNumChk;
-
+ INTREG iregInterLevel;
+ ULONG i;
+ ULONG ulNumChk;
+ ULONG ulError;
+ PLW_CLASS_TCB ptcbCur;
+ PLW_CLASS_PCB ppcb;
+
ulNumChk = ((ULONG)stSize << 3);
ulNumChk = (ulNumChk > LW_NCPUS) ? LW_NCPUS : ulNumChk;
for (i = 0; i < ulNumChk; i++) {
if (ptcb->TCB_ulOption & LW_OPTION_THREAD_AFFINITY_ALWAYS) {
if (LW_CPU_ISSET(i, pcpuset)) {
- ptcb->TCB_ulCPULock = i;
- ptcb->TCB_bCPULock = LW_TRUE; /* 锁定执行 CPU */
- return;
+ break; /* 锁定执行 CPU */
}
} else {
if (LW_CPU_ISSET(i, pcpuset) &&
LW_CPU_IS_ACTIVE(LW_CPU_GET(i)) &&
!(LW_CPU_GET_IPI_PEND(i) & LW_IPI_DOWN_MSK)) { /* 必须激活并且没有要被停止 */
- ptcb->TCB_ulCPULock = i;
- ptcb->TCB_bCPULock = LW_TRUE; /* 锁定执行 CPU */
- return;
+ break; /* 锁定执行 CPU */
}
}
}
- ptcb->TCB_bCPULock = LW_FALSE; /* 关闭 CPU 锁定 */
+ LW_TCB_GET_CUR(ptcbCur);
+
+ if (ptcbCur == ptcb) {
+ if (i >= ulNumChk) {
+ ptcb->TCB_bCPULock = LW_FALSE; /* 关闭 CPU 锁定 */
+
+ } else {
+ iregInterLevel = KN_INT_DISABLE();
+ ppcb = _GetPcb(ptcbCur);
+ __DEL_FROM_READY_RING(ptcbCur, ppcb); /* 从就绪表中删除 */
+
+ ptcbCur->TCB_ulCPULock = i;
+ ptcbCur->TCB_bCPULock = LW_TRUE; /* 锁定执行 CPU */
+
+ ptcbCur->TCB_ucSchedActivate = LW_SCHED_ACT_INTERRUPT; /* 中断激活方式 */
+ ppcb = _GetPcb(ptcbCur);
+ __ADD_TO_READY_RING(ptcbCur, ppcb); /* 加入到相对优先级就绪环 */
+ KN_INT_ENABLE(iregInterLevel);
+ }
+
+ } else {
+ ulError = _ThreadStop(ptcb);
+ if (ulError) {
+ return (ulError);
+ }
+
+ if (i >= ulNumChk) {
+ ptcb->TCB_bCPULock = LW_FALSE; /* 关闭 CPU 锁定 */
+
+ } else {
+ ptcb->TCB_ulCPULock = i;
+ ptcb->TCB_bCPULock = LW_TRUE; /* 锁定执行 CPU */
+ }
+
+ _ThreadContinue(ptcb, LW_FALSE); /* 唤醒目标 */
+ }
+
+ return (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: _ThreadGetAffinity
diff --git a/SylixOS/kernel/include/k_internal.h b/SylixOS/kernel/include/k_internal.h
index cec6154..83f46c4 100644
--- a/SylixOS/kernel/include/k_internal.h
+++ b/SylixOS/kernel/include/k_internal.h
@@ -543,7 +543,7 @@ INT _ThreadSched(PLW_CLASS_TCB ptcbCur);
*********************************************************************************************************/
#if LW_CFG_SMP_EN > 0
-VOID _ThreadSetAffinity(PLW_CLASS_TCB ptcb, size_t stSize, const PLW_CLASS_CPUSET pcpuset);
+ULONG _ThreadSetAffinity(PLW_CLASS_TCB ptcb, size_t stSize, const PLW_CLASS_CPUSET pcpuset);
VOID _ThreadGetAffinity(PLW_CLASS_TCB ptcb, size_t stSize, PLW_CLASS_CPUSET pcpuset);
VOID _ThreadOffAffinity(PLW_CLASS_CPU pcpu);
#endif /* LW_CFG_SMP_EN */
diff --git a/SylixOS/kernel/include/k_kernel.h b/SylixOS/kernel/include/k_kernel.h
index e559eda..846c71f 100644
--- a/SylixOS/kernel/include/k_kernel.h
+++ b/SylixOS/kernel/include/k_kernel.h
@@ -51,7 +51,7 @@
#define __SYLIXOS_MAJOR_VER 1
#define __SYLIXOS_MINOR_VER 10
-#define __SYLIXOS_PATCH_VER 5
+#define __SYLIXOS_PATCH_VER 6
#define __SYLIXOS_PATCH_PAD 0
/*********************************************************************************************************
diff --git a/SylixOS/kernel/interface/CpuPerf.c b/SylixOS/kernel/interface/CpuPerf.c
index beb6160..2cbe74e 100644
--- a/SylixOS/kernel/interface/CpuPerf.c
+++ b/SylixOS/kernel/interface/CpuPerf.c
@@ -110,8 +110,7 @@ ULONG API_CpuBogoMips (ULONG ulCPUId, ULONG *pulKInsPerSec)
API_ThreadGetAffinity(ulMe, sizeof(pcpusetOld), &pcpusetOld);
LW_CPU_ZERO(&pcpusetNew);
LW_CPU_SET(ulCPUId, &pcpusetNew); /* 锁定 CPU */
- API_ThreadSetAffinity(ulMe, sizeof(pcpusetNew), &pcpusetNew);
- API_TimeSleep(1); /* 确保进入指定的 CPU 运行 */
+ API_ThreadSetAffinity(ulMe, sizeof(pcpusetNew), &pcpusetNew);
_CpuBogoMipsCalc(ulCPUId);
API_ThreadSetAffinity(ulMe, sizeof(pcpusetOld), &pcpusetOld);
}
diff --git a/SylixOS/kernel/interface/RmsPeriod.c b/SylixOS/kernel/interface/RmsPeriod.c
index 04b9317..9e41771 100644
--- a/SylixOS/kernel/interface/RmsPeriod.c
+++ b/SylixOS/kernel/interface/RmsPeriod.c
@@ -130,7 +130,6 @@ ULONG API_RmsPeriod (LW_OBJECT_HANDLE ulId, ULONG ulPeriod)
* 当前线程开始睡眠
*/
ppcb = _GetPcb(ptcbCur);
-
__DEL_FROM_READY_RING(ptcbCur, ppcb); /* 从就绪表中删除 */
ptcbCur->TCB_ulDelay = ulWaitTime;
diff --git a/SylixOS/kernel/interface/ThreadAffinity.c b/SylixOS/kernel/interface/ThreadAffinity.c
index ca08a05..4088f9b 100644
--- a/SylixOS/kernel/interface/ThreadAffinity.c
+++ b/SylixOS/kernel/interface/ThreadAffinity.c
@@ -42,7 +42,8 @@ ULONG API_ThreadSetAffinity (LW_OBJECT_HANDLE ulId, size_t stSize, const PLW_
{
REGISTER UINT16 usIndex;
REGISTER PLW_CLASS_TCB ptcb;
- ULONG ulError;
+ PLW_CLASS_TCB ptcbCur;
+ ULONG ulMaxLock;
usIndex = _ObjectGetIndex(ulId);
@@ -66,33 +67,29 @@ ULONG API_ThreadSetAffinity (LW_OBJECT_HANDLE ulId, size_t stSize, const PLW_
return (EPERM);
}
- if (ulId == API_ThreadIdSelf()) { /* 设置自己 */
- LW_TCB_GET_CUR_SAFE(ptcb);
- if (__THREAD_LOCK_GET(ptcb)) { /* 当前任务被锁定 */
- _ErrorHandle(EPERM);
- return (EPERM);
- }
- __KERNEL_ENTER(); /* 进入内核 */
- _ThreadSetAffinity(ptcb, stSize, pcpuset);
- __KERNEL_EXIT(); /* 退出内核 */
- return (ERROR_NONE);
- }
-
- ulError = API_ThreadStop(ulId); /* 首先停止目标线程 */
- if (ulError) {
- return (ulError);
- }
-
__KERNEL_ENTER(); /* 进入内核 */
if (_Thread_Invalid(usIndex)) {
__KERNEL_EXIT(); /* 退出内核 */
_ErrorHandle(ERROR_KERNEL_HANDLE_NULL);
return (ERROR_KERNEL_HANDLE_NULL);
}
-
+
ptcb = _K_ptcbTCBIdTable[usIndex];
+ if (ptcb->TCB_iDeleteProcStatus) { /* 在删除和重启的过程中 */
+ __KERNEL_EXIT(); /* 退出内核 */
+ _ErrorHandle(ERROR_THREAD_NULL);
+ return (ERROR_THREAD_NULL);
+ }
+
+ LW_TCB_GET_CUR(ptcbCur);
+ ulMaxLock = (ptcb == ptcbCur) ? 1 : 0;
+ if (__THREAD_LOCK_GET(ptcb) > ulMaxLock) { /* 任务被锁定 */
+ __KERNEL_EXIT(); /* 退出内核 */
+ _ErrorHandle(EBUSY);
+ return (EBUSY);
+ }
+
_ThreadSetAffinity(ptcb, stSize, pcpuset); /* 设置 */
- _ThreadContinue(ptcb, LW_FALSE); /* 唤醒目标 */
__KERNEL_EXIT(); /* 退出内核 */
return (ERROR_NONE);
diff --git a/SylixOS/loader/src/loader_vpthread.c b/SylixOS/loader/src/loader_vpthread.c
index cbf8026..4ae0b61 100644
--- a/SylixOS/loader/src/loader_vpthread.c
+++ b/SylixOS/loader/src/loader_vpthread.c
@@ -249,15 +249,12 @@ INT vprocThreadAffinity (PVOID pvVProc, size_t stSize, const PLW_CLASS_CPUSET
LW_LD_VPROC *pvproc = (LW_LD_VPROC *)pvVProc;
PLW_LIST_LINE plineTemp;
PLW_CLASS_TCB ptcb;
- PLW_CLASS_TCB ptcbCur;
if (!pvproc) {
_ErrorHandle(ESRCH);
return (PX_ERROR);
}
-
- LW_TCB_GET_CUR_SAFE(ptcbCur);
-
+
LW_VP_LOCK(pvproc); /* 锁定当前进程 */
for (plineTemp = pvproc->VP_plineThread;
plineTemp != LW_NULL;
@@ -267,24 +264,13 @@ INT vprocThreadAffinity (PVOID pvVProc, size_t stSize, const PLW_CLASS_CPUSET
if (ptcb->TCB_iDeleteProcStatus) {
continue; /* 已经在删除过程中 */
}
-
- if (ptcb == ptcbCur) {
- if (!__THREAD_LOCK_GET(ptcb)) { /* 外部没有锁定此任务 */
- __KERNEL_ENTER(); /* 进入内核 */
- _ThreadSetAffinity(ptcb, stSize, pcpuset);
- __KERNEL_EXIT(); /* 退出内核 */
- }
-
- } else if (ptcb->TCB_iDeleteProcStatus == LW_TCB_DELETE_PROC_NONE) {
- __KERNEL_ENTER(); /* 进入内核 */
- _ThreadStop(ptcb);
- __KERNEL_EXIT(); /* 退出内核 (可能产生调度) */
-
- __KERNEL_ENTER(); /* 进入内核 */
- _ThreadSetAffinity(ptcb, stSize, pcpuset);
- _ThreadContinue(ptcb, LW_FALSE);
- __KERNEL_EXIT(); /* 退出内核 */
+ if (__THREAD_LOCK_GET(ptcb)) { /* 外部没有锁定此任务 */
+ continue; /* 线程被锁定 */
}
+
+ __KERNEL_ENTER(); /* 进入内核 */
+ _ThreadSetAffinity(ptcb, stSize, pcpuset);
+ __KERNEL_EXIT(); /* 退出内核 */
}
LW_VP_UNLOCK(pvproc); /* 解锁当前进程 */