diff --git a/include/linux/util_macros.h b/include/linux/util_macros.h new file mode 100644 index 000000000000..d5f4fb69dba3 --- /dev/null +++ b/include/linux/util_macros.h @@ -0,0 +1,40 @@ +#ifndef _LINUX_HELPER_MACROS_H_ +#define _LINUX_HELPER_MACROS_H_ + +#define __find_closest(x, a, as, op) \ +({ \ + typeof(as) __fc_i, __fc_as = (as) - 1; \ + typeof(x) __fc_x = (x); \ + typeof(*a) *__fc_a = (a); \ + for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \ + if (__fc_x op DIV_ROUND_CLOSEST(__fc_a[__fc_i] + \ + __fc_a[__fc_i + 1], 2)) \ + break; \ + } \ + (__fc_i); \ +}) + +/** + * find_closest - locate the closest element in a sorted array + * @x: The reference value. + * @a: The array in which to look for the closest element. Must be sorted + * in ascending order. + * @as: Size of 'a'. + * + * Returns the index of the element closest to 'x'. + */ +#define find_closest(x, a, as) __find_closest(x, a, as, <=) + +/** + * find_closest_descending - locate the closest element in a sorted array + * @x: The reference value. + * @a: The array in which to look for the closest element. Must be sorted + * in descending order. + * @as: Size of 'a'. + * + * Similar to find_closest() but 'a' is expected to be sorted in descending + * order. + */ +#define find_closest_descending(x, a, as) __find_closest(x, a, as, >=) + +#endif