Last active
February 26, 2024 02:16
-
-
Save wsd1/b57ce4946720084549dd06254493827c to your computer and use it in GitHub Desktop.
简单精炼的queue实现
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
From https://github.com/JSchaenzle/c-message-queue | |
20240224: Add 2 APIs | |
20240226: shxt.Bugs. (p_queue->read_idx)++ & (capacity - 1) => (p_queue->read_idx)++ % capacity | |
*/ | |
#ifndef QUEUE_H | |
#define QUEUE_H | |
#include <stdint.h> | |
#include <stdbool.h> | |
#include <string.h> | |
enum enqueue_result { | |
ENQUEUE_RESULT_SUCCESS, | |
ENQUEUE_RESULT_FULL, | |
}; | |
enum dequeue_result { | |
DEQUEUE_RESULT_SUCCESS, | |
DEQUEUE_RESULT_EMPTY, | |
}; | |
#define ARRAY_LENGTH(A) (sizeof(A)/sizeof((A)[0])) | |
#define QUEUE_DECLARATION(NAME, ITEM_TYPE, NUM_ITEMS) \ | |
struct NAME { \ | |
uint16_t read_idx; \ | |
uint16_t write_idx; \ | |
ITEM_TYPE items[NUM_ITEMS]; \ | |
}; \ | |
void NAME ## _init(struct NAME * p_queue); \ | |
enum enqueue_result NAME ##_enqueue(struct NAME * p_queue, ITEM_TYPE * p_new_item); \ | |
enum dequeue_result NAME ##_dequeue(struct NAME * p_queue, ITEM_TYPE * p_item_out); \ | |
enum enqueue_result NAME ##_enqueue_allc(struct NAME * p_queue, ITEM_TYPE * p_new_item);\ | |
enum dequeue_result NAME ##_dequeue_ptr(struct NAME * p_queue, ITEM_TYPE * p_item_out); \ | |
bool NAME ##_is_empty(struct NAME * p_queue); | |
#define QUEUE_DEFINITION(NAME, ITEM_TYPE) \ | |
void NAME ## _init(struct NAME * p_queue) \ | |
{ \ | |
p_queue->read_idx = 0; \ | |
p_queue->write_idx = 0; \ | |
} \ | |
\ | |
enum enqueue_result NAME ##_enqueue(struct NAME * p_queue, ITEM_TYPE * p_new_item) { \ | |
uint16_t elements_in = p_queue->write_idx - p_queue->read_idx; \ | |
\ | |
size_t const capacity = ARRAY_LENGTH(p_queue->items); \ | |
if (elements_in == capacity) { \ | |
return ENQUEUE_RESULT_FULL; \ | |
} \ | |
\ | |
uint16_t i = (p_queue->write_idx)++ % capacity ; \ | |
p_queue->items[i] = *p_new_item; \ | |
return ENQUEUE_RESULT_SUCCESS; \ | |
} \ | |
\ | |
enum dequeue_result NAME ##_dequeue(struct NAME * p_queue, ITEM_TYPE * p_item_out) { \ | |
uint16_t elements_in = p_queue->write_idx - p_queue->read_idx; \ | |
size_t const capacity = ARRAY_LENGTH(p_queue->items); \ | |
\ | |
if(elements_in == 0) { \ | |
return DEQUEUE_RESULT_EMPTY; \ | |
} \ | |
\ | |
uint16_t i = (p_queue->read_idx)++ % capacity ; \ | |
*p_item_out = p_queue->items[i]; \ | |
\ | |
return DEQUEUE_RESULT_SUCCESS; \ | |
} \ | |
\ | |
enum enqueue_result NAME ##_enqueue_alloc(struct NAME * p_queue, ITEM_TYPE ** p_item) {\ | |
uint16_t elements_in = p_queue->write_idx - p_queue->read_idx; \ | |
\ | |
size_t const capacity = ARRAY_LENGTH(p_queue->items); \ | |
if (elements_in == capacity) { \ | |
return ENQUEUE_RESULT_FULL; \ | |
} \ | |
\ | |
uint16_t i = (p_queue->write_idx)++ % capacity ; \ | |
*p_item = &(p_queue->items[i]); \ | |
return ENQUEUE_RESULT_SUCCESS; \ | |
} \ | |
\ | |
enum dequeue_result NAME ##_dequeue_ptr(struct NAME * p_queue, ITEM_TYPE ** p_item_out){\ | |
uint16_t elements_in = p_queue->write_idx - p_queue->read_idx; \ | |
size_t const capacity = ARRAY_LENGTH(p_queue->items); \ | |
\ | |
if(elements_in == 0) { \ | |
return DEQUEUE_RESULT_EMPTY; \ | |
} \ | |
\ | |
uint16_t i = (p_queue->read_idx)++ % capacity ; \ | |
*p_item_out = &(p_queue->items[i]); \ | |
\ | |
return DEQUEUE_RESULT_SUCCESS; \ | |
} \ | |
\ | |
bool NAME ##_is_empty(struct NAME * p_queue) { \ | |
return ((p_queue->write_idx - p_queue->read_idx) == 0); \ | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment