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
) curthreadp
;
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 #if (_MIPS_SZPTR == 64)
76 #define afs_evhash(event) (afs_uint32) ((((long)event)>>3) & (AFS_EVHASHSIZE-1))
78 #define afs_evhash(event) (afs_uint32) ((((long)event)>>2) & (AFS_EVHASHSIZE-1))
80 int afs_evhashcnt
= 0;
82 /* Get and initialize event structure corresponding to lwp event (i.e. address)
85 afs_getevent(char *event
)
87 afs_event_t
*evp
, *newp
= 0;
91 hashcode
= afs_evhash(event
);
92 evp
= afs_evhasht
[hashcode
];
94 if (evp
->event
== event
) {
98 if (evp
->refcount
== 0)
103 newp
= osi_AllocSmallSpace(sizeof(afs_event_t
));
105 newp
->next
= afs_evhasht
[hashcode
];
106 afs_evhasht
[hashcode
] = newp
;
107 cv_init(&newp
->cond
, "event cond var", CV_DEFAULT
, NULL
);
115 /* Release the specified event */
116 #define relevent(evp) ((evp)->refcount--)
120 afs_osi_Sleep(void *event
)
122 struct afs_event
*evp
;
125 evp
= afs_getevent(event
);
127 while (seq
== evp
->seq
) {
129 cv_wait(&evp
->cond
, &afs_global_lock
);
135 afs_osi_SleepSig(void *event
)
137 afs_osi_Sleep(event
);
141 /* afs_osi_TimedSleep
144 * event - event to sleep on
145 * ams --- max sleep time in milliseconds
146 * aintok - 1 if should sleep interruptibly
148 * Returns 0 if timeout and EINTR if signalled.
151 afs_osi_TimedSleep(void *event
, afs_int32 ams
, int aintok
)
154 struct afs_event
*evp
;
155 struct timespec ticks
;
157 ticks
.tv_sec
= ams
/ 1000;
158 ticks
.tv_nsec
= (ams
- (ticks
.tv_sec
* 1000)) * 1000000;
160 evp
= afs_getevent(event
);
165 (&evp
->cond
, AFSD_PRI(), &afs_global_lock
, 0, 0, &ticks
,
166 (struct timespec
*)0))
168 AFS_MUTEX_ENTER(&afs_global_lock
);
170 cv_timedwait(&evp
->cond
, &afs_global_lock
, ticks
);
179 afs_osi_Wakeup(void *event
)
182 struct afs_event
*evp
;
184 evp
= afs_getevent(event
);
185 if (evp
->refcount
> 1) {
187 cv_broadcast(&evp
->cond
);