成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

鴻蒙輕內(nèi)核A核源碼分析系列二:數(shù)據(jù)結(jié)構(gòu)-位圖操作

開(kāi)發(fā) 前端
文章由鴻蒙社區(qū)產(chǎn)出,想要了解更多內(nèi)容請(qǐng)前往:51CTO和華為官方戰(zhàn)略合作共建的鴻蒙技術(shù)社區(qū)https://harmonyos.51cto.com

[[405939]]

想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

在進(jìn)一步分析之前,本文我們先來(lái)熟悉下OpenHarmony鴻蒙輕內(nèi)核提供的位操作模塊,在互斥鎖等模塊對(duì)位操作有使用。位操作是指對(duì)二進(jìn)制數(shù)的bit位進(jìn)行操作。程序可以設(shè)置某一變量為狀態(tài)字,狀態(tài)字中的每一bit位(標(biāo)志位)可以具有自定義的含義。

1 位操作的宏定義

位操作模塊提供對(duì)32位無(wú)符號(hào)整數(shù)數(shù)值的bit位進(jìn)行操作,bit位取值為0-31,以0開(kāi)始計(jì)算,從左向右,第0位,第1位。。。第31位等。⑴處定義的宏OS_BITMAP_MASK如下,也就是十進(jìn)制31。如果傳入的比特位pos大于31,會(huì)通過(guò)邏輯與運(yùn)算截?cái)?pos & OS_BITMAP_MASK),只取低5位,確保不會(huì)大于31,避免溢出。⑵處定義的位圖掩碼全是1。

  1. ⑴  #define OS_BITMAP_MASK 0x1FU 
  2. ⑵  #define OS_BITMAP_WORD_MASK ~0UL 

 在文件kernel\include\los_bitmap.h中定義了常用的位操作相關(guān)的宏。宏BITMAP_WORD根據(jù)參數(shù)x計(jì)算出需要操作第幾個(gè)狀態(tài)字,由于計(jì)算狀態(tài)字的使用的是UINTPTR,狀態(tài)字可以是32位、也可以是64位。后文,我們默認(rèn)以32位進(jìn)行講解。宏BITMAP_FIRST_WORD_MASK傳入的參數(shù)是位操作的開(kāi)始bit位數(shù),用于計(jì)算需要進(jìn)行位操作的掩碼,從開(kāi)始位全部是1,宏BITMAP_LAST_WORD_MASK傳入的參數(shù)是位操作的結(jié)束bit位數(shù),用于計(jì)算需要進(jìn)行位操作的掩碼,結(jié)束位之前全部是1。宏BITMAP_NUM_WORDS傳入位數(shù),計(jì)算狀態(tài)字的數(shù)量。

  1. #define _ONE(x) (1 + ((x) - (x))) 
  2.  #define BIT(n)  (1U << (n)) 
  3.  #define BIT_GET(x, bit) ((x) & (_ONE(x) << (bit))) 
  4.  #define BIT_SHIFT(x, bit) (((x) >> (bit)) & 1) 
  5.  #define BITS_GET(x, high, low) ((x) & (((_ONE(x) << ((high) + 1)) - 1) & ~((_ONE(x) << (low)) - 1))) 
  6.  #define BITS_SHIFT(x, high, low) (((x) >> (low)) & ((_ONE(x) << ((high) - (low) + 1)) - 1)) 
  7.  #define BIT_SET(x, bit) (((x) & (_ONE(x) << (bit))) ? 1 : 0) 
  8.  #define BITMAP_BITS_PER_WORD (sizeof(UINTPTR) * 8) 
  9.  #define BITMAP_NUM_WORDS(x) (((x) + BITMAP_BITS_PER_WORD - 1) / BITMAP_BITS_PER_WORD) 
  10.  #define BITMAP_WORD(x) ((x) / BITMAP_BITS_PER_WORD) 
  11.  #define BITMAP_BIT_IN_WORD(x) ((x) & (BITMAP_BITS_PER_WORD - 1)) 
  12.  #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITMAP_BITS_PER_WORD)) 
  13.  #define BITMAP_LAST_WORD_MASK(nbits) \ 
  14.      (((nbits) % BITMAP_BITS_PER_WORD) ? (1UL << ((nbits) % BITMAP_BITS_PER_WORD)) - 1 : ~0UL) 
  15.  #define BITMAP_BITS_PER_INT (sizeof(INTPTR) * 8) 
  16.  #define BITMAP_BIT_IN_INT(x) ((x) & (BITMAP_BITS_PER_INT - 1)) 
  17.  #define BITMAP_INT(x) ((x) / BITMAP_BITS_PER_INT) 
  18.  #define BIT_MASK(x) (((x) >= sizeof(UINTPTR) * 8) ? (0UL - 1) : ((1UL << (x)) - 1)) 

2 位操作常用功能

OpenHarmony鴻蒙輕內(nèi)核的位操作模塊提供標(biāo)志位的置1和清0操作,可以改變標(biāo)志位的內(nèi)容,同時(shí)還提供獲取狀態(tài)字中標(biāo)志位為1的最高位和最低位的功能。用戶也可以對(duì)系統(tǒng)的寄存器進(jìn)行位操作。位操作提供了7個(gè)API,進(jìn)行置1、清0、獲取為1的最高、最低位等操作,如下:

下面,我們剖析下位操作的源代碼。

2.1 LOS_BitmapSet()對(duì)狀態(tài)字的某一標(biāo)志位進(jìn)行置1操作

對(duì)狀態(tài)字的某一標(biāo)志位進(jìn)行置1操作。我們先看看傳入的參數(shù),需要的2個(gè)參數(shù)分別是:需要改變bit位內(nèi)容的狀態(tài)字UINT32 *bitmap,需要改變的bit位位數(shù)UINT16 pos。

代碼很簡(jiǎn)單,首先進(jìn)行基礎(chǔ)的校驗(yàn),如果狀態(tài)字為空,則返回。然后計(jì)算pos & OS_BITMAP_MASK,只取二進(jìn)制的低5位,最大位值為31,避免左移的時(shí)候發(fā)生溢出。1U << (pos & OS_BITMAP_MASK)就是需要改變內(nèi)容的狀態(tài)字的bit位,通過(guò)按位或運(yùn)算設(shè)置狀態(tài)字UINT32 *bitmap的指定bit位的內(nèi)容為1。

  1. VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos) 
  2.     if (bitmap == NULL) { 
  3.         return
  4.     } 
  5.  
  6.     *bitmap |= 1U << (pos & OS_BITMAP_MASK); 

2.2 LOS_BitmapClr()對(duì)狀態(tài)字的某一標(biāo)志位進(jìn)行清0操作

對(duì)狀態(tài)字的某一標(biāo)志位進(jìn)行清0操作,代碼和置1操作對(duì)應(yīng),比較簡(jiǎn)單,~(1U << (pos & OS_BITMAP_MASK))表示需要改變內(nèi)容的狀態(tài)字的bit位為0,其余位為1,然后通過(guò)按位與運(yùn)算設(shè)置狀態(tài)字UINT32 *bitmap的指定bit位的內(nèi)容為0。

  1. VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos) 
  2.     if (bitmap == NULL) { 
  3.         return
  4.     } 
  5.  
  6.     *bitmap &= ~(1U << (pos & OS_BITMAP_MASK)); 

2.3 LOS_HighBitGet()獲取狀態(tài)字中為1的最高位

代碼中CLZ(bitmap)是宏,展開(kāi)為(__builtin_clz(bitmap)),這是編譯器內(nèi)置的高效位運(yùn)算的庫(kù)函數(shù),clz是count leading zeros的縮寫,就是統(tǒng)計(jì)二進(jìn)制數(shù)值中高位區(qū)開(kāi)頭的全是0的數(shù)目。使用OS_BITMAP_MASK減去該值,結(jié)果就是狀態(tài)字中的1的最高位。

  1. UINT16 LOS_HighBitGet(UINT32 bitmap) 
  2.     if (bitmap == 0) { 
  3.         return LOS_INVALID_BIT_INDEX; 
  4.     } 
  5.  
  6.     return (OS_BITMAP_MASK - CLZ(bitmap)); 

2.4 LOS_LowBitGet()獲取狀態(tài)字中為1的最低位

代碼其中CTZ(bitmap)是宏,展開(kāi)為(__builtin_ctz(value)),這是編譯器內(nèi)置的高效位運(yùn)算的庫(kù)函數(shù),ctz是count trailing zeros的縮寫,就是統(tǒng)計(jì)二進(jìn)制數(shù)值中低位區(qū)結(jié)尾的全是0的數(shù)目,該結(jié)果就是狀態(tài)字中的1的最低位。

  1. UINT16 LOS_LowBitGet(UINT32 bitmap) 
  2.     if (bitmap == 0) { 
  3.         return LOS_INVALID_BIT_INDEX; 
  4.     } 
  5.  
  6.     return CTZ(bitmap); 

2.5 LOS_BitmapSetNBits()對(duì)狀態(tài)字的連續(xù)標(biāo)志位進(jìn)行置1操作

可以使用LOS_BitmapSetNBits()函數(shù)對(duì)狀態(tài)字的連續(xù)比特位進(jìn)行置1操作,第一個(gè)參數(shù)是需要改變bit位內(nèi)容的狀態(tài)字UINT32 *bitmap,第二個(gè)參數(shù)是需要置1的bit位開(kāi)始數(shù)start,第三個(gè)參數(shù)是需要置1的數(shù)量numsSet。由于bit位開(kāi)始數(shù)start并沒(méi)有限制在[0,31],所以實(shí)際上設(shè)置的可能是UINT32 *bitmap狀態(tài)字后面的狀態(tài)字,需要根據(jù)業(yè)務(wù)實(shí)際情況進(jìn)行設(shè)置,避免覆寫其他內(nèi)存。同樣,需要置1的數(shù)量numsSet也可能跨多個(gè)狀態(tài)字。如圖所示:

我們看下代碼,

⑴處計(jì)算出需要操作的狀態(tài)字,其中BITMAP_WORD(start)計(jì)算相對(duì)狀態(tài)字bitmap需要偏移的數(shù)量,如果start處于區(qū)間[0,31],BITMAP_WORD(start)等于0,操作的就是狀態(tài)字bitmap。如果start處于區(qū)間[32,63],BITMAP_WORD(start)等于1,操作的就是狀態(tài)字bitmap后面的第一個(gè)狀態(tài)字,以此類推。

⑵處size可以和bit位開(kāi)始數(shù)start結(jié)合來(lái)理解,size就是需要置1的bit位結(jié)束位數(shù)。

⑶處需要置1操作的bit位的位數(shù)。

⑷是對(duì)應(yīng)需要置1操作的bit位的掩碼。

⑸處如果條件成立,說(shuō)明需要置1操作需要跨多個(gè)狀態(tài)字進(jìn)行操作,代碼會(huì)一個(gè)狀態(tài)字處理完畢,再去處理下一個(gè)狀態(tài)字。

⑹處把當(dāng)前狀態(tài)字的相應(yīng)的bit位進(jìn)行置1操作,然后執(zhí)行⑺把剩余需要置1的位數(shù)減去已經(jīng)置1的位數(shù)。

⑻處更新bitsToSet和maskToSet,然后指針p指向下一個(gè)狀態(tài)字。

⑼處如果需要置1的位數(shù)大于0,并且此時(shí)已經(jīng)可以在一個(gè)狀態(tài)字內(nèi)完成操作,執(zhí)行⑽處計(jì)算需要置1操作的掩碼,從bit開(kāi)始位到結(jié)束位需要進(jìn)行置1。

⑾處代碼執(zhí)行置1操作,完成對(duì)狀態(tài)字的連續(xù)標(biāo)志位進(jìn)行置1操作。

  1. VOID LOS_BitmapSetNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsSet) 
  2. ⑴  UINTPTR *p = bitmap + BITMAP_WORD(start); 
  3. ⑵  const UINT32 size = start + numsSet; 
  4. ⑶  UINT16 bitsToSet = BITMAP_BITS_PER_WORD - (start % BITMAP_BITS_PER_WORD); 
  5. ⑷  UINTPTR maskToSet = BITMAP_FIRST_WORD_MASK(start); 
  6.  
  7. ⑸  while (numsSet > bitsToSet) { 
  8. ⑹      *p |= maskToSet; 
  9. ⑺      numsSet -= bitsToSet; 
  10. ⑻      bitsToSet = BITMAP_BITS_PER_WORD; 
  11.         maskToSet = OS_BITMAP_WORD_MASK; 
  12.         p++; 
  13.     } 
  14. ⑼  if (numsSet) { 
  15. ⑽      maskToSet &= BITMAP_LAST_WORD_MASK(size); 
  16.         *p |= maskToSet; 
  17.     } 

2.6 LOS_BitmapClrNBits()對(duì)狀態(tài)字的連續(xù)標(biāo)志位進(jìn)行清0操作

可以使用LOS_BitmapClrNBits()函數(shù)對(duì)狀態(tài)字的連續(xù)比特位進(jìn)行清0操作,第一個(gè)參數(shù)是需要改變bit位內(nèi)容的狀態(tài)字UINT32 *bitmap,第二個(gè)參數(shù)是需要清0的bit位開(kāi)始數(shù)start,第三個(gè)參數(shù)是需要清0的數(shù)量numsClear。該函數(shù)是函數(shù)LOS_BitmapSetNBits()的反向操作,代碼解釋可以參考函數(shù)LOS_BitmapSetNBits()。

  1. VOID LOS_BitmapClrNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsClear) 
  2.     UINTPTR *p = bitmap + BITMAP_WORD(start); 
  3.     const UINT32 size = start + numsClear; 
  4.     UINT16 bitsToClear = BITMAP_BITS_PER_WORD - (start % BITMAP_BITS_PER_WORD); 
  5.     UINTPTR maskToClear = BITMAP_FIRST_WORD_MASK(start); 
  6.  
  7.     while (numsClear >= bitsToClear) { 
  8.         *p &= ~maskToClear; 
  9.         numsClear -= bitsToClear; 
  10.         bitsToClear = BITMAP_BITS_PER_WORD; 
  11.         maskToClear = OS_BITMAP_WORD_MASK; 
  12.         p++; 
  13.     } 
  14.     if (numsClear) { 
  15.         maskToClear &= BITMAP_LAST_WORD_MASK(size); 
  16.         *p &= ~maskToClear; 
  17.     } 

2.7 LOS_BitmapFfz()獲取從最低有效位開(kāi)始的第一個(gè)0的bit位

可以使用LOS_BitmapFfz()函數(shù)獲取從最低有效位開(kāi)始的第一個(gè)0的bit位位數(shù),第一個(gè)參數(shù)是需要改變bit位內(nèi)容的狀態(tài)字UINT32 *bitmap,第二個(gè)參數(shù)numBits表示最大的位數(shù),對(duì)返回值進(jìn)行限制,需要在指定的位數(shù)內(nèi)找到符合條件的位數(shù),否則返回-1。

在看函數(shù)代碼之前,先了解下Ffz()函數(shù),如下:調(diào)用內(nèi)嵌函數(shù)__builtin_ffsl()可以獲取一個(gè)unsigned long類型數(shù)字的二進(jìn)制形式的從左開(kāi)始的第一個(gè)1的位數(shù),這個(gè)位數(shù)從1開(kāi)始計(jì)數(shù)。比如對(duì)于二進(jìn)制數(shù)字0110,該函數(shù)會(huì)返回2。在下面的函數(shù)中,給函數(shù)__builtin_ffsl()傳入的參數(shù)進(jìn)行了取反,并減去了1,所以Ffz()函數(shù)返回一個(gè)數(shù)字從左開(kāi)始的第一個(gè)0的位數(shù),這個(gè)位數(shù)從0開(kāi)始計(jì)數(shù)。

  1. /* find first zero bit starting from LSB */ 
  2. STATIC INLINE UINT16 Ffz(UINTPTR x) 
  3.     return __builtin_ffsl(~x) - 1; 

我們接著看下函數(shù)LOS_BitmapFfz()的代碼。⑴處根據(jù)位數(shù)numBits計(jì)算出對(duì)應(yīng)的狀態(tài)字的數(shù)量,然后依次循環(huán)每一個(gè)狀態(tài)字,⑵處如果狀態(tài)字全為1,則繼續(xù)循環(huán),否則執(zhí)行⑶。執(zhí)行到⑶說(shuō)明,,前面有i個(gè)狀態(tài)字的各個(gè)位全為1。i * BITMAP_BITS_PER_WORD + Ffz(bitmap[i])就表示各個(gè)狀態(tài)字的二進(jìn)制位中,從左到右第一個(gè)0的位置。⑷處如果獲取的位數(shù)小于第二個(gè)參數(shù),則返回獲取的位數(shù),否則返回-1。如下圖所示:

源代碼如下:

  1. INT32 LOS_BitmapFfz(UINTPTR *bitmap, UINT32 numBits) 
  2.     INT32 bit, i; 
  3.  
  4. ⑴  for (i = 0; i < BITMAP_NUM_WORDS(numBits); i++) { 
  5. ⑵      if (bitmap[i] == OS_BITMAP_WORD_MASK) { 
  6.             continue
  7.         } 
  8. ⑶      bit = i * BITMAP_BITS_PER_WORD + Ffz(bitmap[i]); 
  9. ⑷      if (bit < numBits) { 
  10.             return bit
  11.         } 
  12.         return -1; 
  13.     } 
  14.     return -1; 

小結(jié)

本文帶領(lǐng)大家一起剖析了鴻蒙輕內(nèi)核的位操作模塊的源代碼。

想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

 

責(zé)任編輯:jianghua 來(lái)源: 鴻蒙社區(qū)
相關(guān)推薦

2021-05-12 09:45:20

鴻蒙HarmonyOS應(yīng)用

2021-04-30 15:06:34

鴻蒙HarmonyOS應(yīng)用

2021-05-10 15:05:56

鴻蒙HarmonyOS應(yīng)用

2021-11-08 15:06:15

鴻蒙HarmonyOS應(yīng)用

2022-03-11 20:23:14

鴻蒙源碼分析進(jìn)程管理

2022-04-13 11:02:12

鴻蒙事件模塊事件Event

2022-03-03 18:28:28

Harmony進(jìn)程任務(wù)管理模塊

2022-01-12 10:50:23

鴻蒙HarmonyOS應(yīng)用

2022-01-10 15:31:44

鴻蒙HarmonyOS應(yīng)用

2021-06-04 09:57:49

鴻蒙HarmonyOS應(yīng)用

2021-11-05 15:00:33

鴻蒙HarmonyOS應(yīng)用

2021-05-17 09:28:59

鴻蒙HarmonyOS應(yīng)用

2021-06-04 14:15:10

鴻蒙HarmonyOS應(yīng)用

2021-05-08 15:14:50

鴻蒙HarmonyOS應(yīng)用

2021-05-25 09:28:34

鴻蒙HarmonyOS應(yīng)用

2022-04-13 11:12:43

鴻蒙輕內(nèi)核信號(hào)量模塊操作系統(tǒng)

2021-10-20 16:08:57

鴻蒙HarmonyOS應(yīng)用

2021-05-31 20:30:55

鴻蒙HarmonyOS應(yīng)用

2021-12-01 15:59:22

鴻蒙HarmonyOS應(yīng)用

2022-03-31 16:26:49

鴻蒙源碼分析進(jìn)程管理
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 91国产视频在线观看 | 人人操日日干 | 伊人在线| 免费日韩av| 欧美日韩亚洲国产 | 欧美999| 久草久草久草 | 又黄又爽的网站 | 亚洲欧美综合精品久久成人 | 日韩av啪啪网站大全免费观看 | 在线视频 亚洲 | 欧美高清视频一区 | 国产精品精品视频 | 国内精品久久精品 | av中文字幕在线播放 | 国产黄色大片网站 | 97精品久久 | 国产高清免费 | 日本不卡一区 | 国产一二三视频在线观看 | 亚洲精品久久久久久久久久久久久 | 九九热精品视频 | 欧美激情一区二区 | 日本一区二区高清不卡 | 亚洲黄色视屏 | 色视频一区二区 | 亚洲国产aⅴ成人精品无吗 综合国产在线 | 精品国产aⅴ | 亚洲网址 | 欧美一区2区三区4区公司二百 | 一级黄色录像片子 | www.干| 久久久精彩视频 | 国产成人精品av | 成人免费观看男女羞羞视频 | 亚洲一区在线日韩在线深爱 | 99精品免费 | 久久久激情 | 亚洲社区在线 | 国产激情一区二区三区 | 国产精品视频500部 a久久 |