From 836c5bcfaf33ec118e209b066639c5196efedf47 Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Thu, 1 Apr 2010 23:17:53 -0400 Subject: [PATCH] freebsd switch back to condvar-based sleep add TimedSleep for condvar-based sleep. this should be revisited; mac and freebsd should be able to share this. possibly several other platforms. Change-Id: I918f45a689dd129119477cc63820f5c802e182d2 Reviewed-on: http://gerrit.openafs.org/1684 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- src/afs/FBSD/osi_sleep.c | 152 ++++++++++++--------------------------- src/afs/afs_osi.h | 5 ++ 2 files changed, 51 insertions(+), 106 deletions(-) diff --git a/src/afs/FBSD/osi_sleep.c b/src/afs/FBSD/osi_sleep.c index b70d3c4a9..107a2b8f2 100644 --- a/src/afs/FBSD/osi_sleep.c +++ b/src/afs/FBSD/osi_sleep.c @@ -16,14 +16,12 @@ #include "afsincludes.h" /* Afs-based standard headers */ #include "afs/afs_stats.h" /* afs statistics */ -static char waitV; - - void afs_osi_InitWaitHandle(struct afs_osi_WaitHandle *achandle) { AFS_STATCNT(osi_InitWaitHandle); - achandle->proc = (caddr_t) 0; + cv_init(&achandle->wh_condvar, "afscondvar"); + achandle->wh_inited = 1; } /* cancel osi_Wait */ @@ -35,15 +33,13 @@ afs_osi_InitWaitHandle(struct afs_osi_WaitHandle *achandle) void afs_osi_CancelWait(struct afs_osi_WaitHandle *achandle) { - caddr_t proc; - AFS_STATCNT(osi_CancelWait); - proc = achandle->proc; - if (proc == 0) + /* XXX should not be necessary */ + if (!achandle->wh_inited) return; - achandle->proc = NULL; /* so dude can figure out he was signalled */ - afs_osi_Wakeup(&waitV); + AFS_ASSERT_GLOCK(); + cv_signal(&achandle->wh_condvar); } /* afs_osi_Wait @@ -54,25 +50,28 @@ int afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok) { int code; - afs_int32 endTime; + struct timeval tv; + int ticks; AFS_STATCNT(osi_Wait); + tv.tv_sec = ams / 1000; + tv.tv_usec = (ams % 1000) * 1000; + ticks = tvtohz(&tv); - endTime = osi_Time() + (ams / 1000); - if (ahandle) - ahandle->proc = (caddr_t) curproc; - do { - AFS_ASSERT_GLOCK(); - code = afs_osi_TimedSleep(&waitV, ams, aintok); - if (code) - break; /* if something happened, quit now */ - /* if we we're cancelled, quit now */ - if (ahandle && (ahandle->proc == (caddr_t) 0)) { - /* we've been signalled */ - break; - } - } while (osi_Time() < endTime); - + AFS_ASSERT_GLOCK(); + if (ahandle == NULL) { + /* This is nasty and evil and rude. */ + code = msleep(&tv, &afs_global_mtx, (aintok ? PPAUSE|PCATCH : PVFS), + "afswait", ticks); + } else { + if (!ahandle->wh_inited) + afs_osi_InitWaitHandle(ahandle); /* XXX should not be needed */ + if (aintok) + code = cv_timedwait_sig(&ahandle->wh_condvar, &afs_global_mtx, + ticks); + else + code = cv_timedwait(&ahandle->wh_condvar, &afs_global_mtx, ticks); + } return code; } @@ -86,8 +85,7 @@ typedef struct afs_event { int seq; /* Sequence number: this is incremented * by wakeup calls; wait will not return until * it changes */ - struct mtx *lck; - struct thread *owner; + int cond; } afs_event_t; #define HASHSIZE 128 @@ -95,26 +93,6 @@ afs_event_t *afs_evhasht[HASHSIZE]; /* Hash table for events */ #define afs_evhash(event) (afs_uint32) ((((long)event)>>2) & (HASHSIZE-1)); int afs_evhashcnt = 0; -#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) - /* Get and initialize event structure corresponding to lwp event (i.e. address) * */ static afs_event_t * @@ -127,40 +105,29 @@ afs_getevent(char *event) 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 = osi_AllocSmallSpace(sizeof(afs_event_t)); - newp->lck = osi_AllocSmallSpace(sizeof(struct mtx)); - memset(newp->lck, 0, sizeof(struct mtx)); + newp = (afs_event_t *) osi_AllocSmallSpace(sizeof(afs_event_t)); afs_evhashcnt++; 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 */ -#define relevent(evp) \ - do { \ - osi_Assert((evp)->owner == curthread); \ - (evp)->refcount--; \ - (evp)->owner = 0; \ - mtx_unlock((evp)->lck); \ - } while (0) +#define relevent(evp) ((evp)->refcount--) + void afs_osi_Sleep(void *event) @@ -170,14 +137,11 @@ afs_osi_Sleep(void *event) evp = afs_getevent(event); seq = evp->seq; - AFS_GUNLOCK(); while (seq == evp->seq) { - evp->owner = 0; - msleep(event, evp->lck, PVFS, "afsslp", 0); - evp->owner = curthread; + AFS_ASSERT_GLOCK(); + msleep(event, &afs_global_mtx, PVFS, "afsslp", 0); } relevent(evp); - AFS_GLOCK(); } int @@ -187,7 +151,7 @@ afs_osi_SleepSig(void *event) return 0; } -/* afs_osi_TimedSleep +/* osi_TimedSleep * * Arguments: * event - event to sleep on @@ -199,24 +163,25 @@ afs_osi_SleepSig(void *event) int afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok) { - int code = 0; struct afs_event *evp; - int seq, prio; + int seq, code; + struct timeval tv; + int ticks; + + tv.tv_sec = ams / 1000; + tv.tv_usec = (ams % 1000) * 1000; + ticks = tvtohz(&tv); evp = afs_getevent(event); seq = evp->seq; - AFS_GUNLOCK(); - if (aintok) - prio = PCATCH | PPAUSE; - else - prio = PVFS; - evp->owner = 0; - code = msleep(event, evp->lck, prio, "afsslp", (ams * hz) / 1000); - evp->owner = curthread; - if (seq == evp->seq) - code = EINTR; + while (seq == evp->seq) { + AFS_ASSERT_GLOCK(); + code = msleep(event, &afs_global_mtx, (aintok ? PPAUSE|PCATCH : PVFS), + "afstslp", ticks); + if (code == EINTR) + break; + } relevent(evp); - AFS_GLOCK(); return code; } @@ -235,28 +200,3 @@ 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->lck); - osi_FreeSmallSpace(evp); - afs_evhashcnt--; - } else { - EVTLOCK_UNLOCK(evp); - pevpp = &evp->next; - } - evp = nevp; - } - } -} diff --git a/src/afs/afs_osi.h b/src/afs/afs_osi.h index b83f1d6e6..20e3c54dd 100644 --- a/src/afs/afs_osi.h +++ b/src/afs/afs_osi.h @@ -85,7 +85,12 @@ struct osi_dev { }; struct afs_osi_WaitHandle { +#ifdef AFS_FBSD_ENV + struct cv wh_condvar; + int wh_inited; +#else caddr_t proc; /* process waiting */ +#endif }; #define osi_SetFileProc(x,p) ((x)->proc=(p)) -- 2.39.5