Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107987611
D27056.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D27056.diff
View Options
Index: head/share/man/man9/refcount.9
===================================================================
--- head/share/man/man9/refcount.9
+++ head/share/man/man9/refcount.9
@@ -32,7 +32,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 23, 2019
+.Dd November 2, 2020
.Dt REFCOUNT 9
.Os
.Sh NAME
@@ -46,6 +46,8 @@
.In sys/refcount.h
.Ft void
.Fn refcount_init "volatile u_int *count" "u_int value"
+.Ft u_int
+.Fn refcount_load "volatile u_int *count"
.Ft void
.Fn refcount_acquire "volatile u_int *count"
.Ft bool
@@ -55,6 +57,8 @@
.Ft bool
.Fn refcount_release "volatile u_int *count"
.Ft bool
+.Fn refcount_release_if_last "volatile u_int *count"
+.Ft bool
.Fn refcount_release_if_not_last "volatile u_int *count"
.Sh DESCRIPTION
The
@@ -75,6 +79,16 @@
It is normally used when creating a reference-counted object.
.Pp
The
+.Fn refcount_load
+function returns a snapshot of the counter value.
+This value may immediately become out-of-date in the absence of external
+synchronization.
+.Fn refcount_load
+should be used instead of relying on the properties of the
+.Vt volatile
+qualifier.
+.Pp
+The
.Fn refcount_acquire
function is used to acquire a new reference.
The caller is responsible for ensuring that it holds a valid reference
@@ -119,16 +133,33 @@
otherwise, it returns false.
.Pp
The
+.Fn refcount_release_if_last
+and
.Fn refcount_release_if_not_last
-is a variant of
+functions are variants of
.Fn refcount_release
-which only drops the reference when it is not the last reference.
-In other words, the function returns
+which only drop the reference when it is or is not the last reference,
+respectively.
+In other words,
+.Fn refcount_release_if_last
+returns
.Dv true
when
.Fa *count
+is equal to one, in which case it is decremented to zero.
+Otherwise,
+.Fa *count
+is not modified and the function returns
+.Dv false .
+Similarly,
+.Fn refcount_release_if_not_last
+returns
+.Dv true
+when
+.Fa *count
is greater than one, in which case
-.Fa *count is decremented.
+.Fa *count
+is decremented.
Otherwise, if
.Fa *count
is equal to one, the reference is not released and the function returns
Index: head/sys/sys/refcount.h
===================================================================
--- head/sys/sys/refcount.h
+++ head/sys/sys/refcount.h
@@ -67,6 +67,12 @@
}
static __inline u_int
+refcount_load(volatile u_int *count)
+{
+ return (atomic_load_int(count));
+}
+
+static __inline u_int
refcount_acquire(volatile u_int *count)
{
u_int old;
@@ -168,32 +174,50 @@
return (refcount_releasen(count, 1));
}
+#define _refcount_release_if_cond(cond, name) \
+static __inline __result_use_check bool \
+_refcount_release_if_##name(volatile u_int *count, u_int n) \
+{ \
+ u_int old; \
+ \
+ KASSERT(n > 0, ("%s: zero increment", __func__)); \
+ old = atomic_load_int(count); \
+ for (;;) { \
+ if (!(cond)) \
+ return (false); \
+ if (__predict_false(REFCOUNT_SATURATED(old))) \
+ return (false); \
+ if (atomic_fcmpset_rel_int(count, &old, old - 1)) \
+ return (true); \
+ } \
+}
+_refcount_release_if_cond(old > n, gt)
+_refcount_release_if_cond(old == n, eq)
+
static __inline __result_use_check bool
refcount_release_if_gt(volatile u_int *count, u_int n)
{
- u_int old;
- KASSERT(n > 0,
- ("refcount_release_if_gt: Use refcount_release for final ref"));
- old = atomic_load_int(count);
- for (;;) {
- if (old <= n)
- return (false);
- if (__predict_false(REFCOUNT_SATURATED(old)))
- return (true);
- /*
- * Paired with acquire fence in refcount_releasen().
- */
- if (atomic_fcmpset_rel_int(count, &old, old - 1))
- return (true);
+ return (_refcount_release_if_gt(count, n));
+}
+
+static __inline __result_use_check bool
+refcount_release_if_last(volatile u_int *count)
+{
+
+ if (_refcount_release_if_eq(count, 1)) {
+ /* See the comment in refcount_releasen(). */
+ atomic_thread_fence_acq();
+ return (true);
}
+ return (false);
}
static __inline __result_use_check bool
refcount_release_if_not_last(volatile u_int *count)
{
- return (refcount_release_if_gt(count, 1));
+ return (_refcount_release_if_gt(count, 1));
}
#endif /* !__SYS_REFCOUNT_H__ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 21, 6:02 AM (12 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16001298
Default Alt Text
D27056.diff (4 KB)
Attached To
Mode
D27056: refcount(9): Add refcount_release_if_last() and refcount_load()
Attached
Detach File
Event Timeline
Log In to Comment