#include "afsincludes.h" /* Afs-based standard headers */
#include "afs/afs_stats.h" /* afs statistics */
-
-
-static int osi_TimedSleep(char *event, afs_int32 ams, int aintok);
-
static char waitV;
static void
do {
AFS_ASSERT_GLOCK();
code = 0;
- code = osi_TimedSleep(&waitV, ams, aintok);
+ code = afs_osi_TimedSleep(&waitV, ams, aintok);
if (code)
break; /* if something happened, quit now */
return 0;
}
-/* osi_TimedSleep
+/* afs_osi_TimedSleep
*
* Arguments:
* event - event to sleep on
*
* Returns 0 if timeout and EINTR if signalled.
*/
-static int
-osi_TimedSleep(char *event, afs_int32 ams, int aintok)
+int
+afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok)
{
int code = 0;
struct afs_event *evp;
#include "afsincludes.h" /* Afs-based standard headers */
#include "afs/afs_stats.h" /* afs statistics */
-
-static int osi_TimedSleep(char *event, afs_int32 ams, int aintok);
-
static char waitV;
-
void
afs_osi_InitWaitHandle(struct afs_osi_WaitHandle *achandle)
{
do {
AFS_ASSERT_GLOCK();
code = 0;
- code = osi_TimedSleep(&waitV, ams, aintok);
+ code = afs_osi_TimedSleep(&waitV, ams, aintok);
if (code)
break; /* if something happened, quit now */
return 0;
}
-/* osi_TimedSleep
+/* afs_osi_TimedSleep
*
* Arguments:
* event - event to sleep on
*
* Returns 0 if timeout and EINTR if signalled.
*/
-static int
-osi_TimedSleep(char *event, afs_int32 ams, int aintok)
+int
+afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok)
{
int code = 0;
struct afs_event *evp;
#include "afs/afs_stats.h" /* afs statistics */
#ifndef AFS_FBSD50_ENV
-static int osi_TimedSleep(char *event, afs_int32 ams, int aintok);
static char waitV;
#endif
AFS_ASSERT_GLOCK();
if (ahandle == NULL) {
/* This is nasty and evil and rude. */
+ afs_global_owner = 0;
code = msleep(&tv, &afs_global_mtx, (aintok ? PPAUSE|PCATCH : PVFS),
"afswait", ticks);
+ afs_global_owner = curthread;
} else {
if (!ahandle->wh_inited)
afs_osi_InitWaitHandle(ahandle); /* XXX should not be needed */
ahandle->proc = (caddr_t) curproc;
do {
AFS_ASSERT_GLOCK();
- code = osi_TimedSleep(&waitV, ams, aintok);
+ code = afs_osi_TimedSleep(&waitV, ams, aintok);
if (code)
break; /* if something happened, quit now */
/* if we we're cancelled, quit now */
int seq; /* Sequence number: this is incremented
* by wakeup calls; wait will not return until
* it changes */
+#ifdef AFS_FBSD50_ENV
+ struct mtx *lck;
+ struct thread *owner;
+#else
int cond;
+#endif
} afs_event_t;
#define HASHSIZE 128
#define afs_evhash(event) (afs_uint32) ((((long)event)>>2) & (HASHSIZE-1));
int afs_evhashcnt = 0;
+#ifdef AFS_FBSD50_ENV
+#define EVTLOCK_INIT(e) \
+ do { \
+ mtx_init((e)->lck, "event lock", NULL, MTX_DEF); \
+ (e)->owner = 0; \
+ } while (0)
+#define EVTLOCK_LOCK(e) \
+ do { \
+ osi_Assert((e)->owner != curthread); \
+ mtx_lock((e)->lck); \
+ osi_Assert((e)->owner == 0); \
+ (e)->owner = curthread; \
+ } while (0)
+#define EVTLOCK_UNLOCK(e) \
+ do { \
+ osi_Assert((e)->owner == curthread); \
+ (e)->owner = 0; \
+ mtx_unlock((e)->lck); \
+ } while (0)
+#define EVTLOCK_DESTROY(e) mtx_destroy((e)->lck)
+#else
+#define EVTLOCK_INIT(e)
+#define EVTLOCK_LOCK(e)
+#define EVTLOCK_UNLOCK(e)
+#define EVTLOCK_DESTROY(e)
+#endif
+#endif
+
/* Get and initialize event structure corresponding to lwp event (i.e. address)
* */
static afs_event_t *
hashcode = afs_evhash(event);
evp = afs_evhasht[hashcode];
while (evp) {
+ EVTLOCK_LOCK(evp);
if (evp->event == event) {
evp->refcount++;
return evp;
}
if (evp->refcount == 0)
newp = evp;
+ EVTLOCK_UNLOCK(evp);
evp = evp->next;
}
if (!newp) {
newp->next = afs_evhasht[hashcode];
afs_evhasht[hashcode] = newp;
newp->seq = 0;
+ EVTLOCK_INIT(newp);
}
+ EVTLOCK_LOCK(newp);
newp->event = event;
newp->refcount = 1;
return newp;
}
/* Release the specified event */
+#ifdef AFS_FBSD50_ENV
+#define relevent(evp) \
+ do { \
+ osi_Assert((evp)->owner == curthread); \
+ (evp)->refcount--; \
+ (evp)->owner = 0; \
+ mtx_unlock((evp)->lck); \
+ } while (0)
+#else
#define relevent(evp) ((evp)->refcount--)
-
+#endif
void
afs_osi_Sleep(void *event)
while (seq == evp->seq) {
AFS_ASSERT_GLOCK();
#ifdef AFS_FBSD50_ENV
+ evp->owner = 0;
msleep(event, &afs_global_mtx, PVFS, "afsslp", 0);
+ evp->owner = curthread;
#else
AFS_GUNLOCK();
tsleep(event, PVFS, "afs_osi_Sleep", 0);
return 0;
}
-#ifndef AFS_FBSD50_ENV
-/* osi_TimedSleep
+/* afs_osi_TimedSleep
*
* Arguments:
* event - event to sleep on
*
* Returns 0 if timeout and EINTR if signalled.
*/
-static int
-osi_TimedSleep(char *event, afs_int32 ams, int aintok)
+int
+afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok)
{
int code = 0;
struct afs_event *evp;
- int ticks;
int seq, prio;
-
- ticks = (ams * afs_hz) / 1000;
-
+ struct timespec ts;
evp = afs_getevent(event);
seq = evp->seq;
prio = PCATCH | PPAUSE;
else
prio = PVFS;
- code = tsleep(event, prio, "afs_osi_TimedSleep", ticks);
- AFS_GLOCK();
+ ts.tv_sec = ams / 1000;
+ ts.tv_nsec = (ams % 1000) * 1000000;
+ evp->owner = 0;
+ code = msleep(event, evp->lck, prio, "afsslp", &ts);
+ evp->owner = curthread;
if (seq == evp->seq)
code = EINTR;
relevent(evp);
+ AFS_GLOCK();
return code;
}
-#endif /* not AFS_FBSD50_ENV */
int
afs_osi_Wakeup(void *event)
relevent(evp);
return ret;
}
+
+void
+shutdown_osisleep(void) {
+ struct afs_event *evp, *nevp, **pevpp;
+ int i;
+ for (i=0; i < HASHSIZE; i++) {
+ evp = afs_evhasht[i];
+ pevpp = &afs_evhasht[i];
+ while (evp) {
+ EVTLOCK_LOCK(evp);
+ nevp = evp->next;
+ if (evp->refcount == 0) {
+ EVTLOCK_DESTROY(evp);
+ *pevpp = evp->next;
+ osi_FreeSmallSpace(evp);
+ afs_evhashcnt--;
+ } else {
+ EVTLOCK_UNLOCK(evp);
+ pevpp = &evp->next;
+ }
+ evp = nevp;
+ }
+ }
+}
}
#if defined(AFS_HPUX110_ENV)
+int
+afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok)
+{
+ lock_t *sleep_lock;
+ int intr = EWOULDBLOCK;
+
+ AFS_ASSERT_GLOCK();
+ AFS_GUNLOCK();
+ afs_osi_CallProc(AfsWaitHack, event, ams);
+ sleep((caddr_t) event, PZERO - 2);
+ if (afs_osi_CancelProc(AfsWaitHack, event) < 0)
+ intr = 0;
+ AFS_GLOCK();
+ return intr;
+}
+
void
afs_osi_Sleep(void *event)
{
#include "afsincludes.h" /* Afs-based standard headers */
#include "afs/afs_stats.h" /* afs statistics */
-
-
-static int osi_TimedSleep(char *event, afs_int32 ams, int aintok);
-
static char waitV;
-
void
afs_osi_InitWaitHandle(struct afs_osi_WaitHandle *achandle)
{
do {
AFS_ASSERT_GLOCK();
code = 0;
- code = osi_TimedSleep(&waitV, ams, aintok);
+ code = afs_osi_TimedSleep(&waitV, ams, aintok);
if (code)
break; /* if something happened, quit now */
return 0;
}
-/* osi_TimedSleep
+/* afs_osi_TimedSleep
*
* Arguments:
* event - event to sleep on
*
* Returns 0 if timeout and EINTR if signalled.
*/
-static int
-osi_TimedSleep(char *event, afs_int32 ams, int aintok)
+int
+afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok)
{
int code = 0;
struct afs_event *evp;
ticks.tv_sec = ams / 1000;
ticks.tv_nsec = (ams - (ticks.tv_sec * 1000)) * 1000000;
-
evp = afs_getevent(event);
AFS_ASSERT_GLOCK();
#include <linux/freezer.h>
#endif
-static int osi_TimedSleep(char *event, afs_int32 ams, int aintok);
-
static char waitV, dummyV;
void
do {
AFS_ASSERT_GLOCK();
- code = osi_TimedSleep(&waitV, ams, 1);
+ code = afs_osi_TimedSleep(&waitV, ams, 1);
if (code)
break;
if (ahandle && (ahandle->proc == (caddr_t) 0)) {
SIG_UNLOCK(current);
}
-/* osi_TimedSleep
+/* afs_osi_TimedSleep
*
* Arguments:
* event - event to sleep on
* Returns 0 if timeout, EINTR if signalled, and EGAIN if it might
* have raced.
*/
-static int
-osi_TimedSleep(char *event, afs_int32 ams, int aintok)
+int
+afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok)
{
int code = 0;
long ticks = (ams * HZ / 1000) + 1;
#include <linux/freezer.h>
#endif
-static int osi_TimedSleep(char *event, afs_int32 ams, int aintok);
-
static char waitV, dummyV;
void
do {
AFS_ASSERT_GLOCK();
- code = osi_TimedSleep(&waitV, ams, 1);
+ code = afs_osi_TimedSleep(&waitV, ams, 1);
if (code)
break;
if (ahandle && (ahandle->proc == (caddr_t) 0)) {
SIG_UNLOCK(current);
}
-/* osi_TimedSleep
+/* afs_osi_TimedSleep
*
* Arguments:
* event - event to sleep on
* Returns 0 if timeout, EINTR if signalled, and EGAIN if it might
* have raced.
*/
-static int
-osi_TimedSleep(char *event, afs_int32 ams, int aintok)
+int
+afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok)
{
int code = 0;
long ticks = (ams * HZ / 1000) + 1;
#include "afsincludes.h" /* Afs-based standard headers */
#include "afs/afs_stats.h" /* afs statistics */
-
-
-static int osi_TimedSleep(char *event, afs_int32 ams, int aintok);
static char waitV;
-
void
afs_osi_InitWaitHandle(struct afs_osi_WaitHandle *achandle)
{
do {
AFS_ASSERT_GLOCK();
code = 0;
- code = osi_TimedSleep(&waitV, ams, aintok);
+ code = afs_osi_TimedSleep(&waitV, ams, aintok);
if (code)
break; /* if something happened, quit now */
return 0;
}
-/* osi_TimedSleep
+/* afs_osi_TimedSleep
*
* Arguments:
* event - event to sleep on
*
* Returns 0 if timeout and EINTR if signalled.
*/
-static int
-osi_TimedSleep(char *event, afs_int32 ams, int aintok)
+int
+afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok)
{
int code = 0;
struct afs_event *evp;
return code;
}
+int
+afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok)
+{
+ int code = 0;
+ struct afs_event *evp;
+ int seq, prio;
+ int ticks;
+
+ evp = afs_getevent(event);
+ seq = evp->seq;
+ AFS_GUNLOCK();
+ if (aintok)
+ prio = PCATCH | PPAUSE;
+ else
+ prio = PVFS;
+ ticks = (ams * afs_hz) / 1000;
+ code = tsleep(event, prio, "afs_osi_TimedSleep", ticks);
+ if (seq == evp->seq)
+ code = EINTR;
+ relevent(evp);
+ AFS_GLOCK();
+ return code;
+}
+
void
afs_osi_Sleep(void *event)
{
#include "afsincludes.h" /* Afs-based standard headers */
#include "afs/afs_stats.h" /* afs statistics */
-static int osi_TimedSleep(char *event, afs_int32 ams, int aintok);
-
static char waitV;
void
do {
AFS_ASSERT_GLOCK();
code = 0;
- code = osi_TimedSleep(&waitV, ams, aintok);
+ code = afs_osi_TimedSleep(&waitV, ams, aintok);
if (code)
break; /* if something happened, quit now */
return code;
}
-/* osi_TimedSleep
+/* afs_osi_TimedSleep
*
* Arguments:
* event - event to sleep on
*
* Returns 0 if timeout and EINTR if signalled.
*/
-static int
-osi_TimedSleep(char *event, afs_int32 ams, int aintok)
+int
+afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok)
{
int code = 0;
struct afs_event *evp;
}
int
+afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok)
+{
+ return afs_osi_Wait(ams, event, aintok);
+}
+
+int
afs_osi_Wait(afs_int32 msec, struct afs_osi_WaitHandle *handle, int intok)
{
int index;
extern void afs_osi_CancelWait(struct afs_osi_WaitHandle *achandle);
extern int afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle,
int aintok);
+extern int afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok);
#ifndef afs_osi_Wakeup
extern int afs_osi_Wakeup(void *event);
#endif