快捷搜索: 王者荣耀 脱发

kfifo无锁循环队列的实现

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "kfifo2.h"

bool kfifo_init(kfifo_t *kfifo)
{
    bzero(kfifo, sizeof(kfifo_t));
    return true;
}

bool kfifo_put(kfifo_t *kfifo, kfifo_msg_t *msg)
{
    if (ES_MSG_QUEUE_SIZE - 1 == kfifo->in - kfifo->out)
    {
        return false;
    }

    memcpy(&kfifo->msg[kfifo->in % ES_MSG_QUEUE_SIZE], msg, msg->head.len + sizeof(msg->head));
    kfifo->in++;

    return true;
}

bool kfifo_get(kfifo_t *kfifo, kfifo_msg_t *msg)
{
    if (kfifo->in == kfifo->out)
    {
        return false;
    }

    memcpy(msg, &kfifo->msg[kfifo->out % ES_MSG_QUEUE_SIZE], kfifo->msg[kfifo->out % ES_MSG_QUEUE_SIZE].head.len + sizeof(msg->head));
    kfifo->out++;

    return true;
}

uint32_t kfifo_count(kfifo_t *kfifo)
{
    return kfifo->in - kfifo->out;
}

头文件:

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>
#include <semaphore.h>

#define ES_MSG_QUEUE_SIZE     	5000
#define ES_MSG_LEN            	2048

typedef struct
{
    uint32_t    msg_id;
    uint32_t    len;
}msg_head_t;

typedef struct
{
    msg_head_t  head;
    uint8_t     content[ES_MSG_LEN];
}kfifo_msg_t;

typedef struct
{
    kfifo_msg_t        msg[ES_MSG_QUEUE_SIZE];
    volatile uint32_t  in;
    volatile uint32_t  out;
}kfifo_t;

bool     kfifo_init(kfifo_t *kfifo);
bool     kfifo_put(kfifo_t *kfifo, kfifo_msg_t *msg);
bool     kfifo_get(kfifo_t *kfifo, kfifo_msg_t *msg);
uint32_t kfifo_count(kfifo_t *kfifo);
int vss_send(uint32_t msg_id, uint8_t *msg, uint16_t len, thread_t *thread)
{
    kfifo_msg_t cache;
    bool        rc;

    if (len > sizeof(cache.content))
    {
        len = sizeof(cache.content);
    }

    cache.head.len    = len;
    cache.head.msg_id = msg_id;
    memcpy(cache.content, msg, len);

    pthread_mutex_lock(&thread->kfifo_lock);
    rc = kfifo_put(&thread->kfifo, &cache);
    sem_post(&thread->sem);
    pthread_mutex_unlock(&thread->kfifo_lock);

    if (rc)
        return VSS_OK;
    return VSS_ERR_SEND;
}

uint32_t vss_recv(uint32_t *msg_id, uint8_t  *msg, uint32_t size, thread_t *thread)
{
    kfifo_msg_t cache;

again:
    if (kfifo_count(&thread->kfifo) == 0)
    {
        sem_wait(&thread->sem);
        goto again;
    }

    kfifo_get(&thread->kfifo, &cache);
    if (cache.head.len > size)
    {
        cache.head.len = size;
    }
    memcpy(msg, cache.content, cache.head.len);
    *msg_id = cache.head.msg_id;

    return cache.head.len;
}
经验分享 程序员 微信小程序 职场和发展