Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Oct 2014 20:27:21 +0100
From:      Mateusz Guzik <mjguzik@gmail.com>
To:        John Baldwin <jhb@freebsd.org>
Cc:        John-Mark Gurney <jmg@funkthat.com>, freebsd-arch@freebsd.org
Subject:   Re: refcount_release_take_##lock
Message-ID:  <20141027192721.GA28049@dft-labs.eu>
In-Reply-To: <2629048.tOq3sNXcCP@ralph.baldwin.cx>
References:  <20141025184448.GA19066@dft-labs.eu> <20141025190407.GU82214@funkthat.com> <2629048.tOq3sNXcCP@ralph.baldwin.cx>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Oct 27, 2014 at 11:27:45AM -0400, John Baldwin wrote:
> Please keep the refcount_*() prefix so it matches the rest of the API.  I 
> would just declare the functions directly in refcount.h rather than requiring 
> a macro to be invoked in each C file.  We can also just implement the needed 
> lock types for now instead of all of them.
> 
> You could maybe replace 'take' with 'lock', but either name is fine.
> 


We need sx and rwlocks (and temporarily mutexes, but that is going away
in few days).

I ran into the following issue: opensolaris code has its own rwlock.h,
and their refcount.h eventually includes ours refcount.h (and it has to
since e.g. our file.h requires it).

I don't know any good solution.

We could add locking funcs to a separate header (refcount_lock.h?) or use the
following hack:

diff --git a/sys/sys/refcount.h b/sys/sys/refcount.h
index 4611664..ce35131 100644
--- a/sys/sys/refcount.h
+++ b/sys/sys/refcount.h
@@ -29,15 +29,19 @@
 #ifndef __SYS_REFCOUNT_H__
 #define __SYS_REFCOUNT_H__
 
-#include <sys/limits.h>
-#include <machine/atomic.h>
-
 #ifdef _KERNEL
+#include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/rwlock.h>
+#include <sys/sx.h>
 #else
 #define	KASSERT(exp, msg)	/* */
 #endif
 
+#include <sys/limits.h>
+#include <machine/atomic.h>
+
 static __inline void
 refcount_init(volatile u_int *count, u_int value)
 {
@@ -64,4 +68,36 @@ refcount_release(volatile u_int *count)
 	return (old == 1);
 }
 
+#ifdef _KERNEL
+
+#define	REFCOUNT_RELEASE_LOCK_DEFINE(NAME, TYPE, LOCK, UNLOCK)		\
+static __inline int							\
+refcount_release_lock_##NAME(volatile u_int *count, TYPE *v)		\
+{									\
+	u_int old;							\
+									\
+	old = *count;							\
+	if (old > 1 && atomic_cmpset_int(count, old, old - 1))		\
+		return (0);						\
+	LOCK(v);							\
+	if (refcount_release(count))					\
+		return (1);						\
+	UNLOCK(v);							\
+	return (0);							\
+}
+
+REFCOUNT_RELEASE_LOCK_DEFINE(sx, struct sx, sx_xlock, sx_xunlock);
+
+#ifdef _SYS_RWLOCK_H_
+REFCOUNT_RELEASE_LOCK_DEFINE(rwlock, struct rwlock, rw_wlock, rw_wunlock);
+#else
+/*
+ * A hack to resolve header conflict with opensolaris which provides its own
+ * rwlock.h
+ */
+#define	refcount_release_lock_rwlock CTASSERT(0, "not implemented")
+#endif /* ! _SYS_RWLOCK_H_ */
+
+#endif /* ! _KERNEL */
+
 #endif	/* ! __SYS_REFCOUNT_H__ */

-- 
Mateusz Guzik <mjguzik gmail.com>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20141027192721.GA28049>