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 */
20 afs_osi_InitWaitHandle(struct afs_osi_WaitHandle
*achandle
)
22 AFS_STATCNT(osi_InitWaitHandle
);
23 cv_init(&achandle
->wh_condvar
, "afscondvar");
24 achandle
->wh_inited
= 1;
29 * I can't tell -- is this supposed to be cv_signal() or cv_waitq_remove()?
30 * Or perhaps cv_broadcast()?
31 * Assuming cv_signal() is the desired meaning. -GAW
34 afs_osi_CancelWait(struct afs_osi_WaitHandle
*achandle
)
36 AFS_STATCNT(osi_CancelWait
);
38 /* XXX should not be necessary */
39 if (!achandle
->wh_inited
)
42 cv_signal(&achandle
->wh_condvar
);
46 * Waits for data on ahandle, or ams ms later. ahandle may be null.
47 * Returns 0 if timeout and EINTR if signalled.
50 afs_osi_Wait(afs_int32 ams
, struct afs_osi_WaitHandle
*ahandle
, int aintok
)
56 AFS_STATCNT(osi_Wait
);
57 tv
.tv_sec
= ams
/ 1000;
58 tv
.tv_usec
= (ams
% 1000) * 1000;
62 if (ahandle
== NULL
) {
63 /* This is nasty and evil and rude. */
64 code
= msleep(&tv
, &afs_global_mtx
, (aintok
? PPAUSE
|PCATCH
: PVFS
),
67 if (!ahandle
->wh_inited
)
68 afs_osi_InitWaitHandle(ahandle
); /* XXX should not be needed */
70 code
= cv_timedwait_sig(&ahandle
->wh_condvar
, &afs_global_mtx
,
73 code
= cv_timedwait(&ahandle
->wh_condvar
, &afs_global_mtx
, ticks
);
78 afs_event_t
*afs_evhasht
[AFS_EVHASHSIZE
]; /* Hash table for events */
79 #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
= (afs_event_t
*) afs_osi_Alloc_NoSleep(sizeof(afs_event_t
));
105 newp
->next
= afs_evhasht
[hashcode
];
106 afs_evhasht
[hashcode
] = newp
;
114 /* Release the specified event */
115 #define relevent(evp) ((evp)->refcount--)
119 afs_osi_Sleep(void *event
)
121 struct afs_event
*evp
;
124 evp
= afs_getevent(event
);
126 while (seq
== evp
->seq
) {
128 msleep(event
, &afs_global_mtx
, PVFS
, "afsslp", 0);
134 afs_osi_SleepSig(void *event
)
136 afs_osi_Sleep(event
);
143 * event - event to sleep on
144 * ams --- max sleep time in milliseconds
145 * aintok - 1 if should sleep interruptibly
147 * Returns 0 if timeout and EINTR if signalled.
150 afs_osi_TimedSleep(void *event
, afs_int32 ams
, int aintok
)
152 struct afs_event
*evp
;
157 tv
.tv_sec
= ams
/ 1000;
158 tv
.tv_usec
= (ams
% 1000) * 1000;
161 evp
= afs_getevent(event
);
163 while (seq
== evp
->seq
) {
165 code
= msleep(event
, &afs_global_mtx
, (aintok
? PPAUSE
|PCATCH
: PVFS
),
175 afs_osi_Wakeup(void *event
)
178 struct afs_event
*evp
;
180 evp
= afs_getevent(event
);
181 if (evp
->refcount
> 1) {