#ifndef __QUEUE_H__ #define __QUEUE_H__ #include #include #include #define MAX_QUEUE_SIZE (512) typedef enum PB_STATUS { PB_GOOD = 0, PB_BAD = 1, PB_BAD_BUFFER_SIZE = 2, PB_NULL_BUFFER = 3, PB_NULL_DATA = 4, PB_EMPTY_QUEUE = 5, PB_FULL_QUEUE = 6 } PB_STATUS; // 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 QUEUE(type, size) \ typedef struct queue_##type##_t \ { \ int data[size]; \ 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) \ { \ PB_STATUS ret = PB_GOOD; \ do \ { \ if (!queue) \ { \ ret = PB_NULL_BUFFER; \ break; \ } \ \ if (size > MAX_QUEUE_SIZE || size <= 0) \ { \ ret = PB_BAD_BUFFER_SIZE; \ break; \ } \ } while (0); \ queue->msize = size; \ 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: // QUEUE(int, 4); // queue_int_t queue; // // in .c // queue_int_init(&queue); #endif