Source-Changes-D archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: CVS commit: src/sys



Hi,

After this commit, the kernel stalls just before root file system
will be found on my NetBSD/amd64 laptop.

Reverting
src/sys/kern/kern_rwlock.c to r1.60
and
src/sys/sys/rwlock.h to r1.12
in latest -current tree and I can get the kernel that works like
before.

And on another laptop, the problematic kernel stalls before root file
system detection like my laptop.

It may be universal problem.

Could you take a look at this problem?

Thank you.

"Andrew Doran" <ad%netbsd.org@localhost> writes:

> Module Name:	src
> Committed By:	ad
> Date:		Sun Jan 19 18:34:24 UTC 2020
>
> Modified Files:
> 	src/sys/kern: kern_rwlock.c
> 	src/sys/sys: rwlock.h
>
> Log Message:
> Tidy rwlocks a bit, no functional change intended.  Mainly:
>
> - rw_downgrade(): do it in a for () loop like all the others.
> - Explicitly carry around RW_NODEBUG - don't be lazy.
> - Remove pointless macros.
> - Don't make assertions conditional on LOCKDEBUG, there's no reason.
> - Make space for a new flag bit (not added yet).
>
>
> To generate a diff of this commit:
> cvs rdiff -u -r1.60 -r1.61 src/sys/kern/kern_rwlock.c
> cvs rdiff -u -r1.12 -r1.13 src/sys/sys/rwlock.h
>
> Please note that diffs are not public domain; they are subject to the
> copyright notices on the relevant files.
>
> Modified files:
>
> Index: src/sys/kern/kern_rwlock.c
> diff -u src/sys/kern/kern_rwlock.c:1.60 src/sys/kern/kern_rwlock.c:1.61
> --- src/sys/kern/kern_rwlock.c:1.60	Sun Jan 12 18:37:10 2020
> +++ src/sys/kern/kern_rwlock.c	Sun Jan 19 18:34:24 2020
> @@ -1,4 +1,4 @@
> -/*	$NetBSD: kern_rwlock.c,v 1.60 2020/01/12 18:37:10 ad Exp $	*/
> +/*	$NetBSD: kern_rwlock.c,v 1.61 2020/01/19 18:34:24 ad Exp $	*/
>  
>  /*-
>   * Copyright (c) 2002, 2006, 2007, 2008, 2009, 2019, 2020
> @@ -39,7 +39,9 @@
>   */
>  
>  #include <sys/cdefs.h>
> -__KERNEL_RCSID(0, "$NetBSD: kern_rwlock.c,v 1.60 2020/01/12 18:37:10 ad Exp $");
> +__KERNEL_RCSID(0, "$NetBSD: kern_rwlock.c,v 1.61 2020/01/19 18:34:24 ad Exp $");
> +
> +#include "opt_lockdebug.h"
>  
>  #define	__RWLOCK_PRIVATE
>  
> @@ -63,58 +65,32 @@ __KERNEL_RCSID(0, "$NetBSD: kern_rwlock.
>   * LOCKDEBUG
>   */
>  
> -#if defined(LOCKDEBUG)
> -
> -#define	RW_WANTLOCK(rw, op)						\
> -	LOCKDEBUG_WANTLOCK(RW_DEBUG_P(rw), (rw),			\
> -	    (uintptr_t)__builtin_return_address(0), op == RW_READER);
> -#define	RW_LOCKED(rw, op)						\
> -	LOCKDEBUG_LOCKED(RW_DEBUG_P(rw), (rw), NULL,			\
> -	    (uintptr_t)__builtin_return_address(0), op == RW_READER);
> -#define	RW_UNLOCKED(rw, op)						\
> -	LOCKDEBUG_UNLOCKED(RW_DEBUG_P(rw), (rw),			\
> -	    (uintptr_t)__builtin_return_address(0), op == RW_READER);
> -#define	RW_DASSERT(rw, cond)						\
> -do {									\
> -	if (__predict_false(!(cond)))					\
> -		rw_abort(__func__, __LINE__, rw, "assertion failed: " #cond);\
> -} while (/* CONSTCOND */ 0);
> -
> -#else	/* LOCKDEBUG */
> -
> -#define	RW_WANTLOCK(rw, op)	/* nothing */
> -#define	RW_LOCKED(rw, op)	/* nothing */
> -#define	RW_UNLOCKED(rw, op)	/* nothing */
> -#define	RW_DASSERT(rw, cond)	/* nothing */
> +#define	RW_DEBUG_P(rw)		(((rw)->rw_owner & RW_NODEBUG) == 0)
>  
> -#endif	/* LOCKDEBUG */
> +#define	RW_WANTLOCK(rw, op) \
> +    LOCKDEBUG_WANTLOCK(RW_DEBUG_P(rw), (rw), \
> +        (uintptr_t)__builtin_return_address(0), op == RW_READER);
> +#define	RW_LOCKED(rw, op) \
> +    LOCKDEBUG_LOCKED(RW_DEBUG_P(rw), (rw), NULL, \
> +        (uintptr_t)__builtin_return_address(0), op == RW_READER);
> +#define	RW_UNLOCKED(rw, op) \
> +    LOCKDEBUG_UNLOCKED(RW_DEBUG_P(rw), (rw), \
> +        (uintptr_t)__builtin_return_address(0), op == RW_READER);
>  
>  /*
>   * DIAGNOSTIC
>   */
>  
>  #if defined(DIAGNOSTIC)
> -
> -#define	RW_ASSERT(rw, cond)						\
> -do {									\
> -	if (__predict_false(!(cond)))					\
> +#define	RW_ASSERT(rw, cond) \
> +do { \
> +	if (__predict_false(!(cond))) \
>  		rw_abort(__func__, __LINE__, rw, "assertion failed: " #cond);\
>  } while (/* CONSTCOND */ 0)
> -
>  #else
> -
>  #define	RW_ASSERT(rw, cond)	/* nothing */
> -
>  #endif	/* DIAGNOSTIC */
>  
> -#define	RW_SETDEBUG(rw, on)		((rw)->rw_owner |= (on) ? 0 : RW_NODEBUG)
> -#define	RW_DEBUG_P(rw)			(((rw)->rw_owner & RW_NODEBUG) == 0)
> -#if defined(LOCKDEBUG)
> -#define	RW_INHERITDEBUG(n, o)		(n) |= (o) & RW_NODEBUG
> -#else /* defined(LOCKDEBUG) */
> -#define	RW_INHERITDEBUG(n, o)		/* nothing */
> -#endif /* defined(LOCKDEBUG) */
> -
>  /*
>   * Memory barriers.
>   */
> @@ -128,29 +104,6 @@ do {									\
>  #define	RW_MEMBAR_PRODUCER()		membar_producer()
>  #endif
>  
> -static void	rw_abort(const char *, size_t, krwlock_t *, const char *);
> -static void	rw_dump(const volatile void *, lockop_printer_t);
> -static lwp_t	*rw_owner(wchan_t);
> -
> -static inline uintptr_t
> -rw_cas(krwlock_t *rw, uintptr_t o, uintptr_t n)
> -{
> -
> -	RW_INHERITDEBUG(n, o);
> -	return (uintptr_t)atomic_cas_ptr((volatile void *)&rw->rw_owner,
> -	    (void *)o, (void *)n);
> -}
> -
> -static inline void
> -rw_swap(krwlock_t *rw, uintptr_t o, uintptr_t n)
> -{
> -
> -	RW_INHERITDEBUG(n, o);
> -	n = (uintptr_t)atomic_swap_ptr((volatile void *)&rw->rw_owner,
> -	    (void *)n);
> -	RW_DASSERT(rw, n == o);
> -}
> -
>  /*
>   * For platforms that do not provide stubs, or for the LOCKDEBUG case.
>   */
> @@ -164,6 +117,10 @@ __strong_alias(rw_exit,rw_vector_exit);
>  __strong_alias(rw_tryenter,rw_vector_tryenter);
>  #endif
>  
> +static void	rw_abort(const char *, size_t, krwlock_t *, const char *);
> +static void	rw_dump(const volatile void *, lockop_printer_t);
> +static lwp_t	*rw_owner(wchan_t);
> +
>  lockops_t rwlock_lockops = {
>  	.lo_name = "Reader / writer lock",
>  	.lo_type = LOCKOPS_SLEEP,
> @@ -179,6 +136,37 @@ syncobj_t rw_syncobj = {
>  };
>  
>  /*
> + * rw_cas:
> + *
> + *	Do an atomic compare-and-swap on the lock word.
> + */
> +static inline uintptr_t
> +rw_cas(krwlock_t *rw, uintptr_t o, uintptr_t n)
> +{
> +
> +	return (uintptr_t)atomic_cas_ptr((volatile void *)&rw->rw_owner,
> +	    (void *)o, (void *)n);
> +}
> +
> +/*
> + * rw_swap:
> + *
> + *	Do an atomic swap of the lock word.  This is used only when it's
> + *	known that the lock word is set up such that it can't be changed
> + *	behind us (assert this), so there's no point considering the result.
> + */
> +static inline void
> +rw_swap(krwlock_t *rw, uintptr_t o, uintptr_t n)
> +{
> +
> +	n = (uintptr_t)atomic_swap_ptr((volatile void *)&rw->rw_owner,
> +	    (void *)n);
> +
> +	RW_ASSERT(rw, n == o);
> +	RW_ASSERT(rw, (o & RW_HAS_WAITERS) != 0);
> +}
> +
> +/*
>   * rw_dump:
>   *
>   *	Dump the contents of a rwlock structure.
> @@ -214,16 +202,14 @@ rw_abort(const char *func, size_t line, 
>   *
>   *	Initialize a rwlock for use.
>   */
> -void _rw_init(krwlock_t *, uintptr_t);
>  void
>  _rw_init(krwlock_t *rw, uintptr_t return_address)
>  {
> -	bool dodebug;
>  
> -	memset(rw, 0, sizeof(*rw));
> -
> -	dodebug = LOCKDEBUG_ALLOC(rw, &rwlock_lockops, return_address);
> -	RW_SETDEBUG(rw, dodebug);
> +	if (LOCKDEBUG_ALLOC(rw, &rwlock_lockops, return_address))
> +		rw->rw_owner = 0;
> +	else
> +		rw->rw_owner = RW_NODEBUG;
>  }
>  
>  void
> @@ -243,7 +229,7 @@ rw_destroy(krwlock_t *rw)
>  {
>  
>  	RW_ASSERT(rw, (rw->rw_owner & ~RW_NODEBUG) == 0);
> -	LOCKDEBUG_FREE(RW_DEBUG_P(rw), rw);
> +	LOCKDEBUG_FREE((rw->rw_owner & RW_NODEBUG) == 0, rw);
>  }
>  
>  /*
> @@ -327,7 +313,7 @@ rw_vector_enter(krwlock_t *rw, const krw
>  		need_wait = RW_WRITE_LOCKED | RW_WRITE_WANTED;
>  		queue = TS_READER_Q;
>  	} else {
> -		RW_DASSERT(rw, op == RW_WRITER);
> +		RW_ASSERT(rw, op == RW_WRITER);
>  		incr = curthread | RW_WRITE_LOCKED;
>  		set_wait = RW_HAS_WAITERS | RW_WRITE_WANTED;
>  		need_wait = RW_WRITE_LOCKED | RW_THREAD;
> @@ -430,7 +416,7 @@ rw_vector_enter(krwlock_t *rw, const krw
>  	      (uintptr_t)__builtin_return_address(0)));
>  	LOCKSTAT_EXIT(lsflag);
>  
> -	RW_DASSERT(rw, (op != RW_READER && RW_OWNER(rw) == curthread) ||
> +	RW_ASSERT(rw, (op != RW_READER && RW_OWNER(rw) == curthread) ||
>  	    (op == RW_READER && RW_COUNT(rw) != 0));
>  	RW_LOCKED(rw, op);
>  }
> @@ -448,7 +434,8 @@ rw_vector_exit(krwlock_t *rw)
>  	int rcnt, wcnt;
>  	lwp_t *l;
>  
> -	curthread = (uintptr_t)curlwp;
> +	l = curlwp;
> +	curthread = (uintptr_t)l;
>  	RW_ASSERT(rw, curthread != 0);
>  
>  	/*
> @@ -491,8 +478,8 @@ rw_vector_exit(krwlock_t *rw)
>  	 */
>  	ts = turnstile_lookup(rw);
>  	owner = rw->rw_owner;
> -	RW_DASSERT(rw, ts != NULL);
> -	RW_DASSERT(rw, (owner & RW_HAS_WAITERS) != 0);
> +	RW_ASSERT(rw, ts != NULL);
> +	RW_ASSERT(rw, (owner & RW_HAS_WAITERS) != 0);
>  
>  	wcnt = TS_WAITERS(ts, TS_WRITER_Q);
>  	rcnt = TS_WAITERS(ts, TS_READER_Q);
> @@ -509,31 +496,35 @@ rw_vector_exit(krwlock_t *rw)
>  	 * do the work of acquiring the lock in rw_vector_enter().
>  	 */
>  	if (rcnt == 0 || decr == RW_READ_INCR) {
> -		RW_DASSERT(rw, wcnt != 0);
> -		RW_DASSERT(rw, (owner & RW_WRITE_WANTED) != 0);
> +		RW_ASSERT(rw, wcnt != 0);
> +		RW_ASSERT(rw, (owner & RW_WRITE_WANTED) != 0);
>  
>  		if (rcnt != 0) {
>  			/* Give the lock to the longest waiting writer. */
>  			l = TS_FIRST(ts, TS_WRITER_Q);
> -			newown = (uintptr_t)l | RW_WRITE_LOCKED | RW_HAS_WAITERS;
> +			newown = (uintptr_t)l | (owner & RW_NODEBUG);
> +			newown |= RW_WRITE_LOCKED | RW_HAS_WAITERS;
>  			if (wcnt > 1)
>  				newown |= RW_WRITE_WANTED;
>  			rw_swap(rw, owner, newown);
>  			turnstile_wakeup(ts, TS_WRITER_Q, 1, l);
>  		} else {
>  			/* Wake all writers and let them fight it out. */
> -			rw_swap(rw, owner, RW_WRITE_WANTED);
> +			newown = owner & RW_NODEBUG;
> +			newown |= RW_WRITE_WANTED;
> +			rw_swap(rw, owner, newown);
>  			turnstile_wakeup(ts, TS_WRITER_Q, wcnt, NULL);
>  		}
>  	} else {
> -		RW_DASSERT(rw, rcnt != 0);
> +		RW_ASSERT(rw, rcnt != 0);
>  
>  		/*
>  		 * Give the lock to all blocked readers.  If there
>  		 * is a writer waiting, new readers that arrive
>  		 * after the release will be blocked out.
>  		 */
> -		newown = rcnt << RW_READ_COUNT_SHIFT;
> +		newown = owner & RW_NODEBUG;
> +		newown += rcnt << RW_READ_COUNT_SHIFT;
>  		if (wcnt != 0)
>  			newown |= RW_HAS_WAITERS | RW_WRITE_WANTED;
>  			
> @@ -552,8 +543,10 @@ int
>  rw_vector_tryenter(krwlock_t *rw, const krw_t op)
>  {
>  	uintptr_t curthread, owner, incr, need_wait, next;
> +	lwp_t *l;
>  
> -	curthread = (uintptr_t)curlwp;
> +	l = curlwp;
> +	curthread = (uintptr_t)l;
>  
>  	RW_ASSERT(rw, curthread != 0);
>  
> @@ -561,7 +554,7 @@ rw_vector_tryenter(krwlock_t *rw, const 
>  		incr = RW_READ_INCR;
>  		need_wait = RW_WRITE_LOCKED | RW_WRITE_WANTED;
>  	} else {
> -		RW_DASSERT(rw, op == RW_WRITER);
> +		RW_ASSERT(rw, op == RW_WRITER);
>  		incr = curthread | RW_WRITE_LOCKED;
>  		need_wait = RW_WRITE_LOCKED | RW_THREAD;
>  	}
> @@ -572,24 +565,23 @@ rw_vector_tryenter(krwlock_t *rw, const 
>  		next = rw_cas(rw, owner, owner + incr);
>  		if (__predict_true(next == owner)) {
>  			/* Got it! */
> -			RW_MEMBAR_ENTER();
>  			break;
>  		}
>  	}
>  
>  	RW_WANTLOCK(rw, op);
>  	RW_LOCKED(rw, op);
> -	RW_DASSERT(rw, (op != RW_READER && RW_OWNER(rw) == curthread) ||
> +	RW_ASSERT(rw, (op != RW_READER && RW_OWNER(rw) == curthread) ||
>  	    (op == RW_READER && RW_COUNT(rw) != 0));
>  
> +	RW_MEMBAR_ENTER();
>  	return 1;
>  }
>  
>  /*
>   * rw_downgrade:
>   *
> - *	Downgrade a write lock to a read lock.  Optimise memory accesses for
> - *	the uncontended case.
> + *	Downgrade a write lock to a read lock.
>   */
>  void
>  rw_downgrade(krwlock_t *rw)
> @@ -597,55 +589,64 @@ rw_downgrade(krwlock_t *rw)
>  	uintptr_t owner, curthread, newown, next;
>  	turnstile_t *ts;
>  	int rcnt, wcnt;
> +	lwp_t *l;
>  
> -	curthread = (uintptr_t)curlwp;
> +	l = curlwp;
> +	curthread = (uintptr_t)l;
>  	RW_ASSERT(rw, curthread != 0);
> -	RW_DASSERT(rw, (rw->rw_owner & RW_WRITE_LOCKED) != 0);
> +	RW_ASSERT(rw, (rw->rw_owner & RW_WRITE_LOCKED) != 0);
>  	RW_ASSERT(rw, RW_OWNER(rw) == curthread);
>  	RW_UNLOCKED(rw, RW_WRITER);
>  #if !defined(DIAGNOSTIC)
>  	__USE(curthread);
>  #endif
>  
> -	/*
> -	 * If there are no waiters, so we can do this the easy way.
> -	 * Try swapping us down to one read hold.  If it fails, the
> -	 * lock condition has changed and we most likely now have
> -	 * waiters.
> -	 */
>  	RW_MEMBAR_PRODUCER();
> -	owner = curthread | RW_WRITE_LOCKED;
> -	next = rw_cas(rw, owner, RW_READ_INCR);
> -	if (__predict_true(next == owner)) {
> -		RW_LOCKED(rw, RW_READER);
> -		RW_DASSERT(rw, (rw->rw_owner & RW_WRITE_LOCKED) == 0);
> -		RW_DASSERT(rw, RW_COUNT(rw) != 0);
> -		return;
> -	}
>  
> -	/*
> -	 * Grab the turnstile chain lock.  This gets the interlock
> -	 * on the sleep queue.  Once we have that, we can adjust the
> -	 * waiter bits.
> -	 */
> -	for (;;) {
> -		owner = next;
> +	for (owner = rw->rw_owner;; owner = next) {
> +		/*
> +		 * If there are no waiters we can do this the easy way.  Try
> +		 * swapping us down to one read hold.  If it fails, the lock
> +		 * condition has changed and we most likely now have
> +		 * waiters.
> +		 */
> +		if ((owner & RW_HAS_WAITERS) == 0) {
> +			newown = (owner & RW_NODEBUG);
> +			next = rw_cas(rw, owner, newown + RW_READ_INCR);
> +			if (__predict_true(next == owner)) {
> +				RW_LOCKED(rw, RW_READER);
> +				RW_ASSERT(rw,
> +				    (rw->rw_owner & RW_WRITE_LOCKED) == 0);
> +				RW_ASSERT(rw, RW_COUNT(rw) != 0);
> +				return;
> +			}
> +			continue;
> +		}
> +
> +		/*
> +		 * Grab the turnstile chain lock.  This gets the interlock
> +		 * on the sleep queue.  Once we have that, we can adjust the
> +		 * waiter bits.
> +		 */
>  		ts = turnstile_lookup(rw);
> -		RW_DASSERT(rw, ts != NULL);
> +		RW_ASSERT(rw, ts != NULL);
>  
>  		rcnt = TS_WAITERS(ts, TS_READER_Q);
>  		wcnt = TS_WAITERS(ts, TS_WRITER_Q);
>  
> -		/*
> -		 * If there are no readers, just preserve the waiters
> -		 * bits, swap us down to one read hold and return.
> -		 */
>  		if (rcnt == 0) {
> -			RW_DASSERT(rw, wcnt != 0);
> -			RW_DASSERT(rw, (rw->rw_owner & RW_WRITE_WANTED) != 0);
> -			RW_DASSERT(rw, (rw->rw_owner & RW_HAS_WAITERS) != 0);
> -
> -			newown = RW_READ_INCR | RW_HAS_WAITERS | RW_WRITE_WANTED;
> +			/*
> +			 * If there are no readers, just preserve the
> +			 * waiters bits, swap us down to one read hold and
> +			 * return.
> +			 */
> +			RW_ASSERT(rw, wcnt != 0);
> +			RW_ASSERT(rw, (rw->rw_owner & RW_WRITE_WANTED) != 0);
> +			RW_ASSERT(rw, (rw->rw_owner & RW_HAS_WAITERS) != 0);
> +
> +			newown = owner & RW_NODEBUG;
> +			newown = RW_READ_INCR | RW_HAS_WAITERS |
> +			    RW_WRITE_WANTED;
>  			next = rw_cas(rw, owner, newown);
>  			turnstile_exit(rw);
>  			if (__predict_true(next == owner))
> @@ -653,11 +654,12 @@ rw_downgrade(krwlock_t *rw)
>  		} else {
>  			/*
>  			 * Give the lock to all blocked readers.  We may
> -			 * retain one read hold if downgrading.  If there
> -			 * is a writer waiting, new readers will be blocked
> +			 * retain one read hold if downgrading.  If there is
> +			 * a writer waiting, new readers will be blocked
>  			 * out.
>  			 */
> -			newown = (rcnt << RW_READ_COUNT_SHIFT) + RW_READ_INCR;
> +			newown = owner & RW_NODEBUG;
> +			newown += (rcnt << RW_READ_COUNT_SHIFT) + RW_READ_INCR;
>  			if (wcnt != 0)
>  				newown |= RW_HAS_WAITERS | RW_WRITE_WANTED;
>  
> @@ -673,22 +675,24 @@ rw_downgrade(krwlock_t *rw)
>  
>  	RW_WANTLOCK(rw, RW_READER);
>  	RW_LOCKED(rw, RW_READER);
> -	RW_DASSERT(rw, (rw->rw_owner & RW_WRITE_LOCKED) == 0);
> -	RW_DASSERT(rw, RW_COUNT(rw) != 0);
> +	RW_ASSERT(rw, (rw->rw_owner & RW_WRITE_LOCKED) == 0);
> +	RW_ASSERT(rw, RW_COUNT(rw) != 0);
>  }
>  
>  /*
>   * rw_tryupgrade:
>   *
>   *	Try to upgrade a read lock to a write lock.  We must be the only
> - *	reader.  Optimise memory accesses for the uncontended case.
> + *	reader.
>   */
>  int
>  rw_tryupgrade(krwlock_t *rw)
>  {
>  	uintptr_t owner, curthread, newown, next;
> +	struct lwp *l;
>  
> -	curthread = (uintptr_t)curlwp;
> +	l = curlwp;
> +	curthread = (uintptr_t)l;
>  	RW_ASSERT(rw, curthread != 0);
>  	RW_ASSERT(rw, rw_read_held(rw));
>  
> @@ -709,8 +713,8 @@ rw_tryupgrade(krwlock_t *rw)
>  	RW_UNLOCKED(rw, RW_READER);
>  	RW_WANTLOCK(rw, RW_WRITER);
>  	RW_LOCKED(rw, RW_WRITER);
> -	RW_DASSERT(rw, rw->rw_owner & RW_WRITE_LOCKED);
> -	RW_DASSERT(rw, RW_OWNER(rw) == curthread);
> +	RW_ASSERT(rw, rw->rw_owner & RW_WRITE_LOCKED);
> +	RW_ASSERT(rw, RW_OWNER(rw) == curthread);
>  
>  	return 1;
>  }
>
> Index: src/sys/sys/rwlock.h
> diff -u src/sys/sys/rwlock.h:1.12 src/sys/sys/rwlock.h:1.13
> --- src/sys/sys/rwlock.h:1.12	Wed Jan  1 21:34:39 2020
> +++ src/sys/sys/rwlock.h	Sun Jan 19 18:34:24 2020
> @@ -1,7 +1,7 @@
> -/*	$NetBSD: rwlock.h,v 1.12 2020/01/01 21:34:39 ad Exp $	*/
> +/*	$NetBSD: rwlock.h,v 1.13 2020/01/19 18:34:24 ad Exp $	*/
>  
>  /*-
> - * Copyright (c) 2002, 2006, 2007, 2008, 2019 The NetBSD Foundation, Inc.
> + * Copyright (c) 2002, 2006, 2007, 2008, 2019, 2020 The NetBSD Foundation, Inc.
>   * All rights reserved.
>   *
>   * This code is derived from software contributed to The NetBSD Foundation
> @@ -45,10 +45,6 @@
>   *	rw_tryenter()
>   */
>  
> -#if defined(_KERNEL_OPT)
> -#include "opt_lockdebug.h"
> -#endif
> -
>  #if !defined(_KERNEL)
>  #include <sys/types.h>
>  #include <sys/inttypes.h>
> @@ -75,13 +71,9 @@ typedef struct krwlock krwlock_t;
>  #define	RW_HAS_WAITERS		0x01UL	/* lock has waiters */
>  #define	RW_WRITE_WANTED		0x02UL	/* >= 1 waiter is a writer */
>  #define	RW_WRITE_LOCKED		0x04UL	/* lock is currently write locked */
> -#if defined(LOCKDEBUG)
> -#define	RW_NODEBUG		0x08UL	/* LOCKDEBUG disabled */
> -#else
> -#define	RW_NODEBUG		0x00UL	/* do nothing */
> -#endif	/* LOCKDEBUG */
> +#define	RW_NODEBUG		0x10UL	/* LOCKDEBUG disabled */
>  
> -#define	RW_READ_COUNT_SHIFT	4
> +#define	RW_READ_COUNT_SHIFT	5
>  #define	RW_READ_INCR		(1UL << RW_READ_COUNT_SHIFT)
>  #define	RW_THREAD		((uintptr_t)-RW_READ_INCR)
>  #define	RW_OWNER(rw)		((rw)->rw_owner & RW_THREAD)
> @@ -91,6 +83,7 @@ typedef struct krwlock krwlock_t;
>  void	rw_vector_enter(krwlock_t *, const krw_t);
>  void	rw_vector_exit(krwlock_t *);
>  int	rw_vector_tryenter(krwlock_t *, const krw_t);
> +void	_rw_init(krwlock_t *, uintptr_t);
>  #endif	/* __RWLOCK_PRIVATE */
>  
>  struct krwlock {
>

-- 
Ryo ONODERA // ryo%tetera.org@localhost
PGP fingerprint = 82A2 DC91 76E0 A10A 8ABB  FD1B F404 27FA C7D1 15F3


Home | Main Index | Thread Index | Old Index