rte_ring是一个无锁队列,无锁队列的出队入队操作是rte_ring实现的关键。因此,本文主要讲解dpdk是怎样使用无锁机制实现rte_ring的多生产者入队操作。
rte_atomic32_cmpset()称为CAS(compare and set)操作,是无锁队列实现的关键,实现的伪代码如下:
cmpset(cur, old, next) { if (cur == old) { cur = next; } }
rte_atomic32_cmpset()实现基于gcc内置CAS操作:
__sync_bool_compare_and_swap()
rte_compiler_barrier()
该操作主要保证此语句后的代码执行顺序不被编译器优化。
多生产者入队(mp-enqueue)
/* * 该函数保证多个生产者按顺序入队,而第一步则是给多个生产者排序的过程, * 最先移动r->prod.head位置的生产者排序最靠前,排序靠前的生产者也可以 * 优先执行第二步和第三步。 */ mp_do_enqueue(r, obj, n) { /* 1. 抢占移动prod.head */ do { prod_head = r->prod.head; cons_tail = r->cons.tail; /* check that we have enough room in ring */ CHECK_REMAIN_ROOM() prod_next = prod_head + n; success = rte_atomic32_cmpset(&r->prod.head, prod_head, prod_next); } while (success == 0); /* 2. 元素插入合适位置 */ ENQUEUE_PTRS(); rte_compiler_barrier(); /* 3. 顺序移动prod.tail */ while (unlikely(r->prod.tail != prod_head)) rte_pause(); r->prod.tail = prod_next; }
时间: 2024-10-05 23:50:08