安全模式
如程序清单 3-1所示,在SylixOS中,系统对线程创建的环境和参数检查完毕后,会进入安全模式,安全模式的主要作用是保护主线程在创建新线程时不被删除。
在第2小节中提到"当参数有效性检查完毕后,系统调用_Allocate_Tcb_Object函数,从空闲TCB控件池中取出一个空闲的TCB资源",需要注意这里只是简单的获得一个TCB资源。当系统调用_TCBBuild函数,对TCB结构体的成员进行赋值后,才真正完成TCB的构建。
程序清单 3-1线程创建的安全模式
if (LW_SYS_STATUS_IS_RUNNING()) {
_ThreadSafeInternal(); /* 进入安全模式 */
}
lib_bzero(&ptcb->TCB_pstkStackTop,
sizeof(LW_CLASS_TCB) -
_LIST_OFFSETOF(LW_CLASS_TCB, TCB_pstkStackTop)); /* TCB 清零 */
ulIdTemp = _MakeObjectId(_OBJECT_THREAD,
LW_CFG_PROCESSOR_NUMBER,
ptcb->TCB_usIndex); /* 构建对象 id */
/* 初始化堆栈,SHELL */
pstkFristFree = archTaskCtxCreate((PTHREAD_START_ROUTINE)_ThreadShell,
(PVOID)pfuncThread, /* 真正的可执行代码体 */
pstkTop,
pthreadattr->THREADATTR_ulOption);
ulError = _TCBBuildExt(ptcb); /* 首先先初始化扩展结构 */
if (ulError) {
iErrLevel = 2;
_ErrorHandle(ulError);
goto __error_handle;
}
_TCBBuild(pthreadattr->THREADATTR_ucPriority, /* 构建 TCB */
pstkFristFree, /* 空闲栈区地址 */
pstkTop, /* 主栈区地址 */
pstkButtom, /* 栈底 */
pstkGuard,
pthreadattr->THREADATTR_pvExt,
pstkLowAddress,
stStackSize, /* 相对于字对齐的堆栈大小 */
ulIdTemp,
pthreadattr->THREADATTR_ulOption,
pfuncThread,
ptcb,
pthreadattr->THREADATTR_pvArg);
if (!(pthreadattr->THREADATTR_ulOption &
LW_OPTION_THREAD_INIT)) { /* 非仅初始化 */
_TCBTryRun(ptcb); /* 尝试运行新任务 */
}
if (pulId) {
*pulId = ulIdTemp; /* 记录 ID */
}
if (LW_SYS_STATUS_IS_RUNNING()) {
_ThreadUnsafeInternal(); /* 退出安全模式 */
}
return (LW_OBJECT_HANDLE_INVALID);
}
在安全模式中,当TCB构建完成后,会调用_TCBTryRun函数,尝试将新创建的线程加入候选表中。若候选表非空且新创建的线程优先级高于候选表里的线程时,会产生优先级卷绕。当CPU下次调度,检测到有优先级卷绕时,CPU会从就绪表中寻找一个最适合运行的线程去运行。