From: Alexander Strange Date: Sun, 9 Nov 2003 05:41:03 +0000 (+0000) Subject: Oh wai X-Git-Tag: v0.1~4 X-Git-Url: http://git.ithinksw.org/ITFoundation.git/commitdiff_plain/f63895da2dd9edf0d6f475d49ba9e845c1083f18 Oh wai --- diff --git a/queue.c b/queue.c new file mode 100755 index 0000000..c69061f --- /dev/null +++ b/queue.c @@ -0,0 +1,119 @@ +/* + * + * Copyright (C) 2003 and beyond by Alexander Strange + * and the Dawn Of Infinity developers. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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. + * + * This license is contained in the file "COPYING", + * which is included with this source code; it is available online at + * http://www.gnu.org/licenses/gpl.html + * + */ + +/* + * $Id$ + * + */ +#include +#include "queue.h" + +queue* +qinit(queue *q,size_t defaultsize) +{ + pthread_rwlock_init(&q->pmutex, NULL); + if (!defaultsize) defaultsize = 16; + q->data = (void **) calloc(defaultsize, sizeof(void *)); + q->begin = q->end = 0; + q->allocated = defaultsize; + q->filled = 0; + return q; +} + +void +qdel(queue * q) +{ + pthread_rwlock_destroy(&q->pmutex); + free(q->data); +} + +void * +qpop(queue * q) +{ +if (q->filled == 0) return (void*)0xABCDEF00; + int err = pthread_rwlock_wrlock(&q->pmutex); + void *v = q->data[q->begin++]; + q->filled--; + if (q->filled == 0) {q->begin = q->end = 0;} + if (q->begin >= q->allocated) q->begin = 0; + if(err == 0) + { + err = pthread_rwlock_unlock(&q->pmutex); + } + return v; +} + +void +qpush(queue * q, void *p) +{ + int err = pthread_rwlock_wrlock(&q->pmutex); + if (q->allocated == q->filled) q->allocated = growarray(&q->data,q->allocated); + q->data[q->end++] = p; + q->filled++; + if (q->end >= q->allocated) q->end = 0; + if(err == 0) + { + err = pthread_rwlock_unlock(&q->pmutex); + } +} + +void +qperform(queue *q, qperformer p, void *pctx) +{ + if (q->end == q->begin) return; //no handling wrapped around status + //in fact no handling anything but we'll handle nonwrapped first + int err = pthread_rwlock_rdlock(&q->pmutex); + if (q->end > q->begin) { + int i = q->begin, c = q->end - q->begin; + do + { + p(pctx,q->data[i++]); + } while (c--); + } else { + int i = q->begin, c = q->filled; + while (c--) { + p(pctx,q->data[i++]); + } + i = 0; + c = q->end; + do { + p(pctx,q->data[i++]); + } while (c--); + } + q->filled = q->begin = q->end = 0; + if (err = 0) pthread_rwlock_unlock(&q->pmutex); +} + +/* XXX this should not be in here, but whatever */ +/* + * XXX there should also be a reverse shrinkarray for when the fill size hits + * a low-water-mark point. FreeBSD at least will free up memory if you + * realloc something smaller. + */ +size_t +growarray(void ***datap, size_t oldsize) +{ + size_t newsize = oldsize + 8, diff = 8; + void **data = *datap; + *datap = reallocf(data, sizeof(void *[newsize])); + while (diff--) {data[oldsize+diff] = (void*)0xDDDADEDC;} + return newsize; +} \ No newline at end of file diff --git a/queue.h b/queue.h new file mode 100755 index 0000000..ff43e78 --- /dev/null +++ b/queue.h @@ -0,0 +1,49 @@ +/* + * + * Copyright (C) 2003 and beyond by Alexander Strange + * and the Dawn Of Infinity developers. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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. + * + * This license is contained in the file "COPYING", + * which is included with this source code; it is available online at + * http://www.gnu.org/licenses/gpl.html + * + */ + +/* + * $Id$ + * + */ +#pragma once only +#ifndef _QUEUE_H +#define _QUEUE_H +#include +#include + +typedef struct queue { + void **data; + size_t begin; + size_t end; + size_t allocated; + size_t filled; + pthread_rwlock_t pmutex; +} queue; + +typedef void (*qperformer) (void *context, void *p); + +extern queue *qinit(queue *q,size_t defaultsize); +extern void qdel(queue *q); +extern void *qpop(queue *q); +extern void qpush(queue *q, void *p); +extern size_t growarray(void ***datap, size_t oldsize); +extern void qperform(queue *q, qperformer p, void *pctx); +#endif \ No newline at end of file