Messages in this thread Patch in this message | | | From | Matthew Wilcox <> | Subject | [PATCH 1/5] Add memset_l(), memset32() and memset64() | Date | Wed, 8 Mar 2017 12:24:02 -0800 |
| |
From: Matthew Wilcox <mawilcox@microsoft.com>
memset_l() is like memset() but allows the user to fill the destination with a pattern which fits in an unsigned long. memset32() and memset64() are 32-bit and 64-bit variants of this; memset_l() will call the appropriate one. memset32() is also useful by itself, while I am not currently aware of any user who would benefit from memset64() on 32-bit.
Architecture maintainers should be able to write optimised versions of these quite easily as it would share a lot with the core of an optimised memset().
Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com> --- include/linux/string.h | 13 +++++++++++++ lib/string.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+)
diff --git a/include/linux/string.h b/include/linux/string.h index 26b6f6a66f83..642a82290a25 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -99,6 +99,19 @@ extern __kernel_size_t strcspn(const char *,const char *); #ifndef __HAVE_ARCH_MEMSET extern void * memset(void *,int,__kernel_size_t); #endif +#ifndef __HAVE_ARCH_MEMSET_PLUS +extern void *memset32(uint32_t *, uint32_t, __kernel_size_t); +extern void *memset64(uint64_t *, uint64_t, __kernel_size_t); +static inline void *memset_l(unsigned long *p, unsigned long v, + __kernel_size_t n) +{ +#if BITS_PER_LONG == 32 + return memset32((uint32_t *)p, v, n); +#else + return memset64((uint64_t *)p, v, n); +#endif +} +#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 ed83562a53ae..85628c8d3abd 100644 --- a/lib/string.c +++ b/lib/string.c @@ -697,6 +697,50 @@ void memzero_explicit(void *s, size_t count) } EXPORT_SYMBOL(memzero_explicit); +#ifndef __HAVE_ARCH_MEMSET_PLUS +/** + * memset32() - Fill a memory area with a uint32_t + * @s: Pointer to the start of the area. + * @v: The value to fill the area with + * @count: The number of values to store + * + * Differs from memset() in that it fills with a uint32_t instead + * of a byte. Remember that @count is the number of uint32_ts to + * store, not the number of bytes. + */ +void *memset32(uint32_t *s, uint32_t v, size_t count) +{ + uint32_t *xs = s; + + while (count--) + *xs++ = v; + return s; +} +EXPORT_SYMBOL(memset32); + +#if BITS_PER_LONG > 32 +/** + * memset64() - Fill a memory area with a uint64_t + * @s: Pointer to the start of the area. + * @v: The value to fill the area with + * @count: The number of values to store + * + * Differs from memset() in that it fills with a uint64_t instead + * of a byte. Remember that @count is the number of uint64_ts to + * store, not the number of bytes. + */ +void *memset64(uint64_t *s, uint64_t v, size_t count) +{ + uint64_t *xs = s; + + while (count--) + *xs++ = v; + return s; +} +EXPORT_SYMBOL(memset64); +#endif +#endif + #ifndef __HAVE_ARCH_MEMCPY /** * memcpy - Copy one area of memory to another -- 2.11.0
| |