venus: Remove dedebug
[openafs.git] / src / afs / OBSD / osi_sleep.c
1 /*
2  * $Id$
3  */
4
5 /*
6 copyright 2002
7 the regents of the university of michigan
8 all rights reserved
9
10 permission is granted to use, copy, create derivative works 
11 and redistribute this software and such derivative works 
12 for any purpose, so long as the name of the university of 
13 michigan is not used in any advertising or publicity 
14 pertaining to the use or distribution of this software 
15 without specific, written prior authorization.  if the 
16 above copyright notice or any other identification of the 
17 university of michigan is included in any copy of any 
18 portion of this software, then the disclaimer below must 
19 also be included.
20
21 this software is provided as is, without representation 
22 from the university of michigan as to its fitness for any 
23 purpose, and without warranty by the university of 
24 michigan of any kind, either express or implied, including 
25 without limitation the implied warranties of 
26 merchantability and fitness for a particular purpose. the 
27 regents of the university of michigan shall not be liable 
28 for any damages, including special, indirect, incidental, or 
29 consequential damages, with respect to any claim arising 
30 out of or in connection with the use of the software, even 
31 if it has been or is hereafter advised of the possibility of 
32 such damages.
33 */
34
35 /*
36  * Copyright 2000, International Business Machines Corporation and others.
37  * All Rights Reserved.
38  *
39  * This software has been released under the terms of the IBM Public
40  * License.  For details, see the LICENSE file in the top-level source
41  * directory or online at http://www.openafs.org/dl/license10.html
42  */
43
44 #include <afsconfig.h>
45 #include "afs/param.h"
46
47
48 #include "afs/sysincludes.h"    /* Standard vendor system headers */
49 #include "afs/afsincludes.h"    /* Afs-based standard headers */
50 #include "afs/afs_stats.h"      /* afs statistics */
51
52 static char waitV;
53
54
55 time_t
56 osi_Time()
57 {
58     struct timeval now;
59
60     getmicrotime(&now);
61     return now.tv_sec;
62 }
63
64 /* cancel osi_Wait */
65 void
66 afs_osi_CancelWait(struct afs_osi_WaitHandle *achandle)
67 {
68     caddr_t proc;
69
70     AFS_STATCNT(osi_CancelWait);
71     proc = achandle->proc;
72     if (proc == NULL)
73         return;
74     achandle->proc = NULL;
75     wakeup(&waitV);
76 }
77
78 /* afs_osi_Wait
79  * Waits for data on ahandle, or ams ms later.  ahandle may be null.
80  * Returns 0 if timeout and EINTR if signalled.
81  */
82 int
83 afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
84 {
85     int timo, code = 0;
86     struct timeval atv, now, endTime;
87
88     AFS_STATCNT(osi_Wait);
89
90     atv.tv_sec = ams / 1000;
91     atv.tv_usec = (ams % 1000) * 1000;
92     getmicrotime(&now);
93     timeradd(&atv, &now, &endTime);
94
95     if (ahandle)
96         ahandle->proc = (caddr_t) curproc;
97     AFS_ASSERT_GLOCK();
98     AFS_GUNLOCK();
99
100     do {
101         timersub(&endTime, &now, &atv);
102         timo = atv.tv_sec * hz + atv.tv_usec * hz / 1000000 + 1;
103         if (aintok) {
104             code = tsleep(&waitV, PCATCH | PVFS, "afs_W1", timo);
105             if (code)
106                 code = (code == EWOULDBLOCK) ? 0 : EINTR;
107         } else
108             tsleep(&waitV, PVFS, "afs_W2", timo);
109
110         /* if we were cancelled, quit now */
111         if (ahandle && (ahandle->proc == NULL)) {
112             /* we've been signalled */
113             break;
114         }
115         getmicrotime(&now);
116     } while (timercmp(&now, &endTime, <));
117
118     AFS_GLOCK();
119     return code;
120 }
121
122 afs_event_t *afs_evhasht[AFS_EVHASHSIZE];     /* Hash table for events */
123 #define afs_evhash(event)       (afs_uint32) ((((long)event)>>2) & (AFS_EVHASHSIZE-1))
124 int afs_evhashcnt = 0;
125
126 /* Get and initialize event structure corresponding to lwp event (i.e. address)
127  * */
128 static afs_event_t *
129 afs_getevent(char *event)
130 {
131     afs_event_t *evp, *newp = 0;
132     int hashcode;
133
134     AFS_ASSERT_GLOCK();
135     hashcode = afs_evhash(event);
136     evp = afs_evhasht[hashcode];
137     while (evp) {
138         if (evp->event == event) {
139             evp->refcount++;
140             return evp;
141         }
142         if (evp->refcount == 0)
143             newp = evp;
144         evp = evp->next;
145     }
146     if (!newp) {
147         newp = osi_AllocSmallSpace(sizeof(afs_event_t));
148         afs_evhashcnt++;
149         newp->next = afs_evhasht[hashcode];
150         afs_evhasht[hashcode] = newp;
151         newp->seq = 0;
152     }
153     newp->event = event;
154     newp->refcount = 1;
155     return newp;
156 }
157
158 /* Release the specified event */
159 #define relevent(evp) ((evp)->refcount--)
160
161 int
162 afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok)
163 {
164     int code = 0;
165     struct afs_event *evp;
166     int seq, prio;
167     int ticks;
168
169     evp = afs_getevent(event);
170     seq = evp->seq;
171     AFS_GUNLOCK();
172     if (aintok)
173         prio = PCATCH | PPAUSE;
174     else
175         prio = PVFS;
176     ticks = (ams * afs_hz) / 1000;
177     code = tsleep(event, prio, "afs_osi_TimedSleep", ticks);
178     if (seq == evp->seq)
179         code = EINTR;
180     relevent(evp);
181     AFS_GLOCK();
182     return code;
183 }
184
185 void
186 afs_osi_Sleep(void *event)
187 {
188     AFS_ASSERT_GLOCK();
189     AFS_GUNLOCK();
190     tsleep(event, PVFS, "afsslp", 0);
191     AFS_GLOCK();
192 }
193
194 int
195 afs_osi_SleepSig(void *event)
196 {
197     afs_osi_Sleep(event);
198     return 0;
199 }
200
201 int
202 afs_osi_Wakeup(void *event)
203 {
204     wakeup(event);
205     return 1;
206 }