Created
October 25, 2012 08:13
-
-
Save agarie/3951358 to your computer and use it in GitHub Desktop.
queues.c
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
/* | |
** 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; | |
} |
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
/* | |
** 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); \ | |
} \ |
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
/* | |
** 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