You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
7.5 KiB
C
120 lines
7.5 KiB
C
#ifndef __QUEUE_H__
|
|
#define __QUEUE_H__
|
|
|
|
#include "p_buffer.h"
|
|
|
|
// This macro defines a queue type. It doesn't make a queue for you.
|
|
// See below for an example on how to make a queue.
|
|
// Creates a type of queue_${type}_t of size ${size}.
|
|
// the size will be fixed for all instances of that type unfortunately.
|
|
#define DEFINE_QUEUE(type) \
|
|
typedef struct queue_##type##_t \
|
|
{ \
|
|
type* data; \
|
|
int head; \
|
|
int tail; \
|
|
int msize; \
|
|
int csize; \
|
|
\
|
|
PB_STATUS (*enqueue)(struct queue_##type##_t * queue, type val); \
|
|
PB_STATUS (*dequeue)(struct queue_##type##_t * queue, type* val); \
|
|
void (*empty)(struct queue_##type##_t * queue); \
|
|
bool (*is_full)(struct queue_##type##_t * queue); \
|
|
\
|
|
} queue_##type##_t; \
|
|
\
|
|
bool queue_##type##_is_full(queue_##type##_t* queue) \
|
|
{ \
|
|
return (queue->csize == queue->msize); \
|
|
} \
|
|
\
|
|
void queue_##type##_empty(queue_##type##_t* queue) \
|
|
{ \
|
|
memset(queue->data, 0, sizeof(type) * queue->msize); \
|
|
queue->head = -1; \
|
|
queue->tail = -1; \
|
|
queue->csize = 0; \
|
|
} \
|
|
\
|
|
PB_STATUS queue_##type##_enqueue(queue_##type##_t* queue, type val) \
|
|
{ \
|
|
PB_STATUS ret = PB_GOOD; \
|
|
if (queue->is_full(queue)) \
|
|
{ \
|
|
ret = PB_FULL_QUEUE; \
|
|
} \
|
|
else \
|
|
{ \
|
|
if (queue->head == -1) \
|
|
{ \
|
|
queue->head = 0; \
|
|
queue->csize = 0; \
|
|
queue->tail = queue->msize - 1; \
|
|
} \
|
|
queue->tail = (queue->tail + 1) % queue->msize; \
|
|
queue->data[queue->tail] = val; \
|
|
queue->csize++; \
|
|
} \
|
|
return ret; \
|
|
} \
|
|
\
|
|
PB_STATUS queue_##type##_dequeue(queue_##type##_t* queue, type* val) \
|
|
{ \
|
|
PB_STATUS ret = PB_GOOD; \
|
|
if (queue->csize == 0) \
|
|
{ \
|
|
ret = PB_EMPTY_QUEUE; \
|
|
} \
|
|
else \
|
|
{ \
|
|
*val = queue->data[queue->head]; \
|
|
queue->head = (queue->head + 1) % queue->csize; \
|
|
queue->csize -= 1; \
|
|
} \
|
|
return ret; \
|
|
} \
|
|
PB_STATUS queue_##type##_init(queue_##type##_t* queue, type* buffer, \
|
|
int total_length) \
|
|
{ \
|
|
PB_STATUS ret = PB_GOOD; \
|
|
do \
|
|
{ \
|
|
if (!queue) \
|
|
{ \
|
|
ret = PB_NULL_BUFFER; \
|
|
break; \
|
|
} \
|
|
\
|
|
if (total_length > MAX_QUEUE_SIZE || total_length <= 0) \
|
|
{ \
|
|
ret = PB_BAD_BUFFER_SIZE; \
|
|
break; \
|
|
} \
|
|
} while (0); \
|
|
memset(queue, 0, sizeof(queue_##type##_t)); \
|
|
memset(buffer, 0, sizeof(type) * total_length); \
|
|
queue->data = buffer; \
|
|
queue->msize = total_length; \
|
|
queue->head = -1; \
|
|
queue->tail = -1; \
|
|
queue->csize = 0; \
|
|
queue->enqueue = queue_##type##_enqueue; \
|
|
queue->dequeue = queue_##type##_dequeue; \
|
|
queue->empty = queue_##type##_empty; \
|
|
queue->is_full = queue_##type##_is_full; \
|
|
return ret; \
|
|
}
|
|
|
|
/*
|
|
Example:
|
|
|
|
DEFINE_QUEUE(int);
|
|
// in .c
|
|
queue_int_t queue;
|
|
const int SIZE_QUEUE = 256;
|
|
int buffer[SIZE_QUEUE];
|
|
queue_int_init(&queue, buffer, SIZE_QUEUE);
|
|
queue_int_enqueue(&queue, 12);
|
|
*/
|
|
#endif
|