provide afs_osi_TimedSleep
[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      register void (*aproc) ();
26      register 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      register void (*aproc) ();
47      register 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