Linux内核对fifo编程,[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开始,进行循环使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值