]> git.hungrycats.org Git - linux/commitdiff
[PATCH] sqrt() fixes
authorAndrew Morton <akpm@osdl.org>
Mon, 29 Dec 2003 13:42:51 +0000 (05:42 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Mon, 29 Dec 2003 13:42:51 +0000 (05:42 -0800)
It turns out that the int_sqrt() function in oom_kill.c gets it wrong.

But fb_sqrt() in fbmon.c gets its math right.  Move that function into
lib/int_sqrt.c, and consolidate.

(oom_kill.c fix from Thomas Schlichter <schlicht@uni-mannheim.de>)

drivers/video/fbmon.c
include/linux/kernel.h
lib/Makefile
lib/int_sqrt.c [new file with mode: 0644]
mm/oom_kill.c

index 59533c4897febf6adc41fc7854584852faba0958..bf839fd543034d51e40fcd1d4388884076224bff 100644 (file)
@@ -890,30 +890,6 @@ struct __fb_timings {
        u32 vtotal;
 };
 
-/*
- * a simple function to get the square root of integers 
- */
-static u32 fb_sqrt(int x)
-{
-       register int op, res, one;
-
-       op = x;
-       res = 0;
-
-       one = 1 << 30;
-       while (one > op) one >>= 2;
-
-       while (one != 0) {
-               if (op >= res + one) {
-                       op = op - (res + one);
-                       res = res +  2 * one;
-               }
-               res /= 2;
-               one /= 4;
-       }
-       return((u32) res);
-}
-
 /**
  * fb_get_vblank - get vertical blank time
  * @hfreq: horizontal freq
@@ -1002,7 +978,7 @@ static u32 fb_get_hblank_by_dclk(u32 dclk, u32 xres)
        h_period += (M_VAL * xres * 2 * 1000)/(5 * dclk);
        h_period *=10000; 
 
-       h_period = fb_sqrt((int) h_period);
+       h_period = int_sqrt(h_period);
        h_period -= (100 - C_VAL) * 100;
        h_period *= 1000; 
        h_period /= 2 * M_VAL;
index 6d4cb2db44dbc40a2573525375cb86170e1ae641..74af714ff9469b3ca98b4dd09bd645529bd3c88d 100644 (file)
@@ -87,6 +87,8 @@ extern int session_of_pgrp(int pgrp);
 asmlinkage int printk(const char * fmt, ...)
        __attribute__ ((format (printf, 1, 2)));
 
+unsigned long int_sqrt(unsigned long);
+
 static inline void console_silent(void)
 {
        console_loglevel = 0;
index 3bc9013c4b97388341176d75feb7abe6f03606f0..2fd41ecbb127d2cb0500c3a2c136f8331cea29c5 100644 (file)
@@ -5,7 +5,7 @@
 
 lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
         bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
-        kobject.o idr.o div64.o parser.o
+        kobject.o idr.o div64.o parser.o int_sqrt.o
 
 lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
 lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
diff --git a/lib/int_sqrt.c b/lib/int_sqrt.c
new file mode 100644 (file)
index 0000000..a5d2cdc
--- /dev/null
@@ -0,0 +1,32 @@
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+/**
+ * int_sqrt - rough approximation to sqrt
+ * @x: integer of which to calculate the sqrt
+ *
+ * A very rough approximation to the sqrt() function.
+ */
+unsigned long int_sqrt(unsigned long x)
+{
+       unsigned long op, res, one;
+
+       op = x;
+       res = 0;
+
+       one = 1 << 30;
+       while (one > op)
+               one >>= 2;
+
+       while (one != 0) {
+               if (op >= res + one) {
+                       op = op - (res + one);
+                       res = res +  2 * one;
+               }
+               res /= 2;
+               one /= 4;
+       }
+       return res;
+}
+EXPORT_SYMBOL(int_sqrt);
index 34ac8e140479349ce638dca592c144bb1351d211..ed0cee4e6c80a09efd3fc9f5d0e7bb05287fa992 100644 (file)
 
 /* #define DEBUG */
 
-/**
- * int_sqrt - oom_kill.c internal function, rough approximation to sqrt
- * @x: integer of which to calculate the sqrt
- * 
- * A very rough approximation to the sqrt() function.
- */
-static unsigned int int_sqrt(unsigned int x)
-{
-       unsigned int out = x;
-       while (x & ~(unsigned int)1) x >>=2, out >>=1;
-       if (x) out -= out >> 2;
-       return (out ? out : 1);
-}      
-
 /**
  * oom_badness - calculate a numeric value for how bad this task has been
  * @p: task struct of which task we should calculate
@@ -57,7 +43,7 @@ static unsigned int int_sqrt(unsigned int x)
 
 static int badness(struct task_struct *p)
 {
-       int points, cpu_time, run_time;
+       int points, cpu_time, run_time, s;
 
        if (!p->mm)
                return 0;
@@ -77,8 +63,12 @@ static int badness(struct task_struct *p)
        cpu_time = (p->utime + p->stime) >> (SHIFT_HZ + 3);
        run_time = (get_jiffies_64() - p->start_time) >> (SHIFT_HZ + 10);
 
-       points /= int_sqrt(cpu_time);
-       points /= int_sqrt(int_sqrt(run_time));
+       s = int_sqrt(cpu_time);
+       if (s)
+               points /= s;
+       s = int_sqrt(int_sqrt(run_time));
+       if (s)
+               points /= s;
 
        /*
         * Niced processes are most likely less important, so double