public inbox for linux-wireless@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC v2] average: rewrite for clearity
@ 2023-04-21 13:46 Benjamin Beichler
  2023-04-21 14:37 ` Johannes Berg
  0 siblings, 1 reply; 5+ messages in thread
From: Benjamin Beichler @ 2023-04-21 13:46 UTC (permalink / raw)
  To: nbd, johannes, linux-wireless; +Cc: Benjamin Beichler

Move the former *_add function with its implicit initialization into a
separate function, when the user explicitly wants to init with the first
added value, although this creates issues, when 0 is a expected value for
the internal value.

Add a separate init function with value parameter to allow init with
distinct value, which was formerly done by the implicit init of old
*_add function.

Move the compile time checks into a separate macro, as they are used
multiple times and noise up the functions.

Signed-off-by: Benjamin Beichler <benjamin.beichler@uni-rostock.de>
---
 include/linux/average.h | 86 ++++++++++++++++++++++++-----------------
 1 file changed, 50 insertions(+), 36 deletions(-)

diff --git a/include/linux/average.h b/include/linux/average.h
index a1a8f09631ce..7149a9ee555a 100644
--- a/include/linux/average.h
+++ b/include/linux/average.h
@@ -25,47 +25,61 @@
  * that this parameter must be a power of two for efficiency.
  */
 
-#define DECLARE_EWMA(name, _precision, _weight_rcp)			\
-	struct ewma_##name {						\
-		unsigned long internal;					\
-	};								\
-	static inline void ewma_##name##_init(struct ewma_##name *e)	\
-	{								\
+#define EWMA_BUILD_TIME_CHECKS(_precision, _weight_rcp)			\
+	do {								\
 		BUILD_BUG_ON(!__builtin_constant_p(_precision));	\
 		BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp));	\
-		/*							\
-		 * Even if you want to feed it just 0/1 you should have	\
-		 * some bits for the non-fractional part...		\
-		 */							\
-		BUILD_BUG_ON((_precision) > 30);			\
-		BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp);		\
-		e->internal = 0;					\
-	}								\
-	static inline unsigned long					\
-	ewma_##name##_read(struct ewma_##name *e)			\
-	{								\
-		BUILD_BUG_ON(!__builtin_constant_p(_precision));	\
-		BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp));	\
-		BUILD_BUG_ON((_precision) > 30);			\
-		BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp);		\
-		return e->internal >> (_precision);			\
-	}								\
-	static inline void ewma_##name##_add(struct ewma_##name *e,	\
-					     unsigned long val)		\
-	{								\
-		unsigned long internal = READ_ONCE(e->internal);	\
-		unsigned long weight_rcp = ilog2(_weight_rcp);		\
-		unsigned long precision = _precision;			\
 									\
-		BUILD_BUG_ON(!__builtin_constant_p(_precision));	\
-		BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp));	\
 		BUILD_BUG_ON((_precision) > 30);			\
 		BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp);		\
-									\
-		WRITE_ONCE(e->internal, internal ?			\
-			(((internal << weight_rcp) - internal) +	\
-				(val << precision)) >> weight_rcp :	\
-			(val << precision));				\
+	} while (0)
+
+#define DECLARE_EWMA(name, _precision, _weight_rcp)				\
+	struct ewma_##name {							\
+		unsigned long internal;						\
+	};									\
+	static inline void ewma_##name##_init_val(struct ewma_##name *e,	\
+						  unsigned long init)		\
+	{									\
+		EWMA_BUILD_TIME_CHECKS(_precision, _weight_rcp)			\
+		e->internal = init << _precision;				\
+	}									\
+	static inline void ewma_##name##_init(struct ewma_##name *e)		\
+	{									\
+			ewma_##name##_init_val(e, 0);				\
+	}									\
+	static inline unsigned long						\
+	ewma_##name##_read(struct ewma_##name *e)				\
+	{									\
+		EWMA_BUILD_TIME_CHECKS(_precision, _weight_rcp)			\
+		return e->internal >> (_precision);				\
+	}									\
+	static inline void ewma_##name##_add(struct ewma_##name *e,		\
+					     unsigned long val)			\
+	{									\
+		unsigned long internal = READ_ONCE(e->internal);		\
+		unsigned long weight_rcp = ilog2(_weight_rcp);			\
+		unsigned long precision = _precision;				\
+										\
+		EWMA_BUILD_TIME_CHECKS(_precision, _weight_rcp)			\
+										\
+		WRITE_ONCE(e->internal,						\
+			(((internal << weight_rcp) - internal) +		\
+				(val << precision)) >> weight_rcp);		\
+	}									\
+	static inline void ewma_##name##_add_or_init(struct ewma_##name *e,	\
+					     unsigned long val)			\
+	{									\
+		unsigned long internal = READ_ONCE(e->internal);		\
+		unsigned long weight_rcp = ilog2(_weight_rcp);			\
+		unsigned long precision = _precision;				\
+										\
+		EWMA_BUILD_TIME_CHECKS(_precision, _weight_rcp)			\
+										\
+		WRITE_ONCE(e->internal, internal ?				\
+			(((internal << weight_rcp) - internal) +		\
+				(val << precision)) >> weight_rcp :		\
+			(val << precision));					\
 	}
 
 #endif /* _LINUX_AVERAGE_H */
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-04-24 21:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-21 13:46 [RFC v2] average: rewrite for clearity Benjamin Beichler
2023-04-21 14:37 ` Johannes Berg
2023-04-21 15:16   ` Benjamin Beichler
2023-04-24 15:55     ` Johannes Berg
2023-04-24 21:32       ` Benjamin Beichler

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox