#ifndef __AFSLOCK_INCLUDE__
#define __AFSLOCK_INCLUDE__ 1
-#if !defined(lint) && !defined(LOCORE) && defined(RCS_HDRS)
+#if !defined(KERNEL) && !defined(KDUMP_KERNEL)
+#error Do not include afs/lock.h except for kernel code.
#endif
/*
* LICENSED MATERIALS - PROPERTY OF IBM
*/
-/* The following macros allow multi statement macros to be defined safely, i.e.
- - the multi statement macro can be the object of an if statement;
- - the call to the multi statement macro may be legally followed by a semi-colon.
- BEGINMAC and ENDMAC have been tested with both the portable C compiler and
- Hi-C. Both compilers were from the Palo Alto 4.2BSD software releases, and
- both optimized out the constant loop code. For an example of the use
- of BEGINMAC and ENDMAC, see the definition for ReleaseWriteLock, below.
- An alternative to this, using "if(1)" for BEGINMAC is not used because it
- may generate worse code with pcc, and may generate warning messages with hi-C.
-*/
-
#if (defined(AFS_SUN5_ENV)) || defined(AFS_OSF_ENV)
#define AFS_NOBOZO_LOCK
#endif
#if !defined(AFS_OSF20_ENV) || defined(AFS_OSF30_ENV) || defined(AFS_OSF32_ENV)
/* We do not instrument locks on osf20 because the vcache structure
- ** exceeds the maximim possible limit for a vnode.
- */
+ ** exceeds the maximim possible limit for a vnode.
+ */
#define INSTRUMENT_LOCKS
/* This is the max lock number in use. Please update it if you add any new
* lock numbers.
*/
-#define MAX_LOCK_NUMBER 572
-#endif
+#define MAX_LOCK_NUMBER 700
+#endif
struct afs_bozoLock {
- short count; /* count of excl locks */
- char flags; /* bit 1: is anyone waiting? */
- char spare; /* for later */
- char *proc; /* process holding the lock, really a struct proc * */
+ short count; /* count of excl locks */
+ char flags; /* bit 1: is anyone waiting? */
+ char spare; /* for later */
+ char *proc; /* process holding the lock, really a struct proc * */
};
#ifndef AFS_NOBOZO_LOCK
typedef struct afs_bozoLock afs_bozoLock_t;
#define afs_CheckBozonLockBlocking(lock) 0
#endif
-#define AFS_BOZONWAITING 1 /* someone is waiting for this lock */
+#define AFS_BOZONWAITING 1 /* someone is waiting for this lock */
#undef MObtainWriteLock /* Defined also in ../rx/rx_machdep.h" */
#undef MReleaseWriteLock
-#ifndef RXObtainWriteLock
-#define RXObtainWriteLock(lock) ObtainWriteLock(lock)
-#define RXReleaseWriteLock(lock) ReleaseWriteLock(lock)
-#endif
#define MObtainReadLock(lock) ObtainReadLock(lock)
#define MObtainWriteLock(lock,src) ObtainWriteLock(lock,src)
#define MObtainSharedLock(lock,src) ObtainSharedLock(lock,src)
#undef LOCK_INIT
#define LOCK_INIT(lock, nm) Lock_Init(lock)
+/* The following macros allow multi statement macros to be defined safely, i.e.
+ - the multi statement macro can be the object of an if statement;
+ - the call to the multi statement macro may be legally followed by a semi-colon.
+ BEGINMAC and ENDMAC have been tested with both the portable C compiler and
+ Hi-C. Both compilers were from the Palo Alto 4.2BSD software releases, and
+ both optimized out the constant loop code. For an example of the use
+ of BEGINMAC and ENDMAC, see the definition for ReleaseWriteLock, below.
+ An alternative to this, using "if(1)" for BEGINMAC is not used because it
+ may generate worse code with pcc, and may generate warning messages with hi-C.
+*/
+
#define BEGINMAC do {
#define ENDMAC } while (0)
-#if defined(AFS_SUN5_ENV)
+#if defined(AFS_SUN57_ENV)
+typedef kthread_t * afs_lock_tracker_t;
+#define MyPidxx (curthread)
+#define MyPidxx2Pid(x) (x ? ttoproc(x)->p_pid : 0)
+#elif defined(AFS_SUN5_ENV) || defined(AFS_OBSD_ENV)
+typedef unsigned int afs_lock_tracker_t;
#define MyPidxx (curproc->p_pid)
+#define MyPidxx2Pid(x) (x)
#else
#if defined(AFS_AIX41_ENV)
+typedef tid_t afs_lock_tracker_t;
extern tid_t thread_self();
-#define MyPidxx thread_self()
+#define MyPidxx (thread_self())
+#define MyPidxx2Pid(x) ((afs_int32)(x))
#else /* AFS_AIX41_ENV */
#if defined(AFS_HPUX101_ENV)
-#define MyPidxx ((int)p_pid(u.u_procp))
+#if defined(AFS_HPUX1111_ENV)
+typedef struct kthread * afs_lock_tracker_t;
+#define MyPidxx (u.u_kthreadp)
+#define MyPidxx2Pid(x) (x ? kt_tid(x) : 0)
+#else
+typedef struct proc * afs_lock_tracker_t;
+#define MyPidxx (u.u_procp)
+#define MyPidxx2Pid(x) (x ? (afs_int32)p_pid(x) : 0)
+#endif
#else
#if defined(AFS_SGI64_ENV)
#if defined(AFS_SGI65_ENV)
+typedef unsigned int afs_lock_tracker_t;
#define MyPidxx proc_pid(curproc())
+#define MyPidxx2Pid(x) (x)
#else
+typedef unsigned int afs_lock_tracker_t;
#define MyPidxx current_pid()
+#define MyPidxx2Pid(x) (x)
#endif
#else /* AFS_SGI64_ENV */
#ifdef AFS_LINUX20_ENV
-#define MyPidxx current->pid
+typedef struct task_struct * afs_lock_tracker_t;
+#define MyPidxx (current)
+#define MyPidxx2Pid(x) (x? (x)->pid : 0)
+#else
+#if defined(AFS_DARWIN_ENV)
+#if defined(AFS_DARWIN80_ENV)
+typedef unsigned int afs_lock_tracker_t;
+#define MyPidxx (proc_selfpid())
+#define MyPidxx2Pid(x) (x)
+#else
+typedef unsigned int afs_lock_tracker_t;
+#define MyPidxx (current_proc()->p_pid )
+#define MyPidxx2Pid(x) (x)
+#endif
#else
+#if defined(AFS_FBSD_ENV)
+typedef unsigned int afs_lock_tracker_t;
+#define MyPidxx (curproc->p_pid )
+#define MyPidxx2Pid(x) (x)
+#else
+typedef unsigned int afs_lock_tracker_t;
#define MyPidxx (u.u_procp->p_pid )
+#define MyPidxx2Pid(x) (x)
+#endif /* AFS_FBSD_ENV */
+#endif /* AFS_DARWIN_ENV */
#endif /* AFS_LINUX20_ENV */
#endif /* AFS_SGI64_ENV */
#endif /* AFS_HPUX101_ENV */
#endif /* AFS_AIX41_ENV */
-#endif
+#endif
/* all locks wait on excl_locked except for READ_LOCK, which waits on readers_reading */
struct afs_lock {
- unsigned char wait_states; /* type of lockers waiting */
- unsigned char excl_locked; /* anyone have boosted, shared or write lock? */
- unsigned short readers_reading;/* # readers actually with read locks */
- unsigned short num_waiting; /* probably need this soon */
- unsigned short spare; /* not used now */
- osi_timeval_t time_waiting; /* for statistics gathering */
+ unsigned char wait_states; /* type of lockers waiting */
+ unsigned char excl_locked; /* anyone have boosted, shared or write lock? */
+ unsigned short readers_reading; /* # readers actually with read locks */
+ unsigned short num_waiting; /* probably need this soon */
+ unsigned short spare; /* not used now */
+ osi_timeval_t time_waiting; /* for statistics gathering */
#if defined(INSTRUMENT_LOCKS)
/* the following are useful for debugging
- ** the field 'src_indicator' is updated only by ObtainLock() and
- ** only for writes/shared locks. Hence, it indictes where in the
- ** source code the shared/write lock was set.
- */
- unsigned int pid_last_reader;/* proceess id of last reader */
- unsigned int pid_writer; /* process id of writer, else 0 */
- unsigned int src_indicator; /* third param to ObtainLock()*/
-#endif /* INSTRUMENT_LOCKS */
+ ** the field 'src_indicator' is updated only by ObtainLock() and
+ ** only for writes/shared locks. Hence, it indictes where in the
+ ** source code the shared/write lock was set.
+ */
+ afs_lock_tracker_t pid_last_reader; /* proceess id of last reader */
+ afs_lock_tracker_t pid_writer; /* process id of writer, else 0 */
+ unsigned int src_indicator; /* third param to ObtainLock() */
+#endif /* INSTRUMENT_LOCKS */
};
typedef struct afs_lock afs_lock_t;
typedef struct afs_lock afs_rwlock_t;
#include "icl.h"
extern int afs_trclock;
+
+#define AFS_LOCK_TRACE_ENABLE 0
+#if AFS_LOCK_TRACE_ENABLE
+#define AFS_LOCK_TRACE(op, lock, type) \
+ if (afs_trclock) Afs_Lock_Trace(op, lock, type, __FILE__, __LINE__);
+#else
+#define AFS_LOCK_TRACE(op, lock, type)
+#endif
+
#if defined(INSTRUMENT_LOCKS)
#define ObtainReadLock(lock)\
BEGINMAC \
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKOBTAIN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)READ_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKOBTAIN, lock, READ_LOCK);\
if (!((lock)->excl_locked & WRITE_LOCK)) \
((lock)->readers_reading)++; \
else \
#define ObtainWriteLock(lock, src)\
BEGINMAC \
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKOBTAIN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)WRITE_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKOBTAIN, lock, WRITE_LOCK);\
if (!(lock)->excl_locked && !(lock)->readers_reading)\
(lock) -> excl_locked = WRITE_LOCK;\
else\
(lock)->src_indicator = src;\
ENDMAC
-#define NBObtainWriteLock(lock, src) (((lock)->excl_locked || (lock)->readers_reading) ? EWOULDBLOCK : ((lock) -> excl_locked = WRITE_LOCK), ((lock)->pid_writer = MyPidxx), ((lock)->src_indicator = src), 0)
+#define NBObtainWriteLock(lock, src) (((lock)->excl_locked || (lock)->readers_reading) ? EWOULDBLOCK : (((lock) -> excl_locked = WRITE_LOCK), ((lock)->pid_writer = MyPidxx), ((lock)->src_indicator = src), 0))
#define ObtainSharedLock(lock, src)\
BEGINMAC \
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKOBTAIN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)SHARED_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKOBTAIN, lock, SHARED_LOCK);\
if (!(lock)->excl_locked)\
(lock) -> excl_locked = SHARED_LOCK;\
else\
(lock)->src_indicator = src;\
ENDMAC
+#define NBObtainSharedLock(lock, src) (((lock)->excl_locked) ? EWOULDBLOCK : (((lock) -> excl_locked = SHARED_LOCK), ((lock)->pid_writer = MyPidxx), ((lock)->src_indicator = src), 0))
+
#define UpgradeSToWLock(lock, src)\
BEGINMAC \
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKOBTAIN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)BOOSTED_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKOBTAIN, lock, BOOSTED_LOCK);\
if (!(lock)->readers_reading)\
(lock)->excl_locked = WRITE_LOCK;\
else\
/* this must only be called with a WRITE or boosted SHARED lock! */
#define ConvertWToSLock(lock)\
BEGINMAC\
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKDOWN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)SHARED_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKDOWN, lock, SHARED_LOCK);\
(lock)->excl_locked = SHARED_LOCK; \
if((lock)->wait_states) \
Afs_Lock_ReleaseR(lock); \
#define ConvertWToRLock(lock) \
BEGINMAC\
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKDOWN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)READ_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKDOWN, lock, READ_LOCK);\
(lock)->excl_locked &= ~(SHARED_LOCK | WRITE_LOCK);\
((lock)->readers_reading)++;\
(lock)->pid_last_reader = MyPidxx ; \
#define ConvertSToRLock(lock) \
BEGINMAC\
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKDOWN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)READ_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKDOWN, lock, READ_LOCK);\
(lock)->excl_locked &= ~(SHARED_LOCK | WRITE_LOCK);\
((lock)->readers_reading)++;\
(lock)->pid_last_reader = MyPidxx ; \
#define ReleaseReadLock(lock)\
BEGINMAC\
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKDONE, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)READ_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKDONE, lock, READ_LOCK);\
if (!(--((lock)->readers_reading)) && (lock)->wait_states)\
Afs_Lock_ReleaseW(lock) ; \
if ( (lock)->pid_last_reader == MyPidxx ) \
#define ReleaseWriteLock(lock)\
BEGINMAC\
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKDONE, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)WRITE_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKDONE, lock, WRITE_LOCK);\
(lock)->excl_locked &= ~WRITE_LOCK;\
if ((lock)->wait_states) Afs_Lock_ReleaseR(lock);\
(lock)->pid_writer=0; \
/* can be used on shared or boosted (write) locks */
#define ReleaseSharedLock(lock)\
BEGINMAC\
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKDONE, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)SHARED_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKDONE, lock, SHARED_LOCK);\
(lock)->excl_locked &= ~(SHARED_LOCK | WRITE_LOCK);\
if ((lock)->wait_states) Afs_Lock_ReleaseR(lock);\
(lock)->pid_writer=0; \
#define ObtainReadLock(lock)\
BEGINMAC \
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKOBTAIN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)READ_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKOBTAIN, lock, READ_LOCK);\
if (!((lock)->excl_locked & WRITE_LOCK)) \
((lock)->readers_reading)++; \
else \
#define ObtainWriteLock(lock, src)\
BEGINMAC \
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKOBTAIN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)WRITE_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKOBTAIN, lock, WRITE_LOCK);\
if (!(lock)->excl_locked && !(lock)->readers_reading)\
(lock) -> excl_locked = WRITE_LOCK;\
else\
Afs_Lock_Obtain(lock, WRITE_LOCK); \
ENDMAC
-#define NBObtainWriteLock(lock, src) (((lock)->excl_locked || (lock)->readers_reading) ? EWOULDBLOCK : ((lock) -> excl_locked = WRITE_LOCK), 0)
+#define NBObtainWriteLock(lock, src) (((lock)->excl_locked || (lock)->readers_reading) ? EWOULDBLOCK : (((lock) -> excl_locked = WRITE_LOCK), 0))
#define ObtainSharedLock(lock, src)\
BEGINMAC \
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKOBTAIN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)SHARED_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKOBTAIN, lock, SHARED_LOCK);\
if (!(lock)->excl_locked)\
(lock) -> excl_locked = SHARED_LOCK;\
else\
Afs_Lock_Obtain(lock, SHARED_LOCK); \
ENDMAC
+#define NBObtainSharedLock(lock, src) (((lock)->excl_locked) ? EWOULDBLOCK : (((lock) -> excl_locked = SHARED_LOCK), 0))
+
#define UpgradeSToWLock(lock, src)\
BEGINMAC \
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKOBTAIN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)BOOSTED_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKOBTAIN, lock, BOOSTED_LOCK);\
if (!(lock)->readers_reading)\
(lock)->excl_locked = WRITE_LOCK;\
else\
/* this must only be called with a WRITE or boosted SHARED lock! */
#define ConvertWToSLock(lock)\
BEGINMAC\
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKDOWN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)SHARED_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKDOWN, lock, SHARED_LOCK);\
(lock)->excl_locked = SHARED_LOCK; \
if((lock)->wait_states) \
Afs_Lock_ReleaseR(lock); \
#define ConvertWToRLock(lock) \
BEGINMAC\
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKDOWN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)READ_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKDOWN, lock, READ_LOCK);\
(lock)->excl_locked &= ~(SHARED_LOCK | WRITE_LOCK);\
((lock)->readers_reading)++;\
Afs_Lock_ReleaseR(lock);\
#define ConvertSToRLock(lock) \
BEGINMAC\
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKDOWN, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)READ_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKDOWN, lock, READ_LOCK);\
(lock)->excl_locked &= ~(SHARED_LOCK | WRITE_LOCK);\
((lock)->readers_reading)++;\
Afs_Lock_ReleaseR(lock);\
#define ReleaseReadLock(lock)\
BEGINMAC\
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKDONE, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)READ_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKDONE, lock, READ_LOCK);\
if (!(--((lock)->readers_reading)) && (lock)->wait_states)\
Afs_Lock_ReleaseW(lock) ; \
ENDMAC
#define ReleaseWriteLock(lock)\
BEGINMAC\
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKDONE, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)WRITE_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKDONE, lock, WRITE_LOCK);\
(lock)->excl_locked &= ~WRITE_LOCK;\
if ((lock)->wait_states) Afs_Lock_ReleaseR(lock);\
ENDMAC
/* can be used on shared or boosted (write) locks */
#define ReleaseSharedLock(lock)\
BEGINMAC\
-/* if (afs_trclock) {icl_Trace2(cm_iclSetp, CM_TRACE_LOCKDONE, ICL_TYPE_POINTER, (long)lock, ICL_TYPE_LONG, (long)SHARED_LOCK);} */ \
+ AFS_LOCK_TRACE(CM_TRACE_LOCKDONE, lock, SHARED_LOCK);\
(lock)->excl_locked &= ~(SHARED_LOCK | WRITE_LOCK);\
if ((lock)->wait_states) Afs_Lock_ReleaseR(lock);\
ENDMAC