Example #1
0
/******************************************************************************
 **函数名称: 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;
}
Example #2
0
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;
}