首页 > 系统相关 >《Linux内核设计与实现》内核数据结构6.2队列 P78-81

《Linux内核设计与实现》内核数据结构6.2队列 P78-81

时间:2022-11-13 23:14:16浏览次数:42  
标签:esize 队列 out fifo 内核 81 kfifo P78 size

队列与堆栈

队列

只允许在队列的前端(front,队头)进行删除操作,而在队列的后端(rear,队尾)进行插入操作。当队列中没有元素时,即front=rear,称为空队列。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。队列符合先进先出(FIFO—first in first out)原则

堆栈

栈:又名堆栈,只允许在栈顶插入和删除元素。栈顶是低位,栈底是高位。栈中没有元素时称为空栈,栈符合先进后出原则(LIFO,last in first out)。
操作: push入栈、pop出栈

6.2.1 kfifo入队列和出队列

 

 

(1)空的kfifo

(2)推入一个buffer后

(3)摘取一个buffer后,出口偏移(out)加上摘取的元素数目

(4)当此时put的buffer长度超出in到末尾长度时,则将剩下的移到头部去

参考:https://zhuanlan.zhihu.com/p/548021636

 

 

6.2.2 创建队列

struct __kfifo {
    unsigned int    in;   // 队列头,删除操作
    unsigned int    out;  // 队列尾,插入操作
    unsigned int    mask; // 缓存区大小,byte
    unsigned int    esize; // 缓存区元素占用的字节数,比如char时,eszie为1,int时esize为4
    void        *data;    // 存放数据的缓存区地址
};

kfifo_alloc由内核调用kmalloc_array函数来申请内存空间



int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
        size_t esize, gfp_t gfp_mask)
{
    /* 向上对齐到2的幂 */
    size = roundup_pow_of_two(size);

    fifo->in = 0;     fifo->out = 0;     fifo->esize = esize;
    if (size < 2) {         fifo->data = NULL;         fifo->mask = 0;         return -EINVAL;     }
    fifo->data = kmalloc_array(esize, size, gfp_mask);
    if (!fifo->data) {         fifo->mask = 0;         return -ENOMEM;     }     fifo->mask = size - 1;
    return 0; }

 用户申请好一个buffer,再使用kfifo_init初始化为kfifo队列

int __kfifo_init(struct __kfifo *fifo, void *buffer,
        unsigned int size, size_t esize)
{
    size /= esize;

    if (!is_power_of_2(size))
        size = rounddown_pow_of_two(size);

    fifo->in = 0;
    fifo->out = 0;
    fifo->esize = esize;
    fifo->data = buffer;

    if (size < 2) {
        fifo->mask = 0;
        return -EINVAL;
    }
    fifo->mask = size - 1;

    return 0;
}

 

6.2.7队列使用举例

(1)kfifo_in推入数据(0-31)

 

 (2)kfifo_out_peek读取第0位置的元素,但不删除,out不增加

 

(3)kfifo_out从出口偏移(out)拷贝出一个4byte

 

标签:esize,队列,out,fifo,内核,81,kfifo,P78,size
From: https://www.cnblogs.com/cai-zi/p/16887612.html

相关文章

  • MIT6.S081 Lecture1
         TRANSLATEwithxEnglishArabicHebrewPolishBulgarianHindiPortugueseCatalanHmongDawRomanianChineseSimplifiedHung......
  • Windows Docker安装和卸载(包括linux内核)
    WindowsServer安装DockerPowerShell命令(管理员)WindowsServer安装Docker(windows内核)Install-Module-NameDockerMsftProvider-RepositoryPSGallery-Force ......
  • ESP8266--SDK开发(驱动WS2812B)
    文章目录​​一、WS2812彩灯介绍​​​​二、效果展示​​​​三、七色灯代码​​​​附:彩虹七色码值​​一、WS2812彩灯介绍WS2812是一个集控制电路与发光电路于一体的智能......
  • Linux基础——内核排查过程
    根因:(内核BUG)BUG:unabletohandlekernelNULLpointerdereferenceat0000000000000019,代码调用函数assign_irq_vector报错,通过升级内核版本进行修复。解决办法:  ......
  • Linux性能优化和内核观测 - 内存篇(一)
    内存虚拟内存Linux采用的是​​虚拟内存​​机制,每个进程都有自己的虚拟内存地址空间,仅当实际使用内存的时候才会映射到物理内存地址之上。这种设计提供了物理内存的超额分......
  • Ubuntu更改默认启动内核
    参考:https://blog.csdn.net/m0_37340681/article/details/97896696因为Ubuntu保持所有以前版本的内核。更新之后,更新GRUB配置以启动最新版本,并且可以在启动时在GRUB菜单......
  • ARC081F
    首先能发现一个矩阵是合法的,当且仅当它的每一行都和第一行一样,或正好相反。充分性很显然,但是必要性我还不会()令\(s\)表示原矩阵,\(a_{i,j}=[s_{i,j}=\#]\)。构造数组\(......
  • P8817 假期计划 Sol
    看到数据范围,很容易想到平方。由于是双向边,所以很容易想到其实四个点可以被拆成两部分,两部分本质一样,可以一起处理。考虑枚举中转点\(x,y\),可以想到预处理与\(x\)距离......
  • 力扣 81. 搜索旋转排序数组 II
    81.搜索旋转排序数组II已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同。在传递给函数之前,nums 在预先未知的某个下标 k(0<=k<nums.leng......
  • 818E - Card Game Again 双指针+分解质因数
    题意:有多少种xy的选择方法,使得对于长度为n的a数组,取 a[x+1],a[x+2]...a[y-2],a[y-1]的乘积是k的倍数 思路:对于所有的x,当选择x=x+1时y=y......