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