diff options
author | Thomas White <taw@bitwiz.org.uk> | 2012-02-15 00:36:32 +0100 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2012-02-15 00:36:32 +0100 |
commit | ab48b5d2be4a3c576205aa25e8332ff102db8378 (patch) | |
tree | 52afb3e88518b1ba9258b8f0568db8a9a3ecfbf4 /fifo.c | |
parent | e0ef1d1b20df2ff5f656902f1f95cddc83ec3a81 (diff) |
Diffstat (limited to 'fifo.c')
-rw-r--r-- | fifo.c | 99 |
1 files changed, 99 insertions, 0 deletions
@@ -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; +} |