2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include "afs/param.h"
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 */
21 afs_osi_InitWaitHandle(struct afs_osi_WaitHandle
*achandle
)
23 AFS_STATCNT(osi_InitWaitHandle
);
24 achandle
->proc
= (caddr_t
) 0;
29 afs_osi_CancelWait(struct afs_osi_WaitHandle
*achandle
)
33 AFS_STATCNT(osi_CancelWait
);
34 proc
= achandle
->proc
;
37 achandle
->proc
= (caddr_t
) 0; /* so dude can figure out he was signalled */
38 afs_osi_Wakeup(&waitV
);
42 * Waits for data on ahandle, or ams ms later. ahandle may be null.
43 * Returns 0 if timeout and EINTR if signalled.
46 afs_osi_Wait(afs_int32 ams
, struct afs_osi_WaitHandle
*ahandle
, int aintok
)
49 afs_int32 endTime
, tid
;
51 AFS_STATCNT(osi_Wait
);
52 endTime
= osi_Time() + (ams
/ 1000);
54 ahandle
->proc
= (caddr_t
) curthread
;
58 code
= afs_osi_TimedSleep(&waitV
, ams
, aintok
);
61 break; /* if something happened, quit now */
62 /* if we we're cancelled, quit now */
63 if (ahandle
&& (ahandle
->proc
== (caddr_t
) 0)) {
64 /* we've been signalled */
67 } while (osi_Time() < endTime
);
74 afs_event_t
*afs_evhasht
[AFS_EVHASHSIZE
]; /* Hash table for events */
75 #define afs_evhash(event) (afs_uint32) ((((long)event)>>2) & (AFS_EVHASHSIZE-1))
76 int afs_evhashcnt
= 0;
78 /* Get and initialize event structure corresponding to lwp event (i.e. address)
81 afs_getevent(char *event
)
83 afs_event_t
*evp
, *newp
= 0;
87 hashcode
= afs_evhash(event
);
88 evp
= afs_evhasht
[hashcode
];
90 if (evp
->event
== event
) {
94 if (evp
->refcount
== 0)
99 newp
= osi_AllocSmallSpace(sizeof(afs_event_t
));
101 newp
->next
= afs_evhasht
[hashcode
];
102 afs_evhasht
[hashcode
] = newp
;
103 cv_init(&newp
->cond
, "event cond var", CV_DEFAULT
, NULL
);
111 /* Release the specified event */
112 #define relevent(evp) ((evp)->refcount--)
116 afs_osi_Sleep(void *event
)
118 struct afs_event
*evp
;
121 evp
= afs_getevent(event
);
123 while (seq
== evp
->seq
) {
125 cv_wait(&evp
->cond
, &afs_global_lock
);
131 afs_osi_SleepSig(void *event
)
133 struct afs_event
*evp
;
136 evp
= afs_getevent(event
);
138 while (seq
== evp
->seq
) {
140 if (cv_wait_sig(&evp
->cond
, &afs_global_lock
) == 0) {
149 /* afs_osi_TimedSleep
152 * event - event to sleep on
153 * ams --- max sleep time in milliseconds
154 * aintok - 1 if should sleep interruptibly
156 * Returns 0 if timeout and EINTR if signalled.
159 afs_osi_TimedSleep(void *event
, afs_int32 ams
, int aintok
)
162 struct afs_event
*evp
;
165 ticks
= (ams
* afs_hz
) / 1000;
166 #if defined(AFS_SUN510_ENV)
167 ticks
= ticks
+ ddi_get_lbolt();
169 ticks
= ticks
+ lbolt
;
172 evp
= afs_getevent(event
);
176 if (cv_timedwait_sig(&evp
->cond
, &afs_global_lock
, ticks
) == 0)
179 cv_timedwait(&evp
->cond
, &afs_global_lock
, ticks
);
188 afs_osi_Wakeup(void *event
)
191 struct afs_event
*evp
;
193 evp
= afs_getevent(event
);
194 if (evp
->refcount
> 1) {
196 cv_broadcast(&evp
->cond
);