[LINUX核心編程]學習筆記(二)

來源:互聯網
上載者:User

linux核心————隊列

linux核心——隊列

定義:

struct __kfifo{unsigned int in;  //入隊位移,寫索引unsigned int out;  //出隊位移,讀索引unsigned int mask;unsigned int esize;void *data;}

使用:

建立一個隊列,該函數建立並初始化一個大小為size的kfifo:

 38 int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, 39                 size_t esize, gfp_t gfp_mask) 40 { 45         size = roundup_pow_of_two(size); 46  47         fifo->in = 0; 48         fifo->out = 0; 49         fifo->esize = esize; 50  51         if (size < 2) { 52                 fifo->data = NULL; 53                 fifo->mask = 0; 54                 return -EINVAL; 55         } 56  57         fifo->data = kmalloc(size * esize, gfp_mask); 58  59         if (!fifo->data) { 60                 fifo->mask = 0; 61                 return -ENOMEM; 62         } 63         fifo->mask = size - 1; 64  65         return 0; 66 }

判斷一個整數是否是2的整數次冪

 static inline int is_power_of_2(unsigned long long n) {return (n!=0 &&(n&(n-1)==0)) }

推入資料到隊列的方法是kfifo_in()函數

 102 static void kfifo_copy_in(struct __kfifo *fifo, const void *src,103                 unsigned int len, unsigned int off)104 {105         unsigned int size = fifo->mask + 1;106         unsigned int esize = fifo->esize;107         unsigned int l;108 109         off &= fifo->mask;  //該操作從數學角度將就是對長度fifo->mask的模數運算 110         if (esize != 1) {111                 off *= esize;112                 size *= esize;113                 len *= esize;114         }115         l = min(len, size - off);  //size-off代表的含義是當前in到緩衝區尾的大小,116 /*先從buffer中拷貝l位元組到緩衝區剩餘空間,l<=len,也<=從real_in開始到緩衝區結尾的空間 所以這個copy可能沒拷貝完,但是不會造成緩衝區越界 */117         memcpy(fifo->data + off, src, l);  /*len > l時,拷貝buffer中剩餘的內容,其真實位址當然為buffer + l,而剩餘的大小為len - l 當len == l時,下面的memcpy啥都不幹*/118         memcpy(fifo->data, src + l, len - l);123         smp_wmb();124 }125 126 unsigned int __kfifo_in(struct __kfifo *fifo,127                 const void *buf, unsigned int len)  //buf指向的是請求入隊的緩衝區,len表示的是請求寫入的大小128 {129         unsigned int l;131         l = kfifo_unused(fifo);//計算隊列中剩餘空間的大小,fifo->size-(fifo->in-fifo->out)132         if (len > l)133                 len = l;135         kfifo_copy_in(fifo, buf, len, fifo->in);136         fifo->in += len;137         return len;138 }

 kfifo的巧妙之處在於in和out定義為無符號類型,在put和get時,in和out都是增加,當達到最大值時,產生溢出,使得從0開始,進行迴圈使用
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.