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
11 #include <afsconfig.h>
12 #include "afs/param.h"
15 #include "afs/sysincludes.h" /* Standard vendor system headers */
16 #include "afsincludes.h" /* Afs-based standard headers */
17 #include "afs/afs_stats.h" /* afs statistics */
23 afs_osi_InitWaitHandle(struct afs_osi_WaitHandle *achandle)
25 AFS_STATCNT(osi_InitWaitHandle);
26 achandle->proc = (caddr_t) 0;
31 * I can't tell -- is this supposed to be cv_signal() or cv_waitq_remove()?
32 * Or perhaps cv_broadcast()?
33 * Assuming cv_signal() is the desired meaning. -GAW
36 afs_osi_CancelWait(struct afs_osi_WaitHandle *achandle)
40 AFS_STATCNT(osi_CancelWait);
42 proc = achandle->proc;
45 achandle->proc = NULL; /* so dude can figure out he was signalled */
46 afs_osi_Wakeup(&waitV);
50 * Waits for data on ahandle, or ams ms later. ahandle may be null.
51 * Returns 0 if timeout and EINTR if signalled.
54 afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
59 AFS_STATCNT(osi_Wait);
61 endTime = osi_Time() + (ams / 1000);
63 ahandle->proc = (caddr_t) curproc;
66 code = afs_osi_TimedSleep(&waitV, ams, aintok);
68 break; /* if something happened, quit now */
69 /* if we we're cancelled, quit now */
70 if (ahandle && (ahandle->proc == (caddr_t) 0)) {
71 /* we've been signalled */
74 } while (osi_Time() < endTime);
80 * All this gluck should probably also be replaced with CVs.
82 typedef struct afs_event {
83 struct afs_event *next; /* next in hash chain */
84 char *event; /* lwp event: an address */
85 int refcount; /* Is it in use? */
86 int seq; /* Sequence number: this is incremented
87 * by wakeup calls; wait will not return until
94 afs_event_t *afs_evhasht[HASHSIZE]; /* Hash table for events */
95 #define afs_evhash(event) (afs_uint32) ((((long)event)>>2) & (HASHSIZE-1));
96 int afs_evhashcnt = 0;
98 #define EVTLOCK_INIT(e) \
100 mtx_init((e)->lck, "event lock", NULL, MTX_DEF); \
103 #define EVTLOCK_LOCK(e) \
105 osi_Assert((e)->owner != curthread); \
106 mtx_lock((e)->lck); \
107 osi_Assert((e)->owner == 0); \
108 (e)->owner = curthread; \
110 #define EVTLOCK_UNLOCK(e) \
112 osi_Assert((e)->owner == curthread); \
114 mtx_unlock((e)->lck); \
116 #define EVTLOCK_DESTROY(e) mtx_destroy((e)->lck)
118 /* Get and initialize event structure corresponding to lwp event (i.e. address)
121 afs_getevent(char *event)
123 afs_event_t *evp, *newp = 0;
127 hashcode = afs_evhash(event);
128 evp = afs_evhasht[hashcode];
131 if (evp->event == event) {
135 if (evp->refcount == 0)
141 newp = osi_AllocSmallSpace(sizeof(afs_event_t));
142 newp->lck = osi_AllocSmallSpace(sizeof(struct mtx));
143 memset(newp->lck, 0, sizeof(struct mtx));
145 newp->next = afs_evhasht[hashcode];
146 afs_evhasht[hashcode] = newp;
156 /* Release the specified event */
157 #define relevent(evp) \
159 osi_Assert((evp)->owner == curthread); \
162 mtx_unlock((evp)->lck); \
166 afs_osi_Sleep(void *event)
168 struct afs_event *evp;
171 evp = afs_getevent(event);
174 while (seq == evp->seq) {
176 msleep(event, evp->lck, PVFS, "afsslp", 0);
177 evp->owner = curthread;
184 afs_osi_SleepSig(void *event)
186 afs_osi_Sleep(event);
190 /* afs_osi_TimedSleep
193 * event - event to sleep on
194 * ams --- max sleep time in milliseconds
195 * aintok - 1 if should sleep interruptibly
197 * Returns 0 if timeout and EINTR if signalled.
200 afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok)
203 struct afs_event *evp;
206 evp = afs_getevent(event);
210 prio = PCATCH | PPAUSE;
214 code = msleep(event, evp->lck, prio, "afsslp", (ams * hz) / 1000);
215 evp->owner = curthread;
224 afs_osi_Wakeup(void *event)
227 struct afs_event *evp;
229 evp = afs_getevent(event);
230 if (evp->refcount > 1) {
240 shutdown_osisleep(void) {
241 struct afs_event *evp, *nevp, **pevpp;
243 for (i=0; i < HASHSIZE; i++) {
244 evp = afs_evhasht[i];
245 pevpp = &afs_evhasht[i];
249 if (evp->refcount == 0) {
250 EVTLOCK_DESTROY(evp);
252 osi_FreeSmallSpace(evp->lck);
253 osi_FreeSmallSpace(evp);