rwlock.h revision 1.2
11.2Smatt/*	$NetBSD: rwlock.h,v 1.2 2007/02/17 05:34:07 matt Exp $	*/
21.1Smatt
31.1Smatt/*-
41.1Smatt * Copyright (c) 2002, 2006 The NetBSD Foundation, Inc.
51.1Smatt * All rights reserved.
61.1Smatt *
71.1Smatt * This code is derived from software contributed to The NetBSD Foundation
81.1Smatt * by Jason R. Thorpe and Andrew Doran.
91.1Smatt *
101.1Smatt * Redistribution and use in source and binary forms, with or without
111.1Smatt * modification, are permitted provided that the following conditions
121.1Smatt * are met:
131.1Smatt * 1. Redistributions of source code must retain the above copyright
141.1Smatt *    notice, this list of conditions and the following disclaimer.
151.1Smatt * 2. Redistributions in binary form must reproduce the above copyright
161.1Smatt *    notice, this list of conditions and the following disclaimer in the
171.1Smatt *    documentation and/or other materials provided with the distribution.
181.1Smatt * 3. All advertising materials mentioning features or use of this software
191.1Smatt *    must display the following acknowledgement:
201.1Smatt *	This product includes software developed by the NetBSD
211.1Smatt *	Foundation, Inc. and its contributors.
221.1Smatt * 4. Neither the name of The NetBSD Foundation nor the names of its
231.1Smatt *    contributors may be used to endorse or promote products derived
241.1Smatt *    from this software without specific prior written permission.
251.1Smatt *
261.1Smatt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
271.1Smatt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
281.1Smatt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
291.1Smatt * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
301.1Smatt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
311.1Smatt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
321.1Smatt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
331.1Smatt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
341.1Smatt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
351.1Smatt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
361.1Smatt * POSSIBILITY OF SUCH DAMAGE.
371.1Smatt */
381.1Smatt
391.1Smatt#ifndef _VAX_RWLOCK_H_
401.1Smatt#define	_VAX_RWLOCK_H_
411.1Smatt
421.1Smattstruct krwlock {
431.1Smatt	volatile uintptr_t	rw_owner;
441.2Smatt	__cpu_simple_lock_t	rw_lock;
451.2Smatt	unsigned int	 	rw_id : 24;
461.1Smatt};
471.1Smatt
481.1Smatt#ifdef __RWLOCK_PRIVATE
491.1Smatt
501.1Smatt#define	RW_RECEIVE(rw)			/* nothing */
511.1Smatt#define	RW_GIVE(rw)			/* nothing */
521.1Smatt
531.2Smattbool _rw_cas(krwlock_t *rw, uintptr_t old, uintptr_t new);
541.2Smatt
551.2Smatt/*
561.2Smatt *	RW_ACQUIRE(rw, old, new)
571.2Smatt *		Perform an atomic "compare and swap" operation and
581.2Smatt *		evaluate to true or false according to the success
591.2Smatt *		of the operation, such that:
601.2Smatt *			if (rw->rw_owner == old) {
611.2Smatt *				rw->rw_owner = new;
621.2Smatt *				return 1;
631.2Smatt *			} else
641.2Smatt *				return 0;
651.2Smatt *		Must be MP/interrupt atomic.
661.2Smatt */
671.2Smatt#define	RW_ACQUIRE(rw, old, new)	_rw_cas(rw, old, new)
681.1Smatt
691.2Smatt/*
701.2Smatt *
711.2Smatt *	RW_RELEASE(rw, old, new)
721.2Smatt *		As above, but for releasing the lock.  Must be
731.2Smatt *		MP/interrupt atomic.
741.2Smatt */
751.2Smatt#define	RW_RELEASE(rw, old, new)	_rw_cas(rw, old, new)
761.2Smatt
771.2Smatt/*
781.2Smatt *	RW_SET_WAITERS(rw, need_wait, set_wait)
791.2Smatt *		Set the has-waiters indication.  If the needs-waiting
801.2Smatt *		condition becomes false, abort the operation.  Must
811.2Smatt *		be MP/interrupt atomic.
821.2Smatt */
831.2Smattstatic inline bool
841.2SmattRW_SET_WAITERS(krwlock_t *rw, uintptr_t need, uintptr_t set)
851.2Smatt{
861.2Smatt	uintptr_t old = rw->rw_owner;
871.2Smatt	if (old & need)
881.2Smatt		return _rw_cas(rw, old, old | set);
891.2Smatt	return false;
901.2Smatt}
911.2Smatt
921.2Smatt/*
931.2Smatt *	RW_SETID(rw, id)
941.2Smatt *		Set the debugging ID for the lock, an integer.  Only
951.2Smatt *		used in the LOCKDEBUG case.
961.2Smatt */
971.2Smattstatic inline void
981.2SmattRW_SETID(krwlock_t *rw, u_int id)
991.2Smatt{
1001.2Smatt	rw->rw_id = id;
1011.2Smatt}
1021.2Smatt
1031.2Smatt/*
1041.2Smatt *	RW_GETID(rw)
1051.2Smatt *		Get the debugging ID for the lock, an integer.  Only
1061.2Smatt *		used in the LOCKDEBUG case.
1071.2Smatt */
1081.2Smattstatic inline u_int
1091.2SmattRW_GETID(krwlock_t *rw)
1101.2Smatt{
1111.2Smatt	return rw->rw_id;
1121.2Smatt}
1131.1Smatt
1141.1Smatt#endif	/* __RWLOCK_PRIVATE */
1151.1Smatt
1161.1Smatt#endif /* _VAX_RWLOCK_H_ */
117