Explorar o código

lib: Add strongly typed 64bit int_sqrt

There is no option to perform 64bit integer sqrt on 32bit platform.
Added stronger typed int_sqrt64 enables the 64bit calculations to
be performed on 32bit platforms. Using same algorithm as int_sqrt()
with strong typing provides enough precision also on 32bit platforms,
but it sacrifices some performance. In case values are smaller than
ULONG_MAX the standard int_sqrt is used for calculation to maximize the
performance due to more native calculations.

Signed-off-by: Crt Mori <cmo@melexis.com>
Acked-by: Joe Perches <joe@perches.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Crt Mori %!s(int64=7) %!d(string=hai) anos
pai
achega
47a3616348
Modificáronse 2 ficheiros con 39 adicións e 0 borrados
  1. 9 0
      include/linux/kernel.h
  2. 30 0
      lib/int_sqrt.c

+ 9 - 0
include/linux/kernel.h

@@ -479,6 +479,15 @@ extern int func_ptr_is_kernel_text(void *ptr);
 
 
 unsigned long int_sqrt(unsigned long);
 unsigned long int_sqrt(unsigned long);
 
 
+#if BITS_PER_LONG < 64
+u32 int_sqrt64(u64 x);
+#else
+static inline u32 int_sqrt64(u64 x)
+{
+	return (u32)int_sqrt(x);
+}
+#endif
+
 extern void bust_spinlocks(int yes);
 extern void bust_spinlocks(int yes);
 extern int oops_in_progress;		/* If set, an oops, panic(), BUG() or die() is in progress */
 extern int oops_in_progress;		/* If set, an oops, panic(), BUG() or die() is in progress */
 extern int panic_timeout;
 extern int panic_timeout;

+ 30 - 0
lib/int_sqrt.c

@@ -38,3 +38,33 @@ unsigned long int_sqrt(unsigned long x)
 	return y;
 	return y;
 }
 }
 EXPORT_SYMBOL(int_sqrt);
 EXPORT_SYMBOL(int_sqrt);
+
+#if BITS_PER_LONG < 64
+/**
+ * int_sqrt64 - strongly typed int_sqrt function when minimum 64 bit input
+ * is expected.
+ * @x: 64bit integer of which to calculate the sqrt
+ */
+u32 int_sqrt64(u64 x)
+{
+	u64 b, m, y = 0;
+
+	if (x <= ULONG_MAX)
+		return int_sqrt((unsigned long) x);
+
+	m = 1ULL << (fls64(x) & ~1ULL);
+	while (m != 0) {
+		b = y + m;
+		y >>= 1;
+
+		if (x >= b) {
+			x -= b;
+			y += m;
+		}
+		m >>= 2;
+	}
+
+	return y;
+}
+EXPORT_SYMBOL(int_sqrt64);
+#endif