/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ /* * rx_kmutex.h - mutex and condition variable macros for kernel environment. * * FBSD implementation. */ #ifndef _RX_KMUTEX_H_ #define _RX_KMUTEX_H_ #include #include #ifdef AFS_FBSD70_ENV #include #include #else #include #endif #define RX_ENABLE_LOCKS 1 typedef int afs_kcondvar_t; #define HEAVY_LOCKS #if defined(NULL_LOCKS) typedef struct { struct proc *owner; } afs_kmutex_t; #define MUTEX_INIT(a,b,c,d) \ do { \ (a)->owner = 0; \ } while(0) #define MUTEX_DESTROY(a) \ do { \ (a)->owner = (struct proc *)-1; \ } while(0) #define MUTEX_ENTER(a) \ do { \ osi_Assert((a)->owner == 0); \ (a)->owner = curproc; \ } while(0) #define MUTEX_TRYENTER(a) \ ( osi_Assert((a)->owner == 0), (a)->owner = curproc, 1) #define MUTEX_EXIT(a) \ do { \ osi_Assert((a)->owner == curproc); \ (a)->owner = 0; \ } while(0) #define MUTEX_ASSERT(a) osi_Assert(((afs_kmutex_t *)(a))->owner == curproc) #elif defined(AFS_FBSD70_ENV) /* dunno about 6.x */ typedef struct mtx afs_kmutex_t; #if defined(AFS_FBSD80_ENV) && defined(WITNESS) #define WITCLEAR_MTX(a) \ do { memset((a), 0, sizeof(struct mtx)); } while(0) #else #define WITCLEAR_MTX(a) {} #endif #define MUTEX_INIT(a,b,c,d) \ do { \ WITCLEAR_MTX(a); \ mtx_init((a), (b), 0 /* type defaults to name */, MTX_DEF | MTX_DUPOK); \ } while(0) #define MUTEX_DESTROY(a) \ do { \ mtx_destroy((a)); \ } while(0) #define MUTEX_ENTER(a) \ do { \ mtx_lock((a)); \ } while(0) #define MUTEX_TRYENTER(a) \ ( mtx_trylock((a)) ) #define MUTEX_EXIT(a) \ do { \ mtx_unlock((a)); \ } while(0) #define MUTEX_ASSERT(a) \ osi_Assert(mtx_owned((a))) #else typedef struct { struct lock lock; struct thread *owner; } afs_kmutex_t; #define MUTEX_INIT(a,b,c,d) \ do { \ lockinit(&(a)->lock,PSOCK, "afs rx mutex", 0, 0); \ (a)->owner = 0; \ } while(0) #define MUTEX_DESTROY(a) \ do { \ (a)->owner = (struct proc *)-1; \ } while(0) #define MUTEX_ENTER(a) \ do { \ lockmgr(&(a)->lock, LK_EXCLUSIVE, 0, curthread); \ osi_Assert((a)->owner == 0); \ (a)->owner = curthread; \ } while(0) #define MUTEX_TRYENTER(a) \ ( lockmgr(&(a)->lock, LK_EXCLUSIVE|LK_NOWAIT, 0, curthread) ? 0 : ((a)->owner = curthread, 1) ) #define xMUTEX_TRYENTER(a) \ ( osi_Assert((a)->owner == 0), (a)->owner = curthread, 1) #define MUTEX_EXIT(a) \ do { \ osi_Assert((a)->owner == curthread); \ (a)->owner = 0; \ lockmgr(&(a)->lock, LK_RELEASE, 0, curthread); \ } while(0) #define MUTEX_ASSERT(a) osi_Assert(((afs_kmutex_t *)(a))->owner == curthread) #endif /* * Condition variables * * In Digital Unix (OSF/1), we use something akin to the ancient sleep/wakeup * mechanism. The condition variable itself plays no role; we just use its * address as a convenient unique number. */ #define CV_INIT(cv,a,b,c) #define CV_DESTROY(cv) #if defined(AFS_FBSD70_ENV) #define CV_WAIT(cv, lck) { \ int isGlockOwner = ISAFS_GLOCK(); \ if (isGlockOwner) AFS_GUNLOCK(); \ msleep(cv, lck, PSOCK, "afs_rx_cv_wait", 0); \ if (isGlockOwner) AFS_GLOCK(); \ } #define CV_TIMEDWAIT(cv,lck,t) { \ int isGlockOwner = ISAFS_GLOCK(); \ if (isGlockOwner) AFS_GUNLOCK(); \ msleep(cv, lck, PSOCK, "afs_rx_cv_timedwait", t); \ if (isGlockOwner) AFS_GLOCK(); \ } #else /* !AFS_FBSD70_ENV */ #define CV_WAIT(cv, lck) { \ int isGlockOwner = ISAFS_GLOCK(); \ if (isGlockOwner) AFS_GUNLOCK(); \ MUTEX_EXIT(lck); \ tsleep(cv, PSOCK, "afs_rx_cv_wait", 0); \ if (isGlockOwner) AFS_GLOCK(); \ MUTEX_ENTER(lck); \ } #define CV_TIMEDWAIT(cv,lck,t) { \ int isGlockOwner = ISAFS_GLOCK(); \ if (isGlockOwner) AFS_GUNLOCK(); \ MUTEX_EXIT(lck); \ tsleep(cv, PSOCK, "afs_rx_cv_timedwait", t); \ if (isGlockOwner) AFS_GLOCK(); \ MUTEX_ENTER(lck); \ } #endif /* AFS_FBSD80_ENV */ #define CV_SIGNAL(cv) wakeup_one(cv) #define CV_BROADCAST(cv) wakeup(cv) /* #define osi_rxWakeup(cv) wakeup(cv) */ #endif /* _RX_KMUTEX_H_ */