rte_ring
DPDK应用使用ring来管理各种对象。ring是一个FIFO队列,大小固定,采用无锁机制。
可以批量进出队列。具体描述如下:
-
FIFO
-
Maximum size is fixed, the pointers are stored in a table
-
Lockless implementation
-
Multi-consumer or single-consumer dequeue
-
Multi-producer or single-producer enqueue
-
Bulk dequeue - Dequeues the specified count of objects if successful; otherwise
fails
-
Bulk enqueue - Enqueues the specified count of objects if successful; otherwise
fails
-
Burst dequeue - Dequeue the maximum available objects if the specified count
cannot be fulfilled
-
Burst enqueue - Enqueue the maximum available objects if the specified count
cannot be fulfilled
实现原理:
以如队为例,对ring的操作需要在一个循环里。
1 prod_head = ring->prod_head 首先将ring结构中的prod_head保存到本地。
2 然后执行CAS指令:Compare and swap(CAS) : 如果本地prod_head不等于ring_prod_head,失败,回到1,失败说明之前正有其它线程也在操作该队列,且先成功执行了CAS。
3 否则,将ring->prod_head设置为下一个元素的位置prod_next 该设置过程是CAS的一部分,CAS执行成功,就会原子的更改ring结构中的prod_head.这样如果有另一个线程执行CAS操作,就会失败。执行成功的线程就可以将数据放到它本地prod_head 到prod_next之间了。
有两个线程都获取了ring的prod_head.
core1 CAS成功,ring结构的prod_head变为了core1的prod_next.
core2失败,重新执行步骤1,此时它获取到的 prod_head就跟core1不同了。
core1 将自己的数据放入prod_head和prod_next之间,如 obj4,没有竞争。
core2 放入它自己的prod_head和prod_next之间,如obj5,也没有竞争。