/****************************************************************************** **函数名称: ring_mpop **功 能: 同时弹出多个数据 **输入参数: ** rq: 队列 ** num: 弹出n个地址 **输出参数: ** addr: 指针数组 **返 回: 数据实际条数 **实现描述: 无锁编程 **注意事项: **作 者: # Qifeng.zou # 2015.05.05 # ******************************************************************************/ int ring_mpop(ring_t *rq, void **addr, unsigned int num) { int succ; unsigned int cons_head, cons_next, prod_tail, i; /* > 申请队列空间 */ do { cons_head = rq->cons.head; prod_tail = rq->prod.tail; if (num > prod_tail - cons_head) { return 0; /* 无数据 */ } cons_next = cons_head + num; succ = atomic32_cmp_and_set(&rq->cons.head, cons_head, cons_next); } while(0 == succ); /* > 地址弹出队列 */ for (i=0; i<num; ++i) { addr[i] = (void *)rq->data[(cons_head+i) & rq->mask]; } /* > 判断是否其他线程也在进行处理, 是的话, 则等待对方完成处理 */ while (rq->cons.tail != cons_head) { NULL; } rq->cons.tail = cons_next; atomic32_sub(&rq->num, num); /* 计数 */ return num; }
inline int pkt_fifo_get(pkt_fifo_t *fifo, pkt_node_t *node) { uint32_t out; uint32_t size; uint32_t count; pkt_buf_t *pkt; if (fifo == NULL || node == NULL) { applog(APP_LOG_LEVEL_DEBUG, APP_VPU_LOG_MASK_WORKER, "pkt_fifo_get fifo: %p, node: %p", fifo, node); return -1; //no data in fifo } out = fifo->out; size = fifo->size; count = atomic32_read(&fifo->count); pkt = fifo->pkt; if (count <= 0) { return -2; } if (unlikely(out >= size)) { applog(APP_LOG_LEVEL_DEBUG, APP_VPU_LOG_MASK_WORKER, "pkt_fifo_get out: %u, size: %u", out, size); return -3; } node->pkt = pkt[out].pkt; node->pkt_len = pkt[out].pkt_len; atomic32_sub(&fifo->count, 1); out = out + 1; if (unlikely(out >= size)) { out = 0; } fifo->out = out; return 0; }