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


Groups > linux.kernel > #1595520 > unrolled thread

[PATCH 4/5] Add memfill()

Started byMatthew Wilcox <willy@infradead.org>
First post2017-03-08 22:10 +0100
Last post2017-03-08 22:10 +0100
Articles 1 — 1 participant

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

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

#1595520 — [PATCH 4/5] Add memfill()

FromMatthew Wilcox <willy@infradead.org>
Date2017-03-08 22:10 +0100
Subject[PATCH 4/5] Add memfill()
Message-ID<tiR0l-3EK-11@gated-at.bofh.it>
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

[toc] | [standalone]


Back to top | Article view | linux.kernel


csiph-web