Skip to content

Instantly share code, notes, and snippets.

@agarie
Created October 25, 2012 08:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agarie/3951358 to your computer and use it in GitHub Desktop.
Save agarie/3951358 to your computer and use it in GitHub Desktop.
queues.c
/*
** queue-threadsafe.c
**
** A thread-safe (for 2 threads) implementation of a queue. Based on the
** implementation from the book Embedded Systems, by Jonathan W. Valvano,
** chapter 3, page 130.
*/
#include <stdlib.h>
typedef int DataType;
struct queue {
int size;
DataType *elements;
DataType volatile * tail;
DataType volatile * head;
};
typedef struct queue queue_t;
queue_t * queue_init(int size) {
queue_t * queue;
/* Allocate space for the queue. */
queue = (queue_t *)malloc(sizeof(queue_t));
/* Allocate space for the elements of the queue. */
queue->elements = (DataType *)malloc(size * sizeof(DataType));
/* Initialize pointers. */
queue->tail = queue->head = &queue->elements[0];
}
int queue_put(DataType data) {
DataType volatile * nextTail;
nextTail = queue->tail + 1;
if (nextTail == &queue->elements[queue->size]) {
/* Wrap around. */
nextTail = &queue->elements[0];
}
if (nextTail == queue->head) {
return 0;
} else {
*queue->tail = data;
queue->tail = nextTail;
return 1;
}
}
int queue_get(DataType *dataptr) {
if (queue->tail == queue->head) {
/* Queue is empty. */
return 0;
}
*dataptr = *(queue->head++);
if (queue->head == &queue->elements[queue->size]) {
/* Wrap around. */
queue->head = &queue->elements[0];
}
return 1;
}
/*
** queue-valvano.c
**
** Macro to create thread-safe queues. Originally from the book Embedded
** Systems, by Jonathan W. Valvano, chapter 3, page 130.
*/
/*
** To use it:
**
** 20-element queue storing unsigned 16-bit numbers:
**
** AddPointerFifo(Rx, 20, unsigned short, 1, 0)
**
** which will create RxFifo_Init(), RxFifo_Get and Rx_Fifo_Put().
**
** 150-element queue of struct sensor_data:
**
** AddPointerFifo(Sensor, 150, struct sensor_data, 1, 0)
**
** which will create SensorFifo_Init(), SensorFifo_Get() and SensorFifo_Put().
*/
#define AddPointerFifo(NAME,SIZE,TYPE,SUCCESS,FAIL) \
TYPE volatile *NAME ## PutPt; \
TYPE volatile *NAME ## GetPt; \
TYPE static NAME ## Fifo[SIZE]; \
void NAME ## Fifo_Init(void) { \
NAME ## PutPt = NAME ## GetPt = &NAME ## Fifo[0]; \
} \
int NAME ## Fifo_Put (TYPE data) { \
TYPE volatile *nextPutPt; \
nextPutPt = NAME ## PutPt + 1; \
if (nextPutPt == &NAME ## Fifo[SIZE]) { \
nextPutPt = &NAME ## Fifo[0]; \
} \
if (nextPutPt == NAME ## GetPt) { \
return (FAIL); \
} else { \
*(NAME ## PutPt) = data; \
NAME ## PutPt = nextPutPt; \
return (SUCCESS); \
} \
} \
int NAME ## Fifo_Get (TYPE *datapt) { \
if (NAME ## PutPt == NAME ## GetPt) { \
return (FAIL); \
} \
*datapt = *(NAME ## GetPt ## ++); \
if (NAME ## GetPt == &NAME ## Fifo[SIZE]) { \
NAME ## GetPt = &NAME ## Fifo[0]; \
} \
return (SUCCESS); \
} \
/*
** queue-valvano.c
**
** A thread-safe implementation of a queue. Originally from the book Embedded
** Systems, by Jonathan W. Valvano, chapter 3, page 130.
*/
#define FIFOSIZE 10
#define FIFOSUCCESS 1
#define FIFOFAIL 0
typedef char DataType;
DataType volatile *PutPt;
Datatype volatile *GetPt;
DataType static Fifo[FIFOSIZE];
/* Initialization. */
void Fifo_Init(void) {
PutPt = GetPt = &Fifo[0];
}
int Fifo_Put(DataType data) {
DataType volatile *nextPutPt;
nextPutPt = PutPt + 1;
if (nextPutPt == &Fifo[FIFOSIZE]) {
nextPutPt = &Fifo[0]; /* Wrap around. */
}
if (nextPutPt == GetPt) {
/* Fifo is full. */
return FIFOFAIL;
}
else {
*(PutPt) = data;
PutPt = nextPutPt;
return FIFOSUCCESS;
}
}
int Fifo_Get(DataType *datapt) {
if (PutPt == GetPt) {
/* Fifo is empty. */
return FIFOFAIL;
}
*datapt = *(GetPt++);
if (GetPt == &Fifo[FIFOSIZE]) {
GetPt = &Fifo[0]; /* Wrap around */
}
return FIFOSUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment