patch for <sys/sx.h> to introduce sx_unlock()

Darren Reed darrenr at FreeBSD.ORG
Tue Jul 6 05:35:00 PDT 2004


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;


More information about the freebsd-smp mailing list