lib/checksum.c: optimize do_csum a bit
[linux-2.6.git] / lib / checksum.c
index 0975087..8df2f91 100644 (file)
@@ -49,7 +49,7 @@ static inline unsigned short from32to16(unsigned int x)
 
 static unsigned int do_csum(const unsigned char *buff, int len)
 {
-       int odd, count;
+       int odd;
        unsigned int result = 0;
 
        if (len <= 0)
@@ -64,25 +64,22 @@ static unsigned int do_csum(const unsigned char *buff, int len)
                len--;
                buff++;
        }
-       count = len >> 1;               /* nr of 16-bit words.. */
-       if (count) {
+       if (len >= 2) {
                if (2 & (unsigned long) buff) {
                        result += *(unsigned short *) buff;
-                       count--;
                        len -= 2;
                        buff += 2;
                }
-               count >>= 1;            /* nr of 32-bit words.. */
-               if (count) {
+               if (len >= 4) {
+                       const unsigned char *end = buff + ((unsigned)len & ~3);
                        unsigned int carry = 0;
                        do {
                                unsigned int w = *(unsigned int *) buff;
-                               count--;
                                buff += 4;
                                result += carry;
                                result += w;
                                carry = (w > result);
-                       } while (count);
+                       } while (buff < end);
                        result += carry;
                        result = (result & 0xffff) + (result >> 16);
                }