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
30 qinit(queue *q,size_t defaultsize)
32 pthread_rwlock_init(&q->pmutex, NULL);
33 if (!defaultsize) defaultsize = 16;
34 q->data = (void **) calloc(defaultsize, sizeof(void *));
35 q->begin = q->end = 0;
36 q->allocated = defaultsize;
44 pthread_rwlock_destroy(&q->pmutex);
51 if (q->filled == 0) return (void*)0xABCDEF00;
52 int err = pthread_rwlock_wrlock(&q->pmutex);
53 void *v = q->data[q->begin++];
55 if (q->filled == 0) {q->begin = q->end = 0;}
56 if (q->begin >= q->allocated) q->begin = 0;
59 err = pthread_rwlock_unlock(&q->pmutex);
65 qpush(queue * q, void *p)
67 int err = pthread_rwlock_wrlock(&q->pmutex);
68 if (q->allocated == q->filled) q->allocated = growarray(&q->data,q->allocated);
69 q->data[q->end++] = p;
71 if (q->end >= q->allocated) q->end = 0;
74 err = pthread_rwlock_unlock(&q->pmutex);
79 qperform(queue *q, qperformer p, void *pctx)
81 if (q->end == q->begin) return; //no handling wrapped around status
82 //in fact no handling anything but we'll handle nonwrapped first
83 int err = pthread_rwlock_rdlock(&q->pmutex);
84 if (q->end > q->begin) {
85 int i = q->begin, c = q->end - q->begin;
91 int i = q->begin, c = q->filled;
101 q->filled = q->begin = q->end = 0;
102 if (err = 0) pthread_rwlock_unlock(&q->pmutex);
105 /* XXX this should not be in here, but whatever */
107 * XXX there should also be a reverse shrinkarray for when the fill size hits
108 * a low-water-mark point. FreeBSD at least will free up memory if you
109 * realloc something smaller.
112 growarray(void ***datap, size_t oldsize)
114 size_t newsize = oldsize + 8, diff = 8;
115 void **data = *datap;
116 *datap = reallocf(data, sizeof(void *[newsize]));
117 while (diff--) {data[oldsize+diff] = (void*)0xDDDADEDC;}