refcount_release_take_##lock

Mateusz Guzik mjguzik at gmail.com
Mon Oct 27 19:27:27 UTC 2014


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>


More information about the freebsd-arch mailing list