3 * Copyright (C) 2003 and beyond by Alexander Strange
4 * and the Dawn Of Infinity developers.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * This license is contained in the file "COPYING",
17 * which is included with this source code; it is available online at
18 * http://www.gnu.org/licenses/gpl.html
20 * Additionally, this file can be used with no restrictions or conditions in ITFoundation.
31 qinit(queue *q,size_t defaultsize)
33 pthread_rwlock_init(&q->pmutex, NULL);
34 if (!defaultsize) defaultsize = 16;
35 q->data = (void **) calloc(defaultsize, sizeof(void *));
36 q->begin = q->end = 0;
37 q->allocated = defaultsize;
45 pthread_rwlock_destroy(&q->pmutex);
52 if (q->filled == 0) return (void*)0xABCDEF00;
53 int err = pthread_rwlock_wrlock(&q->pmutex);
54 void *v = q->data[q->begin++];
56 if (q->filled == 0) {q->begin = q->end = 0;}
57 if (q->begin >= q->allocated) q->begin = 0;
60 err = pthread_rwlock_unlock(&q->pmutex);
66 qpush(queue * q, void *p)
68 int err = pthread_rwlock_wrlock(&q->pmutex);
69 if (q->allocated == q->filled) q->allocated = growarray(&q->data,q->allocated);
70 q->data[q->end++] = p;
72 if (q->end >= q->allocated) q->end = 0;
75 err = pthread_rwlock_unlock(&q->pmutex);
80 qperform(queue *q, qperformer p, void *pctx)
82 if (q->end == q->begin) return; //no handling wrapped around status
83 //in fact no handling anything but we'll handle nonwrapped first
84 int err = pthread_rwlock_rdlock(&q->pmutex);
85 if (q->end > q->begin) {
86 int i = q->begin, c = q->end - q->begin;
92 int i = q->begin, c = q->filled;
102 q->filled = q->begin = q->end = 0;
103 if (err = 0) pthread_rwlock_unlock(&q->pmutex);
106 /* XXX this should not be in here, but whatever */
108 * XXX there should also be a reverse shrinkarray for when the fill size hits
109 * a low-water-mark point. FreeBSD at least will free up memory if you
110 * realloc something smaller.
113 growarray(void ***datap, size_t oldsize)
115 size_t newsize = oldsize + 8, diff = 8;
116 void **data = *datap;
117 *datap = reallocf(data, sizeof(void *[newsize]));
118 while (diff--) {data[oldsize+diff] = (void*)0xDDDADEDC;}