svn commit: r363516 - head/sys/sys

Mateusz Guzik mjg at FreeBSD.org
Sat Jul 25 10:29:49 UTC 2020


Author: mjg
Date: Sat Jul 25 10:29:48 2020
New Revision: 363516
URL: https://svnweb.freebsd.org/changeset/base/363516

Log:
  seqc: add a sleepable variant and convert some routines to macros
  
  This temporarily duplicates some code.
  
  Macro conversion convinces clang to carry predicts into consumers.

Added:
  head/sys/sys/_seqc.h   (contents, props changed)
Modified:
  head/sys/sys/seqc.h

Added: head/sys/sys/_seqc.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/sys/_seqc.h	Sat Jul 25 10:29:48 2020	(r363516)
@@ -0,0 +1,11 @@
+/*-
+ * This file is in the public domain.
+ */
+/* $FreeBSD$ */
+
+#ifndef _SYS__SEQC_H_
+#define _SYS__SEQC_H_
+
+typedef uint32_t seqc_t;
+
+#endif /* _SYS__SEQC_H */

Modified: head/sys/sys/seqc.h
==============================================================================
--- head/sys/sys/seqc.h	Sat Jul 25 09:28:38 2020	(r363515)
+++ head/sys/sys/seqc.h	Sat Jul 25 10:29:48 2020	(r363516)
@@ -36,7 +36,7 @@
 /*
  * seqc_t may be included in structs visible to userspace
  */
-typedef uint32_t seqc_t;
+#include <sys/_seqc.h>
 
 #ifdef _KERNEL
 
@@ -45,13 +45,15 @@ typedef uint32_t seqc_t;
 
 #include <machine/cpu.h>
 
-static __inline bool
-seqc_in_modify(seqc_t seqcp)
-{
+/*
+ * Predicts from inline functions are not honored by clang.
+ */
+#define seqc_in_modify(seqc)	({			\
+	seqc_t __seqc = (seqc);				\
+							\
+	__predict_false(__seqc & 1);			\
+})
 
-	return (seqcp & 1);
-}
-
 static __inline void
 seqc_write_begin(seqc_t *seqcp)
 {
@@ -86,7 +88,7 @@ seqc_read(const seqc_t *seqcp)
 
 	for (;;) {
 		ret = seqc_read_any(seqcp);
-		if (__predict_false(seqc_in_modify(ret))) {
+		if (seqc_in_modify(ret)) {
 			cpu_spinwait();
 			continue;
 		}
@@ -96,19 +98,38 @@ seqc_read(const seqc_t *seqcp)
 	return (ret);
 }
 
-static __inline bool
-seqc_consistent_nomb(const seqc_t *seqcp, seqc_t oldseqc)
+#define seqc_consistent_nomb(seqcp, oldseqc)	({	\
+	const seqc_t *__seqcp = (seqcp);		\
+	seqc_t __oldseqc = (oldseqc);			\
+							\
+	MPASS(!(seqc_in_modify(__oldseqc)));		\
+	__predict_true(*__seqcp == __oldseqc);		\
+})
+
+#define seqc_consistent(seqcp, oldseqc)		({	\
+	atomic_thread_fence_acq();			\
+	seqc_consistent_nomb(seqcp, oldseqc);		\
+})
+
+/*
+ * Variant which does not critical enter/exit.
+ */
+static __inline void
+seqc_sleepable_write_begin(seqc_t *seqcp)
 {
 
-	return (*seqcp == oldseqc);
+	MPASS(!seqc_in_modify(*seqcp));
+	*seqcp += 1;
+	atomic_thread_fence_rel();
 }
 
-static __inline bool
-seqc_consistent(const seqc_t *seqcp, seqc_t oldseqc)
+static __inline void
+seqc_sleepable_write_end(seqc_t *seqcp)
 {
 
-	atomic_thread_fence_acq();
-	return (seqc_consistent_nomb(seqcp, oldseqc));
+	atomic_thread_fence_rel();
+	*seqcp += 1;
+	MPASS(!seqc_in_modify(*seqcp));
 }
 
 #endif	/* _KERNEL */


More information about the svn-src-head mailing list