Skip to content

Instantly share code, notes, and snippets.

@ianmacartney
Created October 29, 2013 06:32
Show Gist options
  • Save ianmacartney/7209970 to your computer and use it in GitHub Desktop.
Save ianmacartney/7209970 to your computer and use it in GitHub Desktop.
Basic dispatch queue for static memory applications (e.g. embedded). Caller is responsible for lifetime of all data passed in.
/**
* q: queue of dispatches
* d: dispatch
* front/head = top of stack
* back/end/tail = bottom of stack
*/
struct DQDispatch {
void (*fn)(void *);
void *param;
struct DQDispatch *next;
};
struct DQueue {
struct DQDispatch *tail;
};
struct DQDispatch *DQ_Head(struct DQueue *q);
void DQ_Push(struct DQueue *q, struct DQDispatch *d);
void DQ_Append(struct DQueue *q, struct DQDispatch *d);
struct DQDispatch *DQ_Pop(struct DQueue *q);
struct DQDispatch *DQ_PopAppend(struct DQueue *q);
struct DQDispatch *DQ_Next(struct DQueue *q, struct DQDispatch *d);
//.c
#include <stddef.h>
void DQ_Init(struct DQueue *q) {
q->tail = NULL;
}
struct DQDispatch *DQ_Head(struct DQueue *q) {
return q->tail? q->tail->next: NULL;
}
void DQ_Push(struct DQueue *q, struct DQDispatch *d) {
struct DQDispatch *tail = q->tail;
if (tail) {
d->next = tail->next;
tail->next = d;
} else {
d->next = d;
q->tail = d;
}
}
void DQ_Append(struct DQueue *q, struct DQDispatch *d) {
DQ_Push(q, d);
q->tail = q->tail->next;
}
struct DQDispatch *DQ_Pop(struct DQueue *q) {
struct DQDispatch *tail = q->tail;
struct DQDispatch *head = tail->next;
if (head == tail) {
q->tail = NULL;
} else {
tail->next = head->next;
}
head->next = NULL;
return head;
}
struct DQDispatch *DQ_Pop_append(struct DQueue *q) {
struct DQDispatch *tail = q->tail;
if (tail) {
q->tail = tail->next;
}
return q->tail;
}
struct DQDispatch *DQ_Next(struct DQueue *q, struct DQDispatch *d) {
return d == q->tail? NULL: d->next;
}
#define DQ_TEST
#ifdef DQ_TEST
#include <assert.h>
#include <stdio.h>
#define TEST_SIZE 15
int main(int argc, void **argv) {
static struct DQueue qist;
static struct DQueue *q = &qist;
static struct DQDispatch na[TEST_SIZE];
static int ia[TEST_SIZE];
int i;
DQ_Init(q);
for (i = 0; i < TEST_SIZE; i++) {
ia[i] = i;
na[i].param = &ia[i];
DQ_Push(q, &na[i]);
}
assert(DQ_Head(q));
assert(i == TEST_SIZE);
struct DQDispatch *d;
for (d = DQ_Head(q); d; d = DQ_Next(q, d)) {
i--;
assert(*(int*)d->param == i);
}
printf("Countdown from %i to 0!\r\n", TEST_SIZE - 1);
while(DQ_Head(q) && (d = DQ_Pop(q))) {
printf("%5i!\r\n", *(int*)d->param);
}
assert(DQ_Head(q) == NULL);
assert(i == 0);
for (; i < TEST_SIZE; i++) {
DQ_Append(q, &na[i]);
}
printf("Count 0 up to %i!\r\n", TEST_SIZE - 1);
struct DQDispatch *head = DQ_Head(q);
for (i = 0; i < TEST_SIZE; i++) {
d = DQ_Pop_append(q);
printf("%5i!\r\n", *(int*)d->param);
assert(*(int*)d->param == i);
}
assert(head == DQ_Head(q));
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment