Windows: fix checked UNICODE build of talocale
[openafs.git] / src / WINNT / client_osi / osiqueue.c
1 /* 
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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  */
9
10 /* Copyright (C) 1994 Cazamar Systems, Inc. */
11
12 #include <afs/param.h>
13 #include <afs/stds.h>
14
15 #include <windows.h>
16 #include "osi.h"
17 #include <stdlib.h>
18
19 /* critical section protecting allocation of osi_queueData_t elements */
20 Crit_Sec osi_qdcrit;
21
22 /* free list of queue elements */
23 osi_queueData_t *osi_QDFreeListp = NULL;
24
25 void osi_QAdd(osi_queue_t **headpp, osi_queue_t *eltp)
26 {
27         osi_queue_t *tp;
28
29         /* and both paths do the following; do this early to keep
30          * machine busy while processing delay on conditional check
31          */
32         eltp->prevp = NULL;
33
34         if (tp = *headpp) {
35                 /* there is one element here */
36                 eltp->nextp = tp;
37                 tp->prevp = eltp;
38         }
39         else {
40                 /* we're the first */
41                 eltp->nextp = NULL;
42         }
43
44         /* and both paths do the following */
45         *headpp = eltp;
46 }
47
48 void osi_QAddH(osi_queue_t **headpp, osi_queue_t **tailpp, osi_queue_t *eltp)
49 {
50         osi_queue_t *tp;
51
52         /* and both paths do the following; do this early to keep
53          * machine busy while processing delay on conditional check
54          */
55         eltp->prevp = NULL;
56
57         if (tp = *headpp) {
58                 /* there is one element here */
59                 eltp->nextp = tp;
60                 tp->prevp = eltp;
61         }
62         else {
63                 /* we're the first */
64                 eltp->nextp = NULL;
65                 *tailpp = eltp;
66         }
67
68         /* and both paths do the following */
69         *headpp = eltp;
70 }
71
72 void osi_QAddT(osi_queue_t **headpp, osi_queue_t **tailpp, osi_queue_t *eltp)
73 {
74         osi_queue_t *tp;
75
76         eltp->nextp = NULL;
77
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;
83         }
84         else {
85                 /* we're the only element in the list */
86                 *headpp = eltp;
87                 *tailpp = eltp;
88                 eltp->prevp = NULL;
89         }
90 }
91
92 void osi_QRemove(osi_queue_t **headpp, osi_queue_t *eltp)
93 {
94     osi_queue_t *np = eltp->nextp;      /* next dude */
95     osi_queue_t *pp = eltp->prevp;      /* prev dude */
96
97     if (eltp == *headpp) {
98         /* we're the first element in the list */
99         *headpp = np;
100         if (np) 
101             np->prevp = NULL;
102     }
103     else {
104         pp->nextp = np;
105         if (np) 
106             np->prevp = pp;
107     }
108     eltp->prevp = NULL;
109     eltp->nextp = NULL;
110 }
111
112 void osi_QRemoveHT(osi_queue_t **headpp, osi_queue_t **tailpp, osi_queue_t *eltp)
113 {
114     osi_queue_t *np = eltp->nextp;      /* next dude */
115     osi_queue_t *pp = eltp->prevp;      /* prev dude */
116
117     if (eltp == *headpp && eltp == *tailpp) 
118     {
119         *headpp = *tailpp = NULL;
120     }
121     else if (eltp == *headpp) {
122         /* we're the first element in the list */
123         *headpp = np;
124         if (np) 
125             np->prevp = NULL;
126     }   
127     else if (eltp == *tailpp) {
128         /* we're the last element in the list */
129         *tailpp = pp;
130         if (pp) 
131             pp->nextp = NULL;
132     }   
133     else {
134         if (pp)
135                 pp->nextp = np;
136         if (np)
137                 np->prevp = pp;
138     }
139     eltp->prevp = NULL; 
140     eltp->nextp = NULL;
141 }
142
143 void osi_InitQueue(void)
144 {
145         static int initd = 0;
146
147         if (initd) return;
148
149         initd = 1;
150         thrd_InitCrit(&osi_qdcrit);
151 }
152
153 osi_queueData_t *osi_QDAlloc(void)
154 {
155         osi_queueData_t *tp;
156         int i;
157
158         thrd_EnterCrit(&osi_qdcrit);
159         if (tp = osi_QDFreeListp) {
160                 osi_QDFreeListp = (osi_queueData_t *) tp->q.nextp;
161         }
162         else {
163                 /* need to allocate a block more */
164                 tp = (osi_queueData_t *) malloc(OSI_NQDALLOC * sizeof(osi_queueData_t));
165
166                 /* leave last guy off of the free list; this is the one we'll
167                  * return.
168                  */
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;
173                 }
174                 
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.
177                  */
178                 tp->datap = NULL;
179         }
180         thrd_LeaveCrit(&osi_qdcrit);
181
182         osi_assertx(tp->datap == NULL, "queue freelist screwup");
183
184         return tp;
185 }
186
187 void osi_QDFree(osi_queueData_t *qp)
188 {
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);
194 }