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; }