Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Mon,  4 Feb 2013 00:12:13 +0000
From: Nathan McSween <nwmcsween@...il.com>
To: musl@...ts.openwall.com
Cc: Nathan McSween <nwmcsween@...il.com>
Subject: [PATCH 2/4] String: refactor to utilize word.h and optimize

---
 src/string/memchr.c | 42 ++++++++++++++++++++++++------------------
 src/string/memset.c | 39 +++++++++++++++++++++++----------------
 src/string/strlen.c | 29 ++++++++++++++++-------------
 3 files changed, 63 insertions(+), 47 deletions(-)

diff --git a/src/string/memchr.c b/src/string/memchr.c
index a0472f7..559facc 100644
--- a/src/string/memchr.c
+++ b/src/string/memchr.c
@@ -1,24 +1,30 @@
-#include <string.h>
-#include <stdlib.h>
+#include <stddef.h>
 #include <stdint.h>
-#include <limits.h>
-
-#define SS (sizeof(size_t))
-#define ALIGN (sizeof(size_t)-1)
-#define ONES ((size_t)-1/UCHAR_MAX)
-#define HIGHS (ONES * (UCHAR_MAX/2+1))
-#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+#include <string.h>
+#include "word.h"
 
-void *memchr(const void *src, int c, size_t n)
+/**
+ * memchr - Word sized c standard memchr.
+ * @s: Source
+ * @c: Character
+ * @n: Max size of @s
+ */
+void *memchr(const void *s, int c, size_t n)
 {
-	const unsigned char *s = src;
+	const unsigned char *cs = (const unsigned char *)s;
+	const size_t *w;
+
 	c = (unsigned char)c;
-	for (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--);
-	if (n && *s != c) {
-		const size_t *w;
-		size_t k = ONES * c;
-		for (w = (const void *)s; n>=SS && !HASZERO(*w^k); w++, n-=SS);
-		for (s = (const void *)w; n && *s != c; s++, n--);
+
+	for (; (uintptr_t)cs % sizeof(size_t); cs++, n--) {
+		if (!n) return NULL;
+		if (*cs == c) return (void *)cs;
 	}
-	return n ? (void *)s : 0;
+
+	for (w = (const size_t *)cs; !word_has_char(*w, c); w++, n--)
+		if (!n) return NULL;
+	for (cs = (const unsigned char *)w; *cs != c; cs++, n--)
+		if (!n) return NULL;
+
+	return (void *)cs;
 }
diff --git a/src/string/memset.c b/src/string/memset.c
index 20e47c4..8c87548 100644
--- a/src/string/memset.c
+++ b/src/string/memset.c
@@ -1,21 +1,28 @@
-#include <string.h>
-#include <stdlib.h>
+#include <stddef.h>
 #include <stdint.h>
-#include <limits.h>
-
-#define SS (sizeof(size_t))
-#define ALIGN (sizeof(size_t)-1)
-#define ONES ((size_t)-1/UCHAR_MAX)
+#include <string.h>
+#include "word.h"
 
-void *memset(void *dest, int c, size_t n)
+/**
+ * memset - Word sized c standard memset.
+ * @d: Destination
+ * @c: Charater to set
+ * @n: Max size to set to @c in @d
+ */
+void *memset(void *d, int c, size_t n)
 {
-	unsigned char *s = dest;
+	unsigned char *cd = (unsigned char *)d;
+	const size_t wc = WORD_LSB_ONE * (unsigned char)c;
+	size_t *wd;
+
 	c = (unsigned char)c;
-	for (; ((uintptr_t)s & ALIGN) && n; n--) *s++ = c;
-	if (n) {
-		size_t *w, k = ONES * c;
-		for (w = (void *)s; n>=SS; n-=SS, w++) *w = k;
-		for (s = (void *)w; n; n--, s++) *s = c;
-	}
-	return dest;
+
+	for (; (uintptr_t)cd % sizeof(size_t); *cd++ = c, n--)
+		if (!n) return d;
+
+	for (wd = (size_t *)cd; n >= sizeof(size_t)
+	     ; *wd++ = wc, n -= sizeof(size_t));
+	for (cd = (unsigned char *)wd; n; *cd++ = c, n--);
+
+	return d;
 }
diff --git a/src/string/strlen.c b/src/string/strlen.c
index d6f8631..2b356f0 100644
--- a/src/string/strlen.c
+++ b/src/string/strlen.c
@@ -1,19 +1,22 @@
-#include <string.h>
-#include <stdlib.h>
+#include <stddef.h>
 #include <stdint.h>
-#include <limits.h>
-
-#define ALIGN (sizeof(size_t))
-#define ONES ((size_t)-1/UCHAR_MAX)
-#define HIGHS (ONES * (UCHAR_MAX/2+1))
-#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
+#include <string.h>
+#include "word.h"
 
+/**
+ * strlen - Word sized c standard strlen.
+ * @s: Source
+ */
 size_t strlen(const char *s)
 {
-	const char *a = s;
+	const char *z = s;
 	const size_t *w;
-	for (; (uintptr_t)s % ALIGN; s++) if (!*s) return s-a;
-	for (w = (const void *)s; !HASZERO(*w); w++);
-	for (s = (const void *)w; *s; s++);
-	return s-a;
+
+	for (; (uintptr_t)s % sizeof(size_t); s++)
+		if (!*s) return s - z;
+
+	for (w = (const size_t *)s; !word_has_zero(*w); w++);
+	for (s = (const char *)w; *s; s++);
+
+	return s - z;
 }
-- 
1.7.11.4

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.