kernel: add clamp(), clamp_t() and clamp_val() macros
PATCH 1/6 kernel: add clamp(), clamp_t() and clamp_val() macros
Adds macros similar to min/max/min_t/max_t.
Also, change the variable names used in the min/max macros to avoid shadowed variable warnings when min/max min_t/max_t are nested.
clamp_val is useful when clamping to constants so all types are taken from typeof() the first arg.
Small formatting changes to make all the macros have a similar form.
---
Andrew, this is a rollup of my original patch already in -mm with checkpatch warnings fixed up and one additional macro based on limit_value found in the b43 driver, called clamp_val.
clamp_t is no longer used, but I introduce it anyway as some future user may want to force the return type similar to how min_t/max_t operate.
include/linux/kernel.h | 66 ++++++++++++++++++++++++++++++++++------------- 1 files changed, 48 insertions(+), 18 deletions(-)
include/linux/kernel.h +48 -18
@@ -335,33 +335,63 @@ static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char *#endif /* __LITTLE_ENDIAN */ /* -* min()/max() macros that also do +* min()/max()/clamp() macros that also do * strict type-checking.. See the * "unnecessary" pointer comparison. */ -#define min (x,y) ({ \ - typeof(x) _x = (x); \ - typeof(y) _y = (y); \ - (void) (&_x == &_y); \ - _x < _y ? _x : _y; }) - -#define max (x,y) ({ \ - typeof(x) _x = (x); \ - typeof(y) _y = (y); \ - (void) (&_x == &_y); \ - _x > _y ? _x : _y; }) +#define min (x, y) ({ \ + typeof(x) _min1 = (x); \ + typeof(y) _min2 = (y); \ + (void) (&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; }) + +#define max (x, y) ({ \ + typeof(x) _max1 = (x); \ + typeof(y) _max2 = (y); \ + (void) (&_max1 == &_max2); \ + _max1 > _max2 ? _max1 : _max2; }) + +#define clamp (val, min, max) ({ \ + typeof(val) __val = (val); \ + typeof(min) __min = (min); \ + typeof(max) __max = (max); \ + (void) (&__val == &__min); \ + (void) (&__val == &__max); \ + __val = __val < __min ? __min: __val; \ + __val > __max ? __max: __val; }) + +/* +* Useful when min and max are constants. +*/ +#define clamp_val (val, min, max) ({ \ + typeof(val) __val = (val); \ + typeof(val) __min = (min); \ + typeof(val) __max = (max); \ + __val = __val < __min ? __min: __val; \ + __val > __max ? __max: __val; })/* * ..and if you can't take the strict * types, you can specify one yourself. * -* Or not use min/max at all, of course. +* Or not use min/max/clamp at all, of course. */ -#define min_t (type,x,y) \ - ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) -#define max_t (type,x,y) \ - ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) - +#define min_t (type, x, y) ({ \ + type __min1 = (x); \ + type __min2 = (y); \ + __min1 < __min2 ? __min1: __min2; }) + +#define max_t (type, x, y) ({ \ + type __max1 = (x); \ + type __max2 = (y); \ + __max1 > __max2 ? __max1: __max2; }) + +#define clamp_t (type, val, min, max) ({ \ + type __val = (val); \ + type __min = (min); \ + type __max = (max); \ + __val = __val < __min ? __min: __val; \ + __val > __max ? __max: __val; })/** * container_of - cast a member of a structure out to the containing structure
Signature · 1 line
1.5.4.4.592.g32d4c
Quoted 9 lines · On Tue, 11 Mar 2008 14:11:34 -0700 Harvey Harrison <[email protected]>…
Adds macros similar to min/max/min_t/max_t.
Also, change the variable names used in the min/max macros to avoid shadowed variable warnings when min/max min_t/max_t are nested.
clamp_valis useful when clamping to constants so all types are taken fromtypeof()the first arg.
Quoted 8 lines
Small formatting changes to make all the macros have a similar form.
Signed-off-by Harvey Harrison <[email protected]>---
Andrew, this is a rollup of my original patch already in -mm with checkpatch warnings fixed up and one additional macro based onlimit_valuefound in the b43 driver, calledclamp_val.
Well, this is why I dislike replacement patches. You don't know what changed, and the replacement patch can fail to incproporate fixes from third parties.
Quoted 2 lines
include/linux/kernel.h | 66 ++++++++++++++++++++++++++++++++++------------- 1 files changed, 48 insertions(+), 18 deletions(-)
And so it did. You lost my patch which removes the clamp() implementation from v4l. Instead it seems that you put it into [2/6]. Which means that this patch on its own will break the build, thus screwing up life for git-bisect users.
Please don't screw up git-bisect users' lives.
Quoted 3 lines
clamp_tis no longer used, but I introduce it anyway as some future user may want to force the return type similar to how min_t/max_t operate.
eh, just nuke it.
Quoted 1 line
1.5.4.4.592.g32d4c
Is all this new infrastructure actually used? We seem to be adding more complexity than we're taking away.
Quoted 64 lines · On Tuesday 11 March 2008 22:11:34 Harvey Harrison wrote:
Adds macros similar to min/max/min_t/max_t.
Also, change the variable names used in the min/max macros to avoid shadowed variable warnings when min/max min_t/max_t are nested.
clamp_valis useful when clamping to constants so all types are taken fromtypeof()the first arg.Small formatting changes to make all the macros have a similar form.
Signed-off-by Harvey Harrison <[email protected]>---
Andrew, this is a rollup of my original patch already in -mm with checkpatch warnings fixed up and one additional macro based onlimit_valuefound in the b43 driver, calledclamp_val.
clamp_tis no longer used, but I introduce it anyway as some future user may want to force the return type similar to how min_t/max_t operate.include/linux/kernel.h | 66 ++++++++++++++++++++++++++++++++++------------- 1 files changed, 48 insertions(+), 18 deletions(-)include/linux/kernel.h +16
-12@@ -335,33 +335,63 @@ static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char *#endif /* __LITTLE_ENDIAN */ /* -* min()/max() macros that also do +* min()/max()/clamp() macros that also do * strict type-checking.. See the * "unnecessary" pointer comparison. */ -#define min (x,y) ({ \ - typeof(x) _x = (x); \ - typeof(y) _y = (y); \ - (void) (&_x == &_y); \ - _x < _y ? _x : _y; }) - -#define max (x,y) ({ \ - typeof(x) _x = (x); \ - typeof(y) _y = (y); \ - (void) (&_x == &_y); \ - _x > _y ? _x : _y; }) +#define min (x, y) ({ \ + typeof(x) _min1 = (x); \ + typeof(y) _min2 = (y); \ + (void) (&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; }) + +#define max (x, y) ({ \ + typeof(x) _max1 = (x); \ + typeof(y) _max2 = (y); \ + (void) (&_max1 == &_max2); \ + _max1 > _max2 ? _max1 : _max2; }) + +#define clamp (val, min, max) ({ \ + typeof(val) __val = (val); \ + typeof(min) __min = (min); \
include/linux/kernel.h static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char * · line 366
Quoted 10 lines
include/linux/kernel.h +10
-0+typeof (max) __max = (max); \ + (void ) (&__val == &__min); \ + (void ) (&__val == &__max); \ + __val = __val < __min ? __min: __val; \ + __val > __max ? __max: __val; }) + +/* +* Useful when min and max are constants. +*/ +#define clamp_val (val, min, max) ({ \
So why not call it clamp_const()?
One could even use __builtin_constant_p() and make clamp() use either clamp_const() or clamp_nonconst() from above automagically. I'd prefer that.
Quoted 37 lines
include/linux/kernel.h +22
-6+typeof (val) __val = (val); \ +typeof (val) __min = (min); \ +typeof (val) __max = (max); \ + __val = __val < __min ? __min: __val; \ + __val > __max ? __max: __val; })/* * ..and if you can't take the strict * types, you can specify one yourself. * -* Or not use min/max at all, of course. +* Or not use min/max/clamp at all, of course. */ -#define min_t (type,x,y) \ - ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) -#define max_t (type,x,y) \ - ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) - +#define min_t (type, x, y) ({ \ + type __min1 = (x); \ + type __min2 = (y); \ + __min1 < __min2 ? __min1: __min2; }) + +#define max_t (type, x, y) ({ \ + type __max1 = (x); \ + type __max2 = (y); \ + __max1 > __max2 ? __max1: __max2; }) + +#define clamp_t (type, val, min, max) ({ \ + type __val = (val); \ + type __min = (min); \ + type __max = (max); \ + __val = __val < __min ? __min: __val; \ + __val > __max ? __max: __val; })/** * container_of - cast a member of a structure out to the containing structure
Signature · 1 line
Greetings Michael.
Quoted 4 lines · Michael Buesch
So why not call it
clamp_const()?
One could even use__builtin_constant_p()and makeclamp()use eitherclamp_const()orclamp_nonconst()from above automagically. I'd prefer that.
Did you mean something like this? No more clamp_val, just clamp and clamp_t. clamp_t forces all the types, clamp looks at the min and max args, and if they are constants, uses the type of val instead. If not a constant, the strict typechecking is done.
From: Harvey Harrison <[email protected]>
Subject: [PATCH] kernel: add clamp(), clamp_t() macros
Adds macros similar to min/max/min_t/max_t.
Also, change the variable names used in the min/max macros to avoid shadowed variable warnings when min/max min_t/max_t are nested.
Small formatting changes to make all the macros have a similar form.
--- include/linux/kernel.h | 68 +++++++++++++++++++++++++++++++++++------------ 1 files changed, 50 insertions(+), 18 deletions(-)
include/linux/kernel.h +50 -18
@@ -335,33 +335,65 @@ static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char *#endif /* __LITTLE_ENDIAN */ /* -* min()/max() macros that also do +* min()/max()/clamp() macros that also do * strict type-checking.. See the * "unnecessary" pointer comparison. */ -#define min (x,y) ({ \ - typeof(x) _x = (x); \ - typeof(y) _y = (y); \ - (void) (&_x == &_y); \ - _x < _y ? _x : _y; }) - -#define max (x,y) ({ \ - typeof(x) _x = (x); \ - typeof(y) _y = (y); \ - (void) (&_x == &_y); \ - _x > _y ? _x : _y; }) +#define min (x, y) ({ \ + typeof(x) _min1 = (x); \ + typeof(y) _min2 = (y); \ + (void) (&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; }) + +#define max (x, y) ({ \ + typeof(x) _max1 = (x); \ + typeof(y) _max2 = (y); \ + (void) (&_max1 == &_max2); \ + _max1 > _max2 ? _max1 : _max2; }) + +#define clamp (val, min, max) ({ \ + typeof(val) __val = (val); \ + \ + if (__builtin_constant_p(min)) { \ + typeof(val) __min = (min); \ + __val = __val < __min ? __min: __val; \ + } else { \ + typeof(min) __min = (min); \ + (void) (&__val == &__min); \ + __val = __val < __min ? __min: __val; \ + } \ + \ + if (__builtin_constant_p(max)) { \ + typeof(val) __max = (max); \ + __val > __max ? __max: __val; \ + } else { \ + typeof(max) __max = (max); \ + (void) (&__val == &__max); \ + __val > __max ? __max: __val; \ + } })/* * ..and if you can't take the strict * types, you can specify one yourself. * -* Or not use min/max at all, of course. +* Or not use min/max/clamp at all, of course. */ -#define min_t (type,x,y) \ - ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) -#define max_t (type,x,y) \ - ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) - +#define min_t (type, x, y) ({ \ + type __min1 = (x); \ + type __min2 = (y); \ + __min1 < __min2 ? __min1: __min2; }) + +#define max_t (type, x, y) ({ \ + type __max1 = (x); \ + type __max2 = (y); \ + __max1 > __max2 ? __max1: __max2; }) + +#define clamp_t (type, val, min, max) ({ \ + type __val = (val); \ + type __min = (min); \ + type __max = (max); \ + __val = __val < __min ? __min: __val; \ + __val > __max ? __max: __val; })/** * container_of - cast a member of a structure out to the containing structure
Signature · 1 line
1.5.4.4.592.g32d4c
Quoted 21 lines · On Wednesday 12 March 2008 17:54:26 Harvey Harrison wrote:
Quoted 4 lines · Michael Buesch
So why not call it
clamp_const()?
One could even use__builtin_constant_p()and makeclamp()use eitherclamp_const()orclamp_nonconst()from above automagically. I'd prefer that.Did you mean something like this? No more
clamp_val, just clamp andclamp_t.clamp_tforces all the types, clamp looks at the min and max args, and if they are constants, uses the type of val instead. If not a constant, the strict typechecking is done.include/linux/kernel.h +10
-0+#define clamp (val, min, max) ({ \ + typeof(val) __val = (val); \ + \ + if (__builtin_constant_p(min)) { \ + typeof(val) __min = (min); \ + __val = __val < __min ? __min: __val; \ + } else { \ + typeof(min) __min = (min); \ + (void) (&__val == &__min); \ + __val = __val < __min ? __min: __val; \
include/linux/kernel.h static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char * · line 373
Quoted 10 lines
include/linux/kernel.h +10
-0+ } \ + \ +if (__builtin_constant_p (max)) { \ +typeof (val) __max = (max); \ + __val > __max ? __max: __val; \ + }else { \ +typeof (max) __max = (max); \ + (void ) (&__val == &__max); \ + __val > __max ? __max: __val; \ + } })
Yeah, something like that.
Does returning of the value work over an indentation level, too? I dunno this detail of the language.
But I'd prefer the following for readability anyway:
+ if (__builtin_constant_p(max)) { \
+ typeof(val) __max = (max); \
+ __val = __val > __max ? __max: __val; \
+ } else { \
+ typeof(max) __max = (max); \
+ (void) (&__val == &__max); \+ __val = __val > __max ? __max: __val; \
+ }
+ __val; })
Probably you can also only put the pointer check into the constant check:
+#define clamp(val, min, max) ({ \
+ typeof(val) __val = (val); \
+ typeof(min) __min = (min); \
+ typeof(max) __max = (max); \
+ if (!__builtin_constant_p(min)) \
+ (void) (&__val == &__min); \
+ __val = __val < __min ? __min: __val; \
+ if (!__builtin_constant_p(max)) \
+ (void) (&__val == &__max); \
+ __val = __val > __max ? __max: __val; \+ __val; })
But it seems that this evaluates the arguments twice, so my idea turns out to be not too good anyway. hm..
Signature · 1 line
Greetings Michael.
Quoted 38 lines · Michael Buesch
Quoted 21 lines · On Wednesday 12 March 2008 17:54:26 Harvey Harrison wrote:
Quoted 4 lines · Michael Buesch
So why not call it
clamp_const()?
One could even use__builtin_constant_p()and makeclamp()use eitherclamp_const()orclamp_nonconst()from above automagically. I'd prefer that.Did you mean something like this? No more
clamp_val, just clamp andclamp_t.clamp_tforces all the types, clamp looks at the min and max args, and if they are constants, uses the type of val instead. If not a constant, the strict typechecking is done.include/linux/kernel.h +10
-0+#define clamp (val, min, max) ({ \ + typeof(val) __val = (val); \ + \ + if (__builtin_constant_p(min)) { \ + typeof(val) __min = (min); \ + __val = __val < __min ? __min: __val; \ + } else { \ + typeof(min) __min = (min); \ + (void) (&__val == &__min); \ + __val = __val < __min ? __min: __val; \include/linux/kernel.h static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char * · line 373
Quoted 10 lines
include/linux/kernel.h +10
-0+ } \ + \ +if (__builtin_constant_p (max)) { \ +typeof (val) __max = (max); \ + __val > __max ? __max: __val; \ + }else { \ +typeof (max) __max = (max); \ + (void ) (&__val == &__max); \ + __val > __max ? __max: __val; \ + } })Yeah, something like that.
Does returning of the value work over an indentation level, too? I dunno this detail of the language.
But I'd prefer the following for readability anyway:
include/linux/kernel.h static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char *
Quoted 9 lines
include/linux/kernel.h +9
-0+if (__builtin_constant_p (max)) { \ +typeof (val) __max = (max); \ + __val = __val > __max ? __max: __val; \ + }else { \ +typeof (max) __max = (max); \ + (void ) (&__val == &__max); \ + __val = __val > __max ? __max: __val; \ + } + __val; })
Yeah, that is better. (and even works).
Harvey