[PATCH 4/8] string: introduce memchr_inv

Sascha Hauer s.hauer at pengutronix.de
Mon Jul 22 06:04:06 EDT 2013


Directly taken from Linux Kernel.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 include/linux/string.h |  2 ++
 lib/string.c           | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)

diff --git a/include/linux/string.h b/include/linux/string.h
index 658264c..5df8c50 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -106,6 +106,8 @@ extern char * skip_spaces(const char *);
 
 extern char *strim(char *);
 
+void *memchr_inv(const void *start, int c, size_t bytes);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/string.c b/lib/string.c
index f544b23..eeec137 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -666,3 +666,62 @@ char *strim(char *s)
 	return s;
 }
 EXPORT_SYMBOL(strim);
+
+static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
+{
+	while (bytes) {
+		if (*start != value)
+			return (void *)start;
+		start++;
+		bytes--;
+	}
+	return NULL;
+}
+
+/**
+ * memchr_inv - Find an unmatching character in an area of memory.
+ * @start: The memory area
+ * @c: Find a character other than c
+ * @bytes: The size of the area.
+ *
+ * returns the address of the first character other than @c, or %NULL
+ * if the whole buffer contains just @c.
+ */
+void *memchr_inv(const void *start, int c, size_t bytes)
+{
+	u8 value = c;
+	u64 value64;
+	unsigned int words, prefix;
+
+	if (bytes <= 16)
+		return check_bytes8(start, value, bytes);
+
+	value64 = value;
+	value64 |= value64 << 8;
+	value64 |= value64 << 16;
+	value64 |= value64 << 32;
+
+	prefix = (unsigned long)start % 8;
+	if (prefix) {
+		u8 *r;
+
+		prefix = 8 - prefix;
+		r = check_bytes8(start, value, prefix);
+		if (r)
+			return r;
+		start += prefix;
+		bytes -= prefix;
+	}
+
+	words = bytes / 8;
+
+	while (words) {
+		if (*(u64 *)start != value64)
+			return check_bytes8(start, value, 8);
+		start += 8;
+		words--;
+	}
+
+	return check_bytes8(start, value, bytes % 8);
+}
+EXPORT_SYMBOL(memchr_inv);
-- 
1.8.3.2




More information about the barebox mailing list