DPDK17.02 ring 管理4 – common_ring_mc_dequeue
该函数是针对多消费者的出队函数,其调用关系如下:
1 2 3 | common_ring_mc_dequeue(struct rte_mempool *mp, void * const *obj_table, unsigned n) --> rte_ring_mc_dequeue_bulk(mp->pool_data, obj_table, n) --> __rte_ring_mc_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED) |
RTE_RING_QUEUE_FIXED 宏表示只能出队固定数量的对象,这些指定数量的对象要么全部出队,函数执行成功;要么出队0个,函数执行失败。
最新版本的DPDK 里面已经对这些出队入队函数做了简化处理,可参考《DPDK20.05 – rte_ring无锁环形队列的管理》,这里还是以DPDK 17.02 版本为例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | static inline int __attribute__((always_inline)) __rte_ring_mc_do_dequeue(struct rte_ring *r, void **obj_table, unsigned n, enum rte_ring_queue_behavior behavior) { uint32_t cons_head, prod_tail; uint32_t cons_next, entries; const unsigned max = n; int success; unsigned i, rep = 0; uint32_t mask = r->prod.mask; /* 避免无谓的 cmpset 操作,如果 n 的值为0,下面的操作也会带来性能损耗 */ if (n == 0) return 0; /* 自动移动 cons.head */ do { /* 每次循环都重新获取 n 的值,因为每次循环都有可能会修改 n 的值 */ n = max; cons_head = r->cons.head; prod_tail = r->prod.tail; /* 两个无符号整数相减,结果范围总在 0 到 size(ring) - 1 之间 */ entries = (prod_tail - cons_head); /* Set the actual entries for dequeue */ if (n > entries) { if (behavior == RTE_RING_QUEUE_FIXED) { __RING_STAT_ADD(r, deq_fail, n); return -ENOENT; } else { if (unlikely(entries == 0)){ __RING_STAT_ADD(r, deq_fail, n); return 0; } n = entries; } } /* 移动 r->cons.head 的值 */ cons_next = cons_head + n; success = rte_atomic32_cmpset(&r->cons.head, cons_head, cons_next); } while (unlikely(success == 0)); DEQUEUE_PTRS(); /* 实际的出队操作封装的宏 */ rte_smp_rmb(); /* 如果有其他的出队操作正在进行,需要等待其结束 */ while (unlikely(r->cons.tail != cons_head)) { rte_pause(); /* 设置 RTE_RING_PAUSE_REP_COUNT 的值以避免等待太长时间。 * 该方法给抢占线程一个机会能处理完对ring的出队操作 */ if (RTE_RING_PAUSE_REP_COUNT && ++rep == RTE_RING_PAUSE_REP_COUNT) { rep = 0; sched_yield(); /* 让出CPU */ } } __RING_STAT_ADD(r, deq_success, n); r->cons.tail = cons_next; return behavior == RTE_RING_QUEUE_FIXED ? 0 : n; } |
————————————————————
原创文章,转载请注明: 转载自孙希栋的博客