Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / WINNT / client_osi / osiqueue.c
blobb81ca1aa73a2dd45d5d5634a91e6c57f27bc8404
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
10 /* Copyright (C) 1994 Cazamar Systems, Inc. */
12 #include <afs/param.h>
13 #include <afs/stds.h>
15 #include <windows.h>
16 #include "osi.h"
17 #include <stdlib.h>
19 /* critical section protecting allocation of osi_queueData_t elements */
20 Crit_Sec osi_qdcrit;
22 /* free list of queue elements */
23 osi_queueData_t *osi_QDFreeListp = NULL;
25 void osi_QAdd(osi_queue_t **headpp, osi_queue_t *eltp)
27 osi_queue_t *tp;
29 /* and both paths do the following; do this early to keep
30 * machine busy while processing delay on conditional check
32 eltp->prevp = NULL;
34 if (tp = *headpp) {
35 /* there is one element here */
36 eltp->nextp = tp;
37 tp->prevp = eltp;
39 else {
40 /* we're the first */
41 eltp->nextp = NULL;
44 /* and both paths do the following */
45 *headpp = eltp;
48 void osi_QAddH(osi_queue_t **headpp, osi_queue_t **tailpp, osi_queue_t *eltp)
50 osi_queue_t *tp;
52 /* and both paths do the following; do this early to keep
53 * machine busy while processing delay on conditional check
55 eltp->prevp = NULL;
57 if (tp = *headpp) {
58 /* there is one element here */
59 eltp->nextp = tp;
60 tp->prevp = eltp;
62 else {
63 /* we're the first */
64 eltp->nextp = NULL;
65 *tailpp = eltp;
68 /* and both paths do the following */
69 *headpp = eltp;
72 void osi_QAddT(osi_queue_t **headpp, osi_queue_t **tailpp, osi_queue_t *eltp)
74 osi_queue_t *tp;
76 eltp->nextp = NULL;
78 if (tp = *tailpp) {
79 /* there's at least one element in the list; append ourselves */
80 eltp->prevp = tp;
81 tp->nextp = eltp;
82 *tailpp = eltp;
84 else {
85 /* we're the only element in the list */
86 *headpp = eltp;
87 *tailpp = eltp;
88 eltp->prevp = NULL;
92 void osi_QRemove(osi_queue_t **headpp, osi_queue_t *eltp)
94 osi_queue_t *np = eltp->nextp; /* next dude */
95 osi_queue_t *pp = eltp->prevp; /* prev dude */
97 if (eltp == *headpp) {
98 /* we're the first element in the list */
99 *headpp = np;
100 if (np)
101 np->prevp = NULL;
103 else {
104 pp->nextp = np;
105 if (np)
106 np->prevp = pp;
108 eltp->prevp = NULL;
109 eltp->nextp = NULL;
112 void osi_QRemoveHT(osi_queue_t **headpp, osi_queue_t **tailpp, osi_queue_t *eltp)
114 osi_queue_t *np = eltp->nextp; /* next dude */
115 osi_queue_t *pp = eltp->prevp; /* prev dude */
117 if (eltp == *headpp && eltp == *tailpp)
119 *headpp = *tailpp = NULL;
121 else if (eltp == *headpp) {
122 /* we're the first element in the list */
123 *headpp = np;
124 if (np)
125 np->prevp = NULL;
127 else if (eltp == *tailpp) {
128 /* we're the last element in the list */
129 *tailpp = pp;
130 if (pp)
131 pp->nextp = NULL;
133 else {
134 if (pp)
135 pp->nextp = np;
136 if (np)
137 np->prevp = pp;
139 eltp->prevp = NULL;
140 eltp->nextp = NULL;
143 void osi_InitQueue(void)
145 static int initd = 0;
147 if (initd) return;
149 initd = 1;
150 thrd_InitCrit(&osi_qdcrit);
153 osi_queueData_t *osi_QDAlloc(void)
155 osi_queueData_t *tp;
156 int i;
158 thrd_EnterCrit(&osi_qdcrit);
159 if (tp = osi_QDFreeListp) {
160 osi_QDFreeListp = (osi_queueData_t *) tp->q.nextp;
162 else {
163 /* need to allocate a block more */
164 tp = (osi_queueData_t *) malloc(OSI_NQDALLOC * sizeof(osi_queueData_t));
166 /* leave last guy off of the free list; this is the one we'll
167 * return.
169 for(i=0; i<OSI_NQDALLOC-1; i++, tp++) {
170 tp->q.nextp = (osi_queue_t *) osi_QDFreeListp;
171 tp->datap = NULL;
172 osi_QDFreeListp = tp;
175 /* when we get here, tp is pointing to the last dude allocated.
176 * This guy wasn't put on the free list, so we can return him now.
178 tp->datap = NULL;
180 thrd_LeaveCrit(&osi_qdcrit);
182 osi_assertx(tp->datap == NULL, "queue freelist screwup");
184 return tp;
187 void osi_QDFree(osi_queueData_t *qp)
189 thrd_EnterCrit(&osi_qdcrit);
190 qp->q.nextp = (osi_queue_t *) osi_QDFreeListp;
191 qp->datap = NULL;
192 osi_QDFreeListp = qp;
193 thrd_LeaveCrit(&osi_qdcrit);