Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / afs / HPUX / osi_sleep.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 #include <afsconfig.h>
11 #include "afs/param.h"
12
13
14 #include "afs/sysincludes.h" /* Standard vendor system headers */
15 #include "afsincludes.h" /* Afs-based standard headers */
16 #include "afs/afs_stats.h" /* afs statistics */
17
18 #if !defined(AFS_HPUX110_ENV)
19 static char waitV;
20 #endif
21
22 /* call procedure aproc with arock as an argument, in ams milliseconds */
23 static int
24 afs_osi_CallProc(aproc, arock, ams)
25 void (*aproc) ();
26 char *arock;
27 afs_int32 ams;
28 {
29 int code;
30
31 AFS_STATCNT(osi_CallProc);
32 #if !defined(AFS_HPUX110_ENV)
33 AFS_GUNLOCK();
34 #endif
35 /* hz is in cycles/second, and timeout's 3rd parm is in cycles */
36 code = timeout(aproc, arock, (ams * afs_hz) / 1000 + 1);
37 #if !defined(AFS_HPUX110_ENV)
38 AFS_GLOCK();
39 #endif
40 return code;
41 }
42
43 /* cancel a timeout, whether or not it has already occurred */
44 static int
45 afs_osi_CancelProc(aproc, arock)
46 void (*aproc) ();
47 char *arock;
48 {
49 int code = 0;
50 AFS_STATCNT(osi_CancelProc);
51
52 #if !defined(AFS_HPUX110_ENV)
53 AFS_GUNLOCK();
54 #endif
55 code = untimeout(aproc, arock);
56 #if !defined(AFS_HPUX110_ENV)
57 AFS_GLOCK();
58 #endif
59 return code;
60 }
61
62 #if defined(AFS_HPUX110_ENV)
63 static void
64 AfsWaitHack(char *event)
65 {
66 lock_t *sleep_lock;
67
68 AFS_STATCNT(WaitHack);
69 sleep_lock = get_sleep_lock(event);
70 wakeup(event);
71 spinunlock(sleep_lock);
72 }
73 #else
74
75 static void
76 AfsWaitHack()
77 {
78 AFS_STATCNT(WaitHack);
79 wakeup(&waitV);
80 }
81 #endif
82
83 void
84 afs_osi_InitWaitHandle(struct afs_osi_WaitHandle *achandle)
85 {
86 AFS_STATCNT(osi_InitWaitHandle);
87 achandle->proc = (caddr_t) 0;
88 }
89
90 /* cancel osi_Wait */
91 void
92 afs_osi_CancelWait(struct afs_osi_WaitHandle *achandle)
93 {
94 caddr_t proc;
95
96 AFS_STATCNT(osi_CancelWait);
97 proc = achandle->proc;
98 if (proc == 0)
99 return;
100 achandle->proc = (caddr_t) 0; /* so dude can figure out he was signalled */
101 #if defined(AFS_HPUX110_ENV)
102 afs_osi_Wakeup((char *)achandle);
103 #else
104 afs_osi_Wakeup(&waitV);
105 #endif
106
107 }
108
109 /* afs_osi_Wait
110 * Waits for data on ahandle, or ams ms later. ahandle may be null.
111 * Returns 0 if timeout and EINTR if signalled.
112 */
113 int
114 afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
115 {
116 int code;
117 afs_int32 endTime, tid;
118 #if defined(AFS_HPUX110_ENV)
119 char localwait;
120 char *event;
121 #endif
122
123 AFS_STATCNT(osi_Wait);
124 endTime = osi_Time() + (ams / 1000);
125 if (ahandle)
126 ahandle->proc = (caddr_t) u.u_procp;
127 do {
128 AFS_ASSERT_GLOCK();
129 code = 0;
130 /* do not do anything for solaris, digital, AIX, and SGI MP */
131 #if defined(AFS_HPUX110_ENV)
132 if (ahandle) {
133 event = (char *)ahandle;
134 } else {
135 event = &localwait;
136 }
137 afs_osi_CallProc(AfsWaitHack, event, ams);
138 afs_osi_Sleep(event);
139 afs_osi_CancelProc(AfsWaitHack, event);
140 #else
141 afs_osi_CallProc(AfsWaitHack, (char *)u.u_procp, ams);
142 afs_osi_Sleep(&waitV); /* for HP 10.0 */
143
144 /* do not do anything for solaris, digital, and SGI MP */
145 afs_osi_CancelProc(AfsWaitHack, (char *)u.u_procp);
146 if (code)
147 break; /* if something happened, quit now */
148 #endif
149 /* if we we're cancelled, quit now */
150 if (ahandle && (ahandle->proc == (caddr_t) 0)) {
151 /* we've been signalled */
152 break;
153 }
154 } while (osi_Time() < endTime);
155 return code;
156 }
157
158 int
159 afs_osi_SleepSig(void *event)
160 {
161 afs_osi_Sleep(event);
162 return 0;
163 }
164
165 #if defined(AFS_HPUX110_ENV)
166 int
167 afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok)
168 {
169 lock_t *sleep_lock;
170 int intr = EWOULDBLOCK;
171
172 AFS_ASSERT_GLOCK();
173 AFS_GUNLOCK();
174 afs_osi_CallProc(AfsWaitHack, event, ams);
175 sleep((caddr_t) event, PZERO - 2);
176 if (afs_osi_CancelProc(AfsWaitHack, event) < 0)
177 intr = 0;
178 AFS_GLOCK();
179 return intr;
180 }
181
182 void
183 afs_osi_Sleep(void *event)
184 {
185 lock_t *sleep_lock;
186
187 AFS_ASSERT_GLOCK();
188 get_sleep_lock(event);
189 AFS_GUNLOCK();
190 sleep((caddr_t) event, PZERO - 2);
191 AFS_GLOCK();
192 }
193
194 int
195 afs_osi_Wakeup(void *event)
196 {
197 lock_t *sleep_lock;
198
199 sleep_lock = get_sleep_lock(event);
200 wakeup((caddr_t) event);
201 spinunlock(sleep_lock);
202 return 0;
203 }
204 #else
205 int
206 afs_osi_Wakeup(void *event)
207 {
208 wakeup((caddr_t) event);
209 return 0;
210 }
211 #endif