From owner-freebsd-smp@FreeBSD.ORG Tue Jul 6 12:34:59 2004 Return-Path: Delivered-To: freebsd-smp@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 680) id E0F6A16A4CF; Tue, 6 Jul 2004 12:34:59 +0000 (GMT) To: freebsd-smp@freebsd.org Message-Id: <20040706123459.E0F6A16A4CF@hub.freebsd.org> Date: Tue, 6 Jul 2004 12:34:59 +0000 (GMT) From: darrenr@FreeBSD.ORG (Darren Reed) cc: darrenr@FreeBSD.ORG cc: scottl@FreeBSD.ORG cc: jasone@FreeBSD.ORG cc: jhb@FreeBSD.ORG Subject: patch for to introduce sx_unlock() X-BeenThere: freebsd-smp@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: FreeBSD SMP implementation group List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 06 Jul 2004 12:35:00 -0000 Often you don't care how you got the lock, you just want to get rid of it. Or there maybe multiple different ways the lock could be acquired, all ending in a common point of code where whether it was exclusive or not has been forgotten. This macro isn't really that safe if you look at the _sx_sunlock and _sx_xunlock code (mutex is acquired on sx_lock before anything else) but if we assume the calling code is well behaved, it should be fine (fingers crossed :) as we already have a lock of some sort on sx and no external influences should be able to change the behaviour of the #define code (even if it is locked in shared mode.) If something is wrong then the entry point code in sx_{x,s}unlock() should catch it. There are other alternatives, including merging sx_sunlock() and sx_xunlock() into a sx_unlock() and making the former functions just wrapper #defines for sx_unlock. I'd just commit this but I'm not one of the SMP-elite for FreeBSD :) As a btw, I believe this comment at the bottom of sx(9) is incorrect: A thread may not own a shared lock and an exclusive lock simultaneously; attempting to do so will result in deadlock. Or if it is, the sx implementation is not as useful as it could be if that statement were redundant. Darren Index: sys/sx.h =================================================================== RCS file: /home/ncvs/src/sys/sys/sx.h,v retrieving revision 1.19 diff -c -r1.19 sx.h *** sys/sx.h 4 Feb 2004 14:18:21 -0000 1.19 --- sys/sx.h 6 Jul 2004 12:13:25 -0000 *************** *** 60,65 **** --- 60,72 ---- #ifdef INVARIANT_SUPPORT void _sx_assert(struct sx *sx, int what, const char *file, int line); #endif + #define sx_unlock(sx, file, line) \ + do { \ + if ((sx)->sx_cnt < 0) \ + sx_xunlock(sx, file, line); \ + else + sx_sunlock(sx, file, line); \ + } while (0) struct sx_args { struct sx *sa_sx;