您好,登錄后才能下訂單哦!
本文檔的主要內容是分析SylixOS線程創(chuàng)建的流程,詳細介紹了SylixOS的線程創(chuàng)建函數(shù)API_ThreadCreate。
在SylixOS中,線程的創(chuàng)建函數(shù)不能在中斷中調用。且在線程的創(chuàng)建時,系統(tǒng)會對線程的堆棧大小、優(yōu)先級和名字等參數(shù)做有效性檢查,一旦參數(shù)出錯,則線程創(chuàng)建失敗。當參數(shù)有效性檢查完畢后,系統(tǒng)調用_Allocate_Tcb_Object函數(shù),從空閑TCB控件池中取出一個空閑的TCB資源(TCB是線程控制塊)。具體的代碼實現(xiàn)如程序清單 2-1所示。
程序清單 2-1線程創(chuàng)建的環(huán)境和參數(shù)檢查
/********************************************************************************************************* ** 函數(shù)名稱: API_ThreadCreate ** 功能描述: 建立一個線程 ** 輸 入 : pcName 線程名 ** pfuncThread 指線程代碼段起始地址 ** pthreadattr 線程屬性集合指針 ** pulId 線程生成的ID指針 可以為 NULL ** 輸 出 : pulId 線程句柄 同 ID 一個概念 *********************************************************************************************************/ LW_API LW_OBJECT_HANDLE API_ThreadCreate (CPCHAR pcName, PTHREAD_START_ROUTINE pfuncThread, PLW_CLASS_THREADATTR pthreadattr, LW_OBJECT_ID *pulId) { if (LW_CPU_GET_CUR_NESTING()) { /* 不能在中斷中調用 */ return (LW_OBJECT_HANDLE_INVALID); } if (threadattrDefault.THREADATTR_stStackByteSize == 0) { threadattrDefault = API_ThreadAttrGetDefault(); /* 初始化默認屬性 */ } if (pthreadattr == LW_NULL) { pthreadattr = &threadattrDefault; /* 使用默認屬性 */ } /* 默認屬性總是使用自動分配堆棧*/ #if LW_CFG_ARG_CHK_EN > 0 if (!pfuncThread) { /* 指線程代碼段起始地址為空 */ return (LW_OBJECT_HANDLE_INVALID); } if (_StackSizeCheck(pthreadattr->THREADATTR_stStackByteSize)) { /* 堆棧大小不正確 */ return (LW_OBJECT_HANDLE_INVALID); } if (_PriorityCheck(pthreadattr->THREADATTR_ucPriority)) { /* 優(yōu)先級錯誤 */ return (LW_OBJECT_HANDLE_INVALID); } #endif if (_Object_Name_Invalid(pcName)) { /* 檢查名字有效性 */ return (LW_OBJECT_HANDLE_INVALID); } __KERNEL_MODE_PROC( ptcb = _Allocate_Tcb_Object(); /* 獲得一個 TCB */ ); if (!ptcb) { /* 檢查是否可以建立線程 */ return (LW_OBJECT_HANDLE_INVALID); }
如程序清單 3-1所示,在SylixOS中,系統(tǒng)對線程創(chuàng)建的環(huán)境和參數(shù)檢查完畢后,會進入安全模式,安全模式的主要作用是保護主線程在創(chuàng)建新線程時不被刪除。
在第2小節(jié)中提到"當參數(shù)有效性檢查完畢后,系統(tǒng)調用_Allocate_Tcb_Object函數(shù),從空閑TCB控件池中取出一個空閑的TCB資源",需要注意這里只是簡單的獲得一個TCB資源。當系統(tǒng)調用_TCBBuild函數(shù),對TCB結構體的成員進行賦值后,才真正完成TCB的構建。
程序清單 3-1線程創(chuàng)建的安全模式
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, /* 真正的可執(zhí)行代碼體 */ pstkTop, pthreadattr->THREADATTR_ulOption); ulError = _TCBBuildExt(ptcb); /* 首先先初始化擴展結構 */ if (ulError) { iErrLevel = 2; _ErrorHandle(ulError); goto __error_handle; } _TCBBuild(pthreadattr->THREADATTR_ucPriority, /* 構建 TCB */ pstkFristFree, /* 空閑棧區(qū)地址 */ pstkTop, /* 主棧區(qū)地址 */ 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函數(shù),嘗試將新創(chuàng)建的線程加入候選表中。若候選表非空且新創(chuàng)建的線程優(yōu)先級高于候選表里的線程時,會產(chǎn)生優(yōu)先級卷繞。當CPU下次調度,檢測到有優(yōu)先級卷繞時,CPU會從就緒表中尋找一個最適合運行的線程去運行。
內部交流文檔,僅針對SylixOS平臺,若發(fā)現(xiàn)相關錯誤或者建議,請及時聯(lián)系文檔創(chuàng)建者進行修訂和更新。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。