zoukankan      html  css  js  c++  java
  • [linux内核][LINUX内核编程]学习笔记(二)

    linux内核————队列

    linux内核——队列

    定义:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. struct __kfifo{  
    2.     unsigned int in;  //入队偏移,写索引  
    3.     unsigned int out;  //出队偏移,读索引  
    4.     unsigned int mask;  
    5.     unsigned int esize;  
    6.     void *data;  
    7. }  


    使用:

    创建一个队列,该函数创建并初始化一个大小为size的kfifo:

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. 38 int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,  
    2. 39                 size_t esize, gfp_t gfp_mask)  
    3. 40 {  
    4.   
    5. 45         size = roundup_pow_of_two(size);  
    6. 46   
    7. 47         fifo->in = 0;  
    8. 48         fifo->out = 0;  
    9. 49         fifo->esize = esize;  
    10. 50   
    11. 51         if (size < 2) {  
    12. 52                 fifo->data = NULL;  
    13. 53                 fifo->mask = 0;  
    14. 54                 return -EINVAL;  
    15. 55         }  
    16. 56   
    17. 57         fifo->data = kmalloc(size * esize, gfp_mask);  
    18. 58   
    19. 59         if (!fifo->data) {  
    20. 60                 fifo->mask = 0;  
    21. 61                 return -ENOMEM;  
    22. 62         }  
    23. 63         fifo->mask = size - 1;  
    24. 64   
    25. 65         return 0;  
    26. 66 }  


    判断一个整数是否是2的整数次幂

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. static inline int is_power_of_2(unsigned long long n)  
    2. {  
    3. return (n!=0 &&(n&(n-1)==0))  
    4. }  


    推入数据到队列的方法是kfifo_in()函数

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1.  102 static void kfifo_copy_in(struct __kfifo *fifo, const void *src,  
    2. 103                 unsigned int len, unsigned int off)  
    3. 104 {  
    4. 105         unsigned int size = fifo->mask + 1;  
    5. 106         unsigned int esize = fifo->esize;  
    6. 107         unsigned int l;  
    7. 108   
    8. 109         off &= fifo->mask;  //该操作从数学角度将就是对长度fifo->mask的取模运算   
    9. 110         if (esize != 1) {  
    10. 111                 off *= esize;  
    11. 112                 size *= esize;  
    12. 113                 len *= esize;  
    13. 114         }  
    14. 115         l = min(len, size - off);  //size-off代表的含义是当前in到缓冲区尾的大小,  
    15. 116     /* 
    16.             先从buffer中拷贝l字节到缓冲区剩余空间,l<=len,也<=从real_in开始到缓冲区结尾的空间  
    17.             所以这个copy可能没拷贝完,但是不会造成缓冲区越界  
    18.         */  
    19. 117         memcpy(fifo->data + off, src, l);    
    20.         /* 
    21.             len > l时,拷贝buffer中剩余的内容,其实地址当然为buffer + l,而剩余的大小为len - l  
    22.             当len == l时,下面的memcpy啥都不干 
    23.         */  
    24. 118         memcpy(fifo->data, src + l, len - l);  
    25. 123         smp_wmb();  
    26. 124 }  
    27. 125   
    28. 126 unsigned int __kfifo_in(struct __kfifo *fifo,  
    29. 127                 const void *buf, unsigned int len)  //buf指向的是请求入队的缓冲区,len表示的是请求写入的大小  
    30. 128 {  
    31. 129         unsigned int l;  
    32. 131         l = kfifo_unused(fifo);//计算队列中剩余空间的大小,fifo->size-(fifo->in-fifo->out)  
    33. 132         if (len > l)  
    34. 133                 len = l;  
    35. 135         kfifo_copy_in(fifo, buf, len, fifo->in);  
    36. 136         fifo->in += len;  
    37. 137         return len;  
    38. 138 }  


     kfifo的巧妙之处在于in和out定义为无符号类型,在put和get时,in和out都是增加,当达到最大值时,产生溢出,使得从0开始,进行循环使用

  • 相关阅读:
    redis性能优化、内存分析及优化
    代码质量审核和管理工具分析比较
    SpringBoot集成Nacos
    Navicat,Dbeaver,heidiSql,DataGrip数据库连接工具比较
    python报错:
    6.Python深入_内存管理
    Win7安装python第三方模块objgraph报错
    5.Python深入_装饰器
    4.Python深入_闭包
    1.Python深入_对象的属性
  • 原文地址:https://www.cnblogs.com/zhiliao112/p/4232162.html
Copyright © 2011-2022 走看看