Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1595520

[PATCH 4/5] Add memfill()

From Matthew Wilcox <willy@infradead.org>
Newsgroups linux.kernel
Subject [PATCH 4/5] Add memfill()
Date 2017-03-08 22:10 +0100
Message-ID <tiR0l-3EK-11@gated-at.bofh.it> (permalink)
References <tiR0l-3EK-9@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


From: Matthew Wilcox <mawilcox@microsoft.com>

Similar to Lars Wirzenius' memfill(), this version has optimisations for
source sizes of 1, 2, 4 (and 8 on 64 bit architectures).

Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
---
 include/linux/string.h |  3 +++
 lib/string.c           | 41 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/include/linux/string.h b/include/linux/string.h
index 642a82290a25..f340e6fb309f 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -112,6 +112,9 @@ static inline void *memset_l(unsigned long *p, unsigned long v,
 #endif
 }
 #endif
+#ifndef __HAVE_ARCH_MEMFILL
+extern void memfill(void *, __kernel_size_t, void *, __kernel_size_t);
+#endif
 #ifndef __HAVE_ARCH_MEMCPY
 extern void * memcpy(void *,const void *,__kernel_size_t);
 #endif
diff --git a/lib/string.c b/lib/string.c
index 85628c8d3abd..d22711e6490a 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -741,6 +741,47 @@ EXPORT_SYMBOL(memset64);
 #endif
 #endif
 
+#ifndef __HAVE_ARCH_MEMFILL
+/**
+ * memfill() - Fill a region of memory with copies of another region
+ * @dst: Destination address
+ * @dsz: Size of destination area
+ * @src: Source address
+ * @ssz: Size of source area
+ */
+void memfill(void *dst, size_t dsz, void *src, size_t ssz)
+{
+	if (ssz == 1) {
+		memset(dst, *(unsigned char *)src, dsz);
+		return;
+	} else if (ssz == sizeof(short)) {
+		uint32_t v = *(unsigned short *)src;
+		v |= (v << 16);
+
+		memset32(dst, v, dsz / sizeof(uint32_t));
+		dst = (uint32_t *)dst + dsz / sizeof(uint32_t);
+		dsz %= sizeof(uint32_t);
+	} else if (ssz == sizeof(int)) {
+		memset32(dst, *(uint32_t *)src, dsz / sizeof(uint32_t));
+		dst = (uint32_t *)dst + dsz / sizeof(uint32_t);
+		dsz %= sizeof(int);
+	} else if (ssz == sizeof(long)) {
+		memset_l(dst, *(long *)src, dsz / sizeof(long));
+		dst = (long *)dst + dsz / sizeof(long);
+		dsz %= sizeof(long);
+	} else {
+		while (dsz >= ssz) {
+			memcpy(dst, src, ssz);
+			dsz -= ssz;
+			dst += ssz;
+		}
+	}
+	if (dsz)
+		memcpy(dst, src, dsz);
+}
+EXPORT_SYMBOL(memfill);
+#endif
+
 #ifndef __HAVE_ARCH_MEMCPY
 /**
  * memcpy - Copy one area of memory to another
-- 
2.11.0

Back to linux.kernel | Previous | Next | Find similar | Unroll thread


Thread

[PATCH 4/5] Add memfill() Matthew Wilcox <willy@infradead.org> - 2017-03-08 22:10 +0100

csiph-web