色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

鴻蒙內核源碼:32級優先級的進程和線程調度

鴻蒙系統HarmonyOS ? 來源:my.oschina ? 作者:鴻蒙內核源碼分析 ? 2021-04-24 11:18 ? 次閱讀

先看四個宏定義,進程和線程(線程就是任務)最高和最低優先級定義,[0,31]區間,即32級,優先級用于調度,CPU根據這個來決定先運行哪個進程和任務。

#define OS_PROCESS_PRIORITY_HIGHEST      0 //進程最高優先級
#define OS_PROCESS_PRIORITY_LOWEST       31 //進程最低優先級
#define OS_TASK_PRIORITY_HIGHEST    0 //任務最高優先級,軟時鐘任務就是最高級任務,見于 OsSwtmrTaskCreate
#define OS_TASK_PRIORITY_LOWEST     31 //任務最低優先級

為何進程和線程都是32個優先級?

回答這個問題之前,先回答另一個問題,為什么人類幾乎所有的文明都是用十進制的計數方式。答案掰手指就知道了,因為人有十根手指頭。瑪雅人的二十進制那是把腳指頭算上了,但其實也算是十進制的表示。

這是否說明一個問題,認知受環境的影響,方向是怎么簡單/方便怎么來。這也可以解釋為什么人類語言發音包括各種方言對媽媽這個詞都很類似,因為嬰兒說mama是最容易的。注意認識這點很重要!

而計算機的世界是二進制的,是是非非,清清楚楚,特別的簡單,二進制已經最簡單了,到底啦,不可能有更簡單的了。還記得雙向鏈表篇中說過的嗎,因為簡單所以才不簡單啊,大道若簡,計算機就靠著這01碼,表述萬千世界。

但人類的大腦不擅長存儲,二進制太長了數到100就撐爆了大腦,記不住,為了記憶和運算方便,編程常用靠近10進制的 16進制來表示 ,0x9527ABCD看著比 0011000111100101010100111舒服多了。

應用開發和內核開發有哪些區別?

區別還是很大的,這里只說一點,就是對位的控制能力,內核會出現大量的按位運算(&,|,~,^) , 一個變量的不同位表達不同的含義,但這在應用程序員那是很少看到的,他們用的更多的是邏輯運算(&&,||,!)

#define OS_TASK_STATUS_INIT         0x0001U //初始化狀態
#define OS_TASK_STATUS_READY        0x0002U //就緒狀態的任務都將插入就緒隊列
#define OS_TASK_STATUS_RUNNING      0x0004U //運行狀態
#define OS_TASK_STATUS_SUSPEND      0x0008U //掛起狀態
#define OS_TASK_STATUS_PEND         0x0010U //阻塞狀態

這是任務各種狀態(注者后續將比如成貼標簽)表述,將它們還原成二進制就是:

0000000000000001 =0x0001U

0000000000000010 =0x0002U

0000000000000100 =0x0004U

0000000000001000 =0x0008U

0000000000010000 =0x0010U

發現二進制這邊的區別沒有,用每一位來表示一種不同的狀態,1表示是,0表示不是。

這樣的好處有兩點:

1.可以多種標簽同時存在比如 0x07 = 0b00000111,對應以上就是任務有三個標簽(初始,就緒,和運行),進程和線程在運行期間是允許多種標簽同時存在的。

2.節省了空間,一個變量就搞定了,如果是應用程序員要實現這三個標簽同時存在,習慣上要定義三個變量的,因為你的排他性顆粒度是一個變量而不是一個位。

而對位的管理/運算就需要有個專門的管理器:位圖管理器 (見源碼 los_bitmap.c )

什么是位圖管理器?

直接上部分代碼,代碼關鍵地方都加了中文注釋,簡單說就是對位的各種操作,比如如何在某個位上設1?如何找到最高位為1的是哪個位置?這些函數都是有大用途的。

//對狀態字的某一標志位進行置1操作
VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos)
{
    if (bitmap == NULL) {
        return;
    }

    *bitmap |= 1U << (pos & OS_BITMAP_MASK);//在對應位上置1
}
//對狀態字的某一標志位進行清0操作
VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos)
{
    if (bitmap == NULL) {
        return;
    }

    *bitmap &= ~(1U << (pos & OS_BITMAP_MASK));//在對應位上置0
}
/********************************************************
雜項算術指令
CLZ 用于計算操作數最高端0的個數,這條指令主要用于一下兩個場合
  計算操作數規范化(使其最高位為1)時需要左移的位數
  確定一個優先級掩碼中最高優先級
********************************************************/
//獲取狀態字中為1的最高位 例如: 00110110 返回 5
UINT16 LOS_HighBitGet(UINT32 bitmap)
{
    if (bitmap == 0) {
        return LOS_INVALID_BIT_INDEX;
    }

    return (OS_BITMAP_MASK - CLZ(bitmap));
}
//獲取狀態字中為1的最低位, 例如: 00110110 返回 2
UINT16 LOS_LowBitGet(UINT32 bitmap)
{
    if (bitmap == 0) {
        return LOS_INVALID_BIT_INDEX;
    }

    return CTZ(bitmap);//
}
位圖在哪些地方應用?

內核很多模塊在使用位圖,這里只說進程和線程模塊,還記得開始的問題嗎,為何進程和線程都是32個優先級?因為他們的優先級是由位圖管理的,管理一個UINT32的變量,所以是32級,一個位一個級別,最高位優先級最低。

    UINT32          priBitMap;          /**< BitMap for recording the change of task priority, //任務在執行過程中優先級會經常變化,這個變量用來記錄所有曾經變化
                                             the priority can not be greater than 31 */   //過的優先級,例如 ..01001011 曾經有過 0,1,3,6 優先級

這是任務控制塊中對調度優先級位圖的定義,注意一個任務的優先級在運行過程中可不是一成不變的,內核會根據運行情況而改變它的,這個變量是用來保存這個任務曾經有過的所有優先級歷史記錄。

比如 任務A的優先級位圖是 00000001001011 ,可以看出它曾經有過四個調度等級記錄,那如果想知道優先級最低的記錄是多少時怎么辦呢?

誒,上面的位圖管理器函數UINT16 LOS_HighBitGet(UINT32 bitmap)就很有用啦 ,它返回的是1在高位出現的位置,可以數一下是 6

因為任務的優先級0最大,所以最終的意思就是A任務曾經有過的最低優先級是6

一定要理解位圖的操作,內核中大量存在這類代碼,尤其到了匯編層,對寄存器的操作大量的出現。

比如以下這段匯編代碼。

    MSR     CPSR_c, #(CPSR_INT_DISABLE | CPSR_SVC_MODE)  @禁止中斷并切到管理模式
    LDRH    R1, [R0, #4]  @將存儲器地址為R0+4 的低16位數據讀入寄存器R1,并將R1的高16 位清零
    ORR     R1, #OS_TASK_STATUS_RUNNING @或指令 R1=R1|OS_TASK_STATUS_RUNNING
    STRH    R1, [R0, #4]  @將寄存器R1中的低16位寫入以R0+4為地址的存儲器中

編程實例

對數據實現位操作,本實例實現如下功能:

某一標志位置1。

獲取標志位為1的最高bit位。

某一標志位清0。

獲取標志位為1的最低bit位。

#include "los_bitmap.h"
#include "los_printf.h"

static UINT32 Bit_Sample(VOID)
{
  UINT32 flag = 0x10101010;
  UINT16 pos;

  dprintf("\nBitmap Sample!\n");
  dprintf("The flag is 0x%8x\n", flag);

  pos = 8;
  LOS_BitmapSet(&flag, pos);
  dprintf("LOS_BitmapSet:\t pos : %d, the flag is 0x%0+8x\n", pos, flag);

  pos = LOS_HighBitGet(flag);
  dprintf("LOS_HighBitGet:\t The highest one bit is %d, the flag is 0x%0+8x\n", pos, flag);

  LOS_BitmapClr(&flag, pos);
  dprintf("LOS_BitmapClr:\t pos : %d, the flag is 0x%0+8x\n", pos, flag);

  pos = LOS_LowBitGet(flag);
  dprintf("LOS_LowBitGet:\t The lowest one bit is %d, the flag is 0x%0+8x\n\n", pos, flag);

  return LOS_OK;
}

結果驗證

Bitmap Sample!
The flag is 0x10101010
LOS_BitmapSet: pos : 8,  the flag is 0x10101110
LOS_HighBitGet:The highest one bit is 28, the flag is 0x10101110
LOS_BitmapClr: pos : 28, the flag is 0x00101110
LOS_LowBitGet: The lowest one bit is 4, the flag is 0x00101110

編輯:hfy

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • cpu
    cpu
    +關注

    關注

    68

    文章

    10854

    瀏覽量

    211585
  • 鴻蒙系統
    +關注

    關注

    183

    文章

    2634

    瀏覽量

    66308
收藏 人收藏

    評論

    相關推薦

    基于優先級搶占系統的QNX調度算法

    調度算法,是基于優先級的。QNX的線程優先級,是一個0-255的數字,數字越大優先級越高。所以,優先級
    發表于 10-31 09:17 ?727次閱讀

    基于優先級調度的嵌入式實時操作系統內核詳解(上)

    今日分享參加瑞薩RA MCU創意氛圍賽的選手項目——基于優先級的RTOS內核。本項目為基于優先級調度的嵌入式實時操作系統內核,其中
    發表于 09-04 14:12 ?763次閱讀

    用戶線程內核線程

    線程的創建、撤消和調度不需要OS內核的支持,是在語言(如Java)這一處理的;而內核支持
    發表于 01-10 15:01

    任務優先級問題

    優先級的任務可以通過時間片輪轉調度來實現任務切換。在不同優先級的任務中,如果高優先級的任務沒有延時,沒有等待信號量等使用任務調度
    發表于 04-02 04:35

    【HarmonyOS】鴻蒙內核源碼分析(調度機制篇)

    有以下兩種:有更高優先級進程創建或者恢復后,會發生進程調度,此刻就緒列表中最高優先級進程變為運
    發表于 10-14 14:00

    鴻蒙內核源碼分析(調度機制篇):Task是如何被調度執行的

    執行. 不允許任何中斷發生, 沒錯,說的是任何事是不能去打斷它,否則后果太嚴重了,這可是內核在切換進程線程的操作啊。在就緒隊列里找個最高優先級的task切換
    發表于 11-23 10:53

    鴻蒙內核源碼分析(調度隊列篇):進程和Task的就緒隊列對調度的作用

    進程下的線程優先級可以不一樣嗎?請先想一下這個問題。進程線程是一對多的父子關系,內核
    發表于 11-23 11:09

    鴻蒙內核源碼分析(Task管理篇):task是內核調度的單元

    獨立運行、獨立調度,當前進程線程調度不受其它進程線程的影響。
    發表于 11-23 14:01

    rt-thread高優先級線程可以調度執行嗎?

    請教下,在rt-thread中,如果低優先級線程中用while(1){}直接死循環,是不是高優先級線程也無法調度執行了?如果高
    發表于 05-13 10:51

    Linux內核線程優先級設置的方法介紹

    內核線程進程是一樣的,前者與POSIX線程(pthread)有很大的區別。因此,內核
    發表于 04-23 14:58 ?5641次閱讀
    Linux<b class='flag-5'>內核</b><b class='flag-5'>線程</b><b class='flag-5'>優先級</b>設置的方法介紹

    鴻蒙內核源碼分析:任務池管理技術

    當前進程內高優先級線程可搶占當前進程內低優先級線程,當前
    的頭像 發表于 04-24 11:11 ?1627次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>內核</b><b class='flag-5'>源碼</b>分析:任務池管理技術

    鴻蒙內核源碼分析:task是內核調度的單元

    進程線程的影響。 鴻蒙內核中的線程采用搶占式調度機制,同時支持時間片輪轉
    發表于 11-23 15:51 ?22次下載
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>內核</b><b class='flag-5'>源碼</b>分析:task是<b class='flag-5'>內核</b><b class='flag-5'>調度</b>的單元

    cortex M內核優先級設置

    Cortex M內核中每個中斷都有一個8位的優先級設置寄存器這個8位的寄存器可以分為搶占優先級和子優先級兩個部分(通過設置優先級組設置)搶占
    發表于 12-01 11:51 ?4次下載
    cortex M<b class='flag-5'>內核</b><b class='flag-5'>優先級</b>設置

    uC/OS-II學習筆記——優先級反轉與優先級繼承機制

    優先級反轉,是指某同步資源被較低優先級進程/線程所擁有,較高優先級進程/
    發表于 02-09 10:33 ?2次下載
    uC/OS-II學習筆記——<b class='flag-5'>優先級</b>反轉與<b class='flag-5'>優先級</b>繼承機制

    基于優先級調度的嵌入式實時操作系統內核詳解(下)

    基于優先級調度的嵌入式實時操作系統內核詳解(下)
    的頭像 發表于 09-06 12:46 ?880次閱讀
    基于<b class='flag-5'>優先級</b><b class='flag-5'>調度</b>的嵌入式實時操作系統<b class='flag-5'>內核</b>詳解(下)
    主站蜘蛛池模板: 中文字幕亚洲欧美日韩2019| 久久99影院| 成人永久免费视频| 亚洲合集综合久久性色| 色噜噜噜视频| 麻豆AV福利AV久久AV| 99re在这里只有精品| 日本熟妇乱人伦A片精品软件| 久久一级片| 和I儿媳妇激情| 国产精品成人免费观看| 国产偷国产偷亚洲高清人乐享| 国产毛片女人18水多| 韩国黄电影| 免费撕开胸罩吮胸视频| 日韩精品亚洲专区在线影院| 小草高清视频免费直播| 亚洲绝美精品一区二区| 538在线播放| 国产AV无码成人黄网站免费| 国产一及毛片| 免费观看99热只有精品| 手机看片成人| 樱花草动漫www| 俄罗斯14一18处交| 久久99AV无色码人妻蜜| 青柠电影高清在线观看| 性xxx免费| bbw极度另类孕妇| 精品久久久噜噜噜久久7| 欧美乱妇狂野欧美在线视频| 无限资源在线看影院免费观看| 一区三区不卡高清影视| 丰满人妻按磨HD| 久久精品影院永久网址| 十8禁用B站在线看漫画| 最近免费中文字幕MV免费高清| 国产成人久久AV免费看澳门| 美国色情三级欧美三级纸匠情挑| 色综合 亚洲 自拍 欧洲| 99精品国产高清自在线看超|