From 753a02c15661a650762495257bf3abf1167998a7 Mon Sep 17 00:00:00 2001 From: Fredrik Holmqvist Date: Sat, 24 Dec 2011 20:51:28 +0100 Subject: [PATCH] Reworked strlen and strnlen to look at four bytes at the time. From what I understand this should be safe. Based on info from bit twiddling hacks: http://graphics.stanford.edu/~seander/bithacks.html --- src/system/libroot/posix/string/strlen.c | 21 +++++++++++++--- src/system/libroot/posix/string/strnlen.c | 30 +++++++++++++++++++---- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/system/libroot/posix/string/strlen.c b/src/system/libroot/posix/string/strlen.c index 08e0d9a037..013c278796 100644 --- a/src/system/libroot/posix/string/strlen.c +++ b/src/system/libroot/posix/string/strlen.c @@ -3,18 +3,33 @@ ** Distributed under the terms of the NewOS License. */ -#include #include +#include +// From Bit twiddling hacks: http://graphics.stanford.edu/~seander/bithacks.html +#define hasZeroByte(value) (value - 0x01010101) & ~value & 0x80808080 size_t strlen(char const *s) { size_t i = 0; + uint32 *value; - while (s[i]) { - i += 1; + //Make sure we use aligned access + while (((uint32) s + i) & 3) { + if (!s[i]) return i; + i++; } + //Check four bytes at once + value = (uint32 *) (s + i); + while (!(hasZeroByte(*value))) + value++; + + //Find the exact length + i = ((char *) value) - s; + while (s[i]) + i++; + return i; } diff --git a/src/system/libroot/posix/string/strnlen.c b/src/system/libroot/posix/string/strnlen.c index 573b36527e..05a29207b8 100644 --- a/src/system/libroot/posix/string/strnlen.c +++ b/src/system/libroot/posix/string/strnlen.c @@ -3,16 +3,36 @@ ** Distributed under the terms of the NewOS License. */ -#include #include +#include +// From Bit twiddling hacks: http://graphics.stanford.edu/~seander/bithacks.html +#define hasZeroByte(value) (value - 0x01010101) & ~value & 0x80808080 + size_t strnlen(char const *s, size_t count) { - const char *sc; + size_t i = 0; + uint32 *value; - for (sc = s; count-- && *sc != '\0'; ++sc) - ; - return sc - s; + //Make sure we use aligned access + while (((uint32) s + i) & 3) { + if (i == count || !s[i]) return i; + i++; + } + + + const uint32 * end = (uint32 *) s + count; + //Check four bytes at once + value = (uint32 *) (s + i); + while (value < end && !(hasZeroByte(*value)) ) + value++; + + //Find the exact length + i = ((char *) value) - s; + while (s[i] && i < count ) + i++; + + return i; }