This patch adds a function for getting a snapshot of a reference
counter. This will let code like crcopy() access the value in an
API-observing way.

OK?

Index: share/man/man9/refcnt_init.9
===================================================================
RCS file: src/share/man/man9/refcnt_init.9,v
retrieving revision 1.1
diff -u -p -r1.1 refcnt_init.9
--- share/man/man9/refcnt_init.9        11 Sep 2015 19:13:22 -0000      1.1
+++ share/man/man9/refcnt_init.9        15 Mar 2022 07:52:39 -0000
@@ -23,6 +23,7 @@
 .Nm refcnt_rele ,
 .Nm refcnt_rele_wake ,
 .Nm refcnt_finalize ,
+.Nm refcnt_read ,
 .Nm REFCNT_INITIALIZER
 .Nd reference count API
 .Sh SYNOPSIS
@@ -37,6 +38,8 @@
 .Fn "refcnt_rele_wake" "struct refcnt *r"
 .Ft void
 .Fn "refcnt_finalize" "struct refcnt *r" "const char *wmesg"
+.Ft unsigned int
+.Fn "refcnt_read" "struct refcnt *r"
 .Fn "REFCNT_INITIALIZER"
 .Sh DESCRIPTION
 The refcnt API provides simple reference counters that can be used
@@ -68,14 +71,21 @@ There may only be one caller to
 per refcnt
 .Fa r .
 .Pp
+.Fn refcnt_read
+returns a snapshot of the counter value.
+The value can become stale immediately if other CPUs are able to change
+the counter in parallel.
+The function does not enforce any memory access order.
+.Pp
 .Fn REFCNT_INITIALIZER
 initialises a declaration of a refcnt to 1.
 .Sh CONTEXT
 .Fn refcnt_init ,
 .Fn refcnt_take ,
 .Fn refcnt_rele ,
+.Fn refcnt_rele_wake ,
 and
-.Fn refcnt_rele_wake
+.Fn refcnt_read
 can be called during autoconf, from process context, or from interrupt
 context.
 .Pp
@@ -85,3 +95,6 @@ can be called from process context.
 .Fn refcnt_rele
 returns a non-zero value if the last reference has been released,
 otherwise 0.
+.Pp
+.Fn refcnt_read
+returns a snapshot of the counter value.
Index: sys/kern/kern_synch.c
===================================================================
RCS file: src/sys/kern/kern_synch.c,v
retrieving revision 1.183
diff -u -p -r1.183 kern_synch.c
--- sys/kern/kern_synch.c       10 Mar 2022 15:21:08 -0000      1.183
+++ sys/kern/kern_synch.c       15 Mar 2022 07:52:39 -0000
@@ -852,6 +852,12 @@ refcnt_finalize(struct refcnt *r, const 
        }
 }
 
+unsigned int
+refcnt_read(struct refcnt *r)
+{
+       return (atomic_load_int(&r->r_refs));
+}
+
 void
 cond_init(struct cond *c)
 {
Index: sys/sys/refcnt.h
===================================================================
RCS file: src/sys/sys/refcnt.h,v
retrieving revision 1.5
diff -u -p -r1.5 refcnt.h
--- sys/sys/refcnt.h    10 Mar 2022 15:21:08 -0000      1.5
+++ sys/sys/refcnt.h    15 Mar 2022 07:52:39 -0000
@@ -37,6 +37,7 @@ void  refcnt_take(struct refcnt *);
 int    refcnt_rele(struct refcnt *);
 void   refcnt_rele_wake(struct refcnt *);
 void   refcnt_finalize(struct refcnt *, const char *);
+unsigned int   refcnt_read(struct refcnt *);
 
 #endif /* _KERNEL */
 

Reply via email to