无锁ring-buffer实现原理

嗯...这个东西...Linux 2 .6 .2 8 ...当时推出...通用环形缓冲区...但是...块...太多...块...导致...嗯...性能不太好...
后来...DPDK...用了...Steven Rostedt提到的...无锁...算法...这个算法...嗯...写入时...无锁...所以...内核...收集信息...很快...非常高效...
这篇文章...我们来说说...这个原理...那个一般...在Linux上...用法...内核...执行收集...写入操作...不要拖延...事件处理...读取操作...用户空间...要求...低...
Linux内核...提供环形缓冲区...环形...双向链表...头指针...尾指针...写入...尾指针...读取...头指针...但是问题来了...已经满了...写入者...可以...覆盖...头指针指向的页面...读取数据会混乱...
所以... Rostedt的算法…呃…提供…一个独立的阅读页面…完全独立…不在链表上…所以…阅读时…不用担心…被写入破坏…
唯一的缺点是…呃…阅读器处理完之后…要改变页面…必须…插到队列中指针后面…并去掉旧的头…创建一个新的阅读器…移动…这个过程…阻塞…以保证安全…
Rostedt的…结构…嗯…H是header...指针...
当有多个writer...writerA...可以被writerB中断...A只需...在B开始之前完成...这个...可以使用中断堆栈...机制...writer初始化...在尾指针之后...保留空间...完成写入...更新尾指针...有一个提交指针...标记最后...写入完成...
清空循环缓冲区...阅读器页...尾页...提交页...可以...指向同一个地方...
清除写入块...原子操作使用 cmpxchg()... 该算法...还假设...双向链表指针... 4 字节对齐...低 2 位...用作标志...
HEADER...指向当前头页... UPDATE...指向写入...或...将被设置为头...
读者页...消耗后...头页...将下降...并成为新的阅读页...通过下一个指针的 HEADER 位...读者可以使用 cmpxchg()...来请求此 HEADER 标志...确保...页面未被修改...
writers...将标志设置为UPDATE...或清除...以指示...页面已被修改...比较cmpxchg()...失败...reader...只需找到...一个新的主页...避免使用块...
writers...更新新的尾页...检查下一个指针的HEADER标志...如果设置...更新为UPDATE...指示...页面已检查... cmpxchg()...错误...只是...删除...新主页面...给读者...这个状态...表示...环快满了...只剩下一页...写入数据...
嗯...就这样...就这样了...

Linux内核API完全参考手册目录