最近了解无锁队列的时候,看了这个博主的文章,感觉这个设计挺巧妙的。有些地方我不是很理解,看了好几遍才能了解,所以在代码上加上一点自己的注释。
原作者提的in out指针绕回原点,一开始我理解成in指针会到out的前面,读取的时候循环找。后来发现其实不是这样的,因为做了取模,in/out无限增长也没有关系。
---------------------
作者:海枫
来源:优快云
原文:https://blog.youkuaiyun.com/linyt/article/details/53355355
版权声明:本文为博主原创文章,转载请附上博文链接!
-------------------------
unsigned int __kfifo_put(struct kfifo *fifo,
unsigned char *buffer, unsigned int len)
{
unsigned int l;
len = min(len, fifo->size - fifo->in + fifo->out);
//这一步是取buffer长度和队列剩余长度较小值。如果len小,说明可以全部放入。如果第二参数小,
//说明只能尽量满足。
/*
* Ensure that we sample the fifo->out index -before- we
* start putting bytes into the kfifo.
*/
smp_mb();
/* first put the data starting from fifo->in to buffer end */
l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
//这个l是指in右侧的空间。同上,尽量满足。
memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);
//先填充in右侧空间。
/* then put the rest (if any) at the beginning of the buffer */
memcpy(fifo->buffer, buffer + l, len - l);
//再从头开始填充。
/*
* Ensure that we add the bytes to the kfifo -before-
* we update the fifo->in index.
*/
smp_wmb();
fifo->in += len;
//最后再偏移in。
return len;
}
unsigned int __kfifo_get(struct kfifo *fifo,
unsigned char *buffer, unsigned int len)
{
unsigned int l;
len = min(len, fifo->in - fifo->out);
/*
* Ensure that we sample the fifo->in index -before- we
* start removing bytes from the kfifo.
*/
smp_rmb();
/* first get the data from fifo->out until the end of the buffer */
l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
/* then get the rest (if any) from the beginning of the buffer */
memcpy(buffer + l, fifo->buffer, len - l);
/*
* Ensure that we remove the bytes from the kfifo -before-
* we update the fifo->out index.
*/
smp_mb();
fifo->out += len;
return len;
}
---------------------
作者:海枫
来源:优快云
原文:https://blog.youkuaiyun.com/linyt/article/details/53355355
版权声明:本文为博主原创文章,转载请附上博文链接!