summaryrefslogtreecommitdiff
path: root/fifo.c
diff options
context:
space:
mode:
Diffstat (limited to 'fifo.c')
-rw-r--r--fifo.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/fifo.c b/fifo.c
new file mode 100644
index 0000000..245fb8e
--- /dev/null
+++ b/fifo.c
@@ -0,0 +1,99 @@
+/*
+ * fifo.c
+ *
+ * (c) 2012 Thomas White <taw@bitwiz.org.uk>
+ *
+ * This file is part of MIDInator.
+ *
+ * MIDInator is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * MIDInator is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIDInator. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdlib.h>
+#include <pthread.h>
+
+#include "fifo.h"
+
+struct _fifo
+{
+ pthread_mutex_t lock;
+
+ unsigned char *buf;
+ size_t sz;
+ size_t n_used;
+
+ size_t r; /* Read pointer */
+ size_t w; /* Write pointer */
+};
+
+
+FIFO *fifo_new()
+{
+ FIFO *f;
+
+ f = malloc(sizeof(struct _fifo));
+ if ( f == NULL ) return NULL;
+
+ f->sz = 64*1024;
+ f->buf = malloc(f->sz);
+ if ( f->buf == NULL ) {
+ free(f);
+ return NULL;
+ }
+
+ f->r = 0;
+ f->w = 0;
+ f->n_used = 0;
+
+ pthread_mutex_init(&f->lock, NULL);
+
+ return f;
+}
+
+
+void fifo_push(FIFO *f, unsigned char c)
+{
+ pthread_mutex_lock(&f->lock);
+
+ f->buf[f->w++] = c;
+ f->n_used++;
+
+ if ( f->w == f->sz ) {
+ f->w = 0;
+ }
+
+ pthread_mutex_unlock(&f->lock);
+}
+
+
+unsigned char fifo_pop(FIFO *f, int *err)
+{
+ unsigned char c;
+
+ pthread_mutex_lock(&f->lock);
+
+ if ( f->n_used == 0 ) {
+ pthread_mutex_unlock(&f->lock);
+ *err = 1;
+ return 0;
+ }
+
+ *err = 0;
+ c = f->buf[f->r++];
+ f->n_used--;
+
+ pthread_mutex_unlock(&f->lock);
+
+ return c;
+}