From 1ebef0a393ddbc27a1e6071d8364b43a42277c77 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sat, 24 Nov 2018 01:48:25 +0100 Subject: Add [raw]memelem{cpy,move} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- Makefile | 4 + libsimple/mem.h | 30 ++--- libsimple/memelem.h | 78 +++++++++++- libsimple/str.h | 20 ++-- libsimple/strn.h | 26 ++-- memelemcpy.c | 94 +++++++++++++++ memelemmove.c | 124 +++++++++++++++++++ rawmemelem.c | 2 +- rawmemelemcpy.c | 158 ++++++++++++++++++++++++ rawmemelemmove.c | 340 ++++++++++++++++++++++++++++++++++++++++++++++++++++ vmemalloc.c | 6 +- 11 files changed, 839 insertions(+), 43 deletions(-) create mode 100644 memelemcpy.c create mode 100644 memelemmove.c create mode 100644 rawmemelemcpy.c create mode 100644 rawmemelemmove.c diff --git a/Makefile b/Makefile index 047cc45..6937830 100644 --- a/Makefile +++ b/Makefile @@ -74,6 +74,8 @@ OBJ =\ memdup.o\ memelem.o\ memelem_inv.o\ + memelemcpy.o\ + memelemmove.o\ memelemscan.o\ memelemscan_inv.o\ memends.o\ @@ -106,6 +108,8 @@ OBJ =\ rawmemchr_inv.o\ rawmemelem.o\ rawmemelem_inv.o\ + rawmemelemcpy.o\ + rawmemelemmove.o\ rawmemrcasechr.o\ rawmemrcasechr_inv.o\ rawmemrchr.o\ diff --git a/libsimple/mem.h b/libsimple/mem.h index e6fb310..5ec8f9e 100644 --- a/libsimple/mem.h +++ b/libsimple/mem.h @@ -607,10 +607,10 @@ static inline void *libsimple_mempset(void *__s, int __c, size_t __n) * occurence of the specified byte value in the specified byte * array, its behaviour is undefined * - * @param d The location the byt array shall be copied to - * @param s The byte array to copy - * @param c The byte that stops the copying - * @param `&rawmemchr(d, c)[1]` (after copying) + * @param d The location the byte array shall be copied to + * @param s The byte array to copy + * @param c The byte that stops the copying + * @return `&rawmemchr(d, c)[1]` (after copying) */ static inline void * libsimple_rawmemccpy(void *restrict __d_, const void *restrict __s_, int __c_) /* TODO man */ @@ -628,13 +628,13 @@ libsimple_rawmemccpy(void *restrict __d_, const void *restrict __s_, int __c_) / /** * Move a string, but stop after a specific character * - * @param d The location the byt array shall be copied to - * @param s The byte array to copy - * @param c The byte that stops the copying - * @param n The length of `s` - * @param `&rawmemchr(d, c)[1]` (after copying) if `c` can - * be found within the first `n` bytes of `s` (before - * copying), `NULL` otherwise + * @param d The location the byte array shall be copied to + * @param s The byte array to copy + * @param c The byte that stops the copying + * @param n The length of `s` + * @return `&rawmemchr(d, c)[1]` (after copying) if `c` can + * be found within the first `n` bytes of `s` (before + * copying), `NULL` otherwise */ void *libsimple_memcmove(void *__d_, const void *__s_, int __c_, size_t __n); #ifndef memcmove @@ -650,10 +650,10 @@ void *libsimple_memcmove(void *__d_, const void *__s_, int __c_, size_t __n); * occurence of the specified byte value in the specified byte * array, its behaviour is undefined * - * @param d The location the byt array shall be copied to - * @param s The byte array to copy - * @param c The byte that stops the copying - * @param `&rawmemchr(d, c)[1]` (after copying) + * @param d The location the byte array shall be copied to + * @param s The byte array to copy + * @param c The byte that stops the copying + * @return `&rawmemchr(d, c)[1]` (after copying) */ static inline void * libsimple_rawmemcmove(void *__d_, const void *__s_, int __c_) /* TODO man */ diff --git a/libsimple/memelem.h b/libsimple/memelem.h index bce3e0c..4533db8 100644 --- a/libsimple/memelem.h +++ b/libsimple/memelem.h @@ -36,7 +36,7 @@ void *libsimple_memelem(const void *, size_t, const void *, size_t); * returned pointer and such that `(r - haystack) % nneedle == 0` */ _LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __returns_nonnull__, __warn_unused_result__))) -void *libsimple_rawmemelem(const void *, const void *, size_t); /* TODO man */ +void *libsimple_rawmemelem(const void *, const void *, size_t); #ifndef rawmemelem # define rawmemelem libsimple_rawmemelem #endif @@ -245,6 +245,82 @@ static inline void *libsimple_memsetelem(void *__buf, const void *__item, size_t #endif +/** + * Copy elements in an array to another array, but stop after a specific element + * + * @param d The location the array shall be copied to + * @param s The array to copy + * @param elem The element that stops the copying + * @param size The size of each element + * @param n The maximum number of elements to copy + * @return `&rawmemelem(d, c, size)[size]` (after copying) if `elem` + * can be found within the first `n` elements of `s` (before + * copying), `NULL` otherwise + */ +void *libsimple_memelemcpy(void *restrict __d, const void *restrict __s, const void *restrict __elem, size_t __size, size_t __n); +#ifndef memelemcpy +# define memelemcpy libsimple_memelemcpy +#endif + + +/** + * Move elements in an array, but stop after a specific element + * + * @param d The location the array shall be copied to + * @param s The array to copy + * @param elem The element that stops the copying + * @param size The size of each element + * @param n The maximum number of elements to copy + * @return `&rawmemelem(d, c, size)[size]` (after copying) if `elem` + * can be found within the first `n` elements of `s` (before + * copying), `NULL` otherwise + */ +void *libsimple_memelemmove(void *__d, const void *__s, const void *restrict __elem, size_t __size, size_t __n); +#ifndef memelemmove +# define memelemmove libsimple_memelemmove +#endif + + +/** + * Copy elements in an array to another array, but stop after a specific element + * + * This function is optimised for instances where it is already + * known that there is at least one occurence; if there is no + * occurence of the specified value in the specified array, its + * behaviour is undefined + * + * @param d The location the array shall be copied to + * @param s The array to copy + * @param elem The element that stops the copying + * @param size The size of each element + * @return `&rawmemelem(d, c, size)[size]` (after copying) + */ +void *libsimple_rawmemelemcpy(void *restrict __d, const void *restrict __s, const void *restrict __elem, size_t __size); +#ifndef rawmemelemcpy +# define rawmemelemcpy libsimple_rawmemelemcpy +#endif + + +/** + * Move elements in an array, but stop after a specific element + * + * This function is optimised for instances where it is already + * known that there is at least one occurence; if there is no + * occurence of the specified value in the specified array, its + * behaviour is undefined + * + * @param d The location the array shall be copied to + * @param s The array to copy + * @param elem The element that stops the copying + * @param size The size of each element + * @return `&rawmemelem(d, c, size)[size]` (after copying) + */ +void *libsimple_rawmemelemmove(void *__d, const void *__s, const void *restrict __elem, size_t __size); +#ifndef rawmemelemmove +# define rawmemelemmove libsimple_rawmemelemmove +#endif + + /** * Replace all instances of an element in an array of * elements with another element diff --git a/libsimple/str.h b/libsimple/str.h index 48d3aa9..5a5c146 100644 --- a/libsimple/str.h +++ b/libsimple/str.h @@ -546,11 +546,11 @@ libsimple_stpset(char *__s, int __c_) /* TODO man */ * Copy a string, but stop after a specific character, * the new string will be NUL-terminated * - * @param d The location the string shall be copied to - * @param s The string to copy - * @param c The character that stops the copying - * @param `&strchr(d, c)[1]` (after copying) if `c` can be - * found in `s`, `NULL` otherwise + * @param d The location the string shall be copied to + * @param s The string to copy + * @param c The character that stops the copying + * @return `&strchr(d, c)[1]` (after copying) if `c` can be + * found in `s`, `NULL` otherwise */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) static inline char * @@ -571,11 +571,11 @@ libsimple_strccpy(char *restrict __d, const char *restrict __s, int __c_) /* TOD /** * Move a string, but stop after a specific character * - * @param d The location the string shall be moved to - * @param s The string to copy - * @param c The character that stops the copying - * @param `&strchr(d, c)[1]` (after copying) if `c` can be - * found in `s` (before copying), `NULL` otherwise + * @param d The location the string shall be moved to + * @param s The string to copy + * @param c The character that stops the copying + * @return `&strchr(d, c)[1]` (after copying) if `c` can be + * found in `s` (before copying), `NULL` otherwise */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) char *libsimple_strcmove(char *, const char *, int); diff --git a/libsimple/strn.h b/libsimple/strn.h index eaff234..59539e1 100644 --- a/libsimple/strn.h +++ b/libsimple/strn.h @@ -621,12 +621,12 @@ libsimple_stpnset(char *__s, int __c_, size_t __n) /* TODO man */ * the new string will be NUL-terminated if it is * shorter than `n` bytes * - * @param d The location the string shall be copied to - * @param s The string to copy - * @param c The character that stops the copying - * @param n The maximum number of bytes to copy - * @param `&strchr(d, c)[1]` (after copying) if `c` can be - * found in `s`, `NULL` otherwise + * @param d The location the string shall be copied to + * @param s The string to copy + * @param c The character that stops the copying + * @param n The maximum number of bytes to copy + * @return `&strchr(d, c)[1]` (after copying) if `c` can be + * found in `s`, `NULL` otherwise */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) static inline char * @@ -653,13 +653,13 @@ libsimple_strnccpy(char *restrict __d, const char *restrict __s, int __c_, size_ /** * Move a string, but stop after a specific character * - * @param d The location the string shall be moved to - * @param s The string to copy - * @param c The character that stops the copying - * @param n The maximum number of bytes to move - * @param `&strchr(d, c)[1]` (after copying) if `c` can be - * found within the first `n` bytes of `s` (before - * copying), `NULL` otherwise + * @param d The location the string shall be moved to + * @param s The string to copy + * @param c The character that stops the copying + * @param n The maximum number of bytes to move + * @return `&strchr(d, c)[1]` (after copying) if `c` can be + * found within the first `n` bytes of `s` (before + * copying), `NULL` otherwise */ _LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__))) char *libsimple_strncmove(char *, const char *, int, size_t); diff --git a/memelemcpy.c b/memelemcpy.c new file mode 100644 index 0000000..da32946 --- /dev/null +++ b/memelemcpy.c @@ -0,0 +1,94 @@ +/* See LICENSE file for copyright and license details. */ +#include "libsimple.h" +#ifndef TEST + + +static inline uint8_t * +memelemcpy8(uint8_t *restrict d, const uint8_t *restrict s, uint8_t elem, size_t n) +{ + for (; n; s++, n--) + if ((*d++ = *s) == elem) + return d; + return NULL; +} + + +static inline uint16_t * +memelemcpy16(uint16_t *restrict d, const uint16_t *restrict s, uint16_t elem, size_t n) +{ + for (; n; s++, n--) + if ((*d++ = *s) == elem) + return d; + return NULL; +} + + +static inline uint32_t * +memelemcpy32(uint32_t *restrict d, const uint32_t *restrict s, uint32_t elem, size_t n) +{ + for (; n; s++, n--) + if ((*d++ = *s) == elem) + return d; + return NULL; +} + + +static inline uint64_t * +memelemcpy64(uint64_t *restrict d, const uint64_t *restrict s, uint64_t elem, size_t n) +{ + for (; n; s++, n--) + if ((*d++ = *s) == elem) + return d; + return NULL; +} + + +static inline char * +memelemcpyx(char *restrict d, const char *restrict s, const char *restrict elem, size_t size, size_t n) +{ + size_t i; + for (; n; s += size, n--) { + for (i = 0; i < size; i++) + d[i] = s[i]; + for (i = 0; i < size; i++) + if (d[i] != elem[i]) + goto next; + d += size; + return d; + next: + d += size; + } + return NULL; +} + + +void * +libsimple_memelemcpy(void *restrict d, const void *restrict s, const void *restrict elem, size_t size, size_t n) /* TODO test, man */ +{ + switch (size) { + case 0: + return d; + case 1: + return memelemcpy8(d, s, *(const uint8_t *)elem, n); + case 2: + return memelemcpy16(d, s, *(const uint16_t *)elem, n); + case 4: + return memelemcpy32(d, s, *(const uint32_t *)elem, n); + case 8: + return memelemcpy64(d, s, *(const uint64_t *)elem, n); + default: + return memelemcpyx(d, s, elem, size, n); + } +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/memelemmove.c b/memelemmove.c new file mode 100644 index 0000000..2a90e26 --- /dev/null +++ b/memelemmove.c @@ -0,0 +1,124 @@ +/* See LICENSE file for copyright and license details. */ +#include "libsimple.h" +#ifndef TEST + + +#define MEMELEMMOVE(TYPE)\ + do {\ + TYPE *p;\ + if (d <= s) {\ + for (; n; n--, s++)\ + if ((*d++ = *s) == elem)\ + return d;\ + } else {\ + for (p = *(TYPE **)(void *)&s; n; n--, p++) {\ + if (*p == elem) {\ + n = (size_t)(p - s);\ + p = &d[n + 1];\ + do { d[n] = s[n]; } while (n--);\ + return p;\ + }\ + }\ + for (n = (size_t)(p - s); n;) {\ + n--;\ + d[n] = s[n];\ + }\ + }\ + return NULL;\ + } while (0) + + +static uint16_t * +memelemmove16(uint16_t *restrict d, const uint16_t *restrict s, uint16_t elem, size_t n) +{ + MEMELEMMOVE(uint16_t); +} + + +static uint32_t * +memelemmove32(uint32_t *restrict d, const uint32_t *restrict s, uint32_t elem, size_t n) +{ + MEMELEMMOVE(uint32_t); +} + + +static uint64_t * +memelemmove64(uint64_t *restrict d, const uint64_t *restrict s, uint64_t elem, size_t n) +{ + MEMELEMMOVE(uint64_t); +} + + +static char * +memelemmovex(char *restrict d, const char *restrict s, const char *restrict elem, size_t size, size_t n) +{ + char *p; + size_t i; + if (d <= s) { + for (; n; s += size, n--) { + for (i = 0; i < size; i++) + d[i] = s[i]; + for (i = 0; i < size; i++) + if (d[i] != elem[i]) + goto next_forwards; + d += size; + return d; + next_forwards: + d += size; + } + return NULL; + } else { + for (p = *(char **)(void *)&s; n; n--) { + for (i = 0; i < size; i++) + if (p[i] != elem[i]) + goto next_backwards; + + p += size; + n = (size_t)(p - s); + p = &d[n]; + goto out_backwards; + next_backwards: + p += size; + } + n = (size_t)(p - s); + p = NULL; + out_backwards: + while (n) { + n--; + d[n] = s[n]; + } + return p; + } +} + + +void * +libsimple_memelemmove(void *d, const void *s, const void *restrict elem, size_t size, size_t n) /* TODO test, man */ +{ + switch (size) { + case 0: + return d; + case 1: + return memcmove(d, s, *(const char *)elem, n); + case 2: + return memelemmove16(d, s, *(const uint16_t *)elem, n); + case 4: + return memelemmove32(d, s, *(const uint32_t *)elem, n); + case 8: + return memelemmove64(d, s, *(const uint64_t *)elem, n); + default: + return memelemmovex(d, s, elem, size, n); + } +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif diff --git a/rawmemelem.c b/rawmemelem.c index d2d743a..92beedb 100644 --- a/rawmemelem.c +++ b/rawmemelem.c @@ -4,7 +4,7 @@ void * -libsimple_rawmemelem(const void *hay_, const void *sub_, size_t subn) +libsimple_rawmemelem(const void *hay_, const void *sub_, size_t subn) /* TODO man */ { switch (subn) { case 0: diff --git a/rawmemelemcpy.c b/rawmemelemcpy.c new file mode 100644 index 0000000..2f0f9f0 --- /dev/null +++ b/rawmemelemcpy.c @@ -0,0 +1,158 @@ +/* See LICENSE file for copyright and license details. */ +#include "libsimple.h" +#ifndef TEST + + +static inline uint8_t * +rawmemelemcpy8(uint8_t *restrict d, const uint8_t *restrict s, uint16_t elem) +{ + for (; (*d++ = *s) != elem; s++); + return d; +} + + +static inline uint16_t * +rawmemelemcpy16(uint16_t *restrict d, const uint16_t *restrict s, uint16_t elem) +{ + for (; (*d++ = *s) != elem; s++); + return d; +} + + +static inline uint32_t * +rawmemelemcpy32(uint32_t *restrict d, const uint32_t *restrict s, uint32_t elem) +{ + for (; (*d++ = *s) != elem; s++); + return d; +} + + +static inline uint64_t * +rawmemelemcpy64(uint64_t *restrict d, const uint64_t *restrict s, uint64_t elem) +{ + for (; (*d++ = *s) != elem; s++); + return d; +} + + +static inline char * +rawmemelemcpyx(char *restrict d, const char *restrict s, const char *restrict elem, size_t size) +{ + size_t i; + for (;; s += size) { + for (i = 0; i < size; i++) + d[i] = s[i]; + for (i = 0; i < size; i++) + if (d[i] != elem[i]) + goto next; + d += size; + return d; + next: + d += size; + } +} + + +void * +libsimple_rawmemelemcpy(void *restrict d, const void *restrict s, const void *restrict elem, size_t size) /* TODO man */ +{ + switch (size) { + case 0: + return d; + case 1: + return rawmemelemcpy8(d, s, *(const uint8_t *)elem); + case 2: + return rawmemelemcpy16(d, s, *(const uint16_t *)elem); + case 4: + return rawmemelemcpy32(d, s, *(const uint32_t *)elem); + case 8: + return rawmemelemcpy64(d, s, *(const uint64_t *)elem); + default: + return rawmemelemcpyx(d, s, elem, size); + } +} + + +#else +#include "test.h" + +int +main(void) +{ + char buf[1024]; + + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, "hello", "o", 0) == &buf[0]); + assert(!strncmp(buf, "x", 1)); + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, "hello", "l", 0) == &buf[0]); + assert(!strncmp(buf, "x", 1)); + + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, "hello", "o", 1) == &buf[5]); + assert(!strncmp(buf, "hellox", 6)); + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, "hello", "l", 1) == &buf[3]); + assert(!strncmp(buf, "helx", 4)); + + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, ".h.e.l.l.o", ".o", 2) == &buf[5 * 2]); + assert(!strncmp(buf, ".h.e.l.l.ox", 11)); + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, ".h.e.l.l.o", ".l", 2) == &buf[3 * 2]); + assert(!strncmp(buf, ".h.e.lx", 7)); + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, ".h.l.ll..o", "l.", 2) == &buf[4 * 2]); + assert(!strncmp(buf, ".h.l.ll.x", 9)); + + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, "..h..e..l..l..o", "..o", 3) == &buf[5 * 3]); + assert(!strncmp(buf, "..h..e..l..l..ox", 16)); + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, "..h..e..l..l..o", "..l", 3) == &buf[3 * 3]); + assert(!strncmp(buf, "..h..e..lx", 10)); + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, "..h..l..ll....o", "l..", 3) == &buf[4 * 3]); + assert(!strncmp(buf, "..h..l..ll..x", 13)); + + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, "...h...e...l...l...o", "...o", 4) == &buf[5 * 4]); + assert(!strncmp(buf, "...h...e...l...l...ox", 21)); + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, "...h...e...l...l...o", "...l", 4) == &buf[3 * 4]); + assert(!strncmp(buf, "...h...e...lx", 13)); + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, "...h...l...ll......o", "l...", 4) == &buf[4 * 4]); + assert(!strncmp(buf, "...h...l...ll...x", 17)); + + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, ".......h.......e.......l.......l.......o", ".......o", 8) == &buf[5 * 8]); + assert(!strncmp(buf, ".......h.......e.......l.......l.......ox", 21)); + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, ".......h.......e.......l.......l.......o", ".......l", 8) == &buf[3 * 8]); + assert(!strncmp(buf, ".......h.......e.......lx", 13)); + + memset(buf, 'x', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + assert(libsimple_rawmemelemcpy(buf, ".......h.......l.......ll..............o", "l.......", 8) == &buf[4 * 8]); + assert(!strncmp(buf, ".......h.......l.......ll.......x", 21)); + + + return 0; +} + +#endif diff --git a/rawmemelemmove.c b/rawmemelemmove.c new file mode 100644 index 0000000..c663219 --- /dev/null +++ b/rawmemelemmove.c @@ -0,0 +1,340 @@ +/* See LICENSE file for copyright and license details. */ +#include "libsimple.h" +#ifndef TEST + + +#define RAWMEMELEMMOVE(TYPE)\ + do {\ + TYPE *p;\ + size_t n;\ + if (d <= s) {\ + for (; (*d++ = *s) != elem; s++);\ + return d;\ + } else {\ + for (p = *(TYPE **)(void *)&s; *p++ != elem;);\ + n = (size_t)(p - s);\ + p = &d[n];\ + while (n) {\ + n--;\ + d[n] = s[n];\ + }\ + return p;\ + }\ + } while (0) + + +static uint16_t * +rawmemelemmove16(uint16_t *restrict d, const uint16_t *restrict s, uint16_t elem) +{ + RAWMEMELEMMOVE(uint16_t); +} + + +static uint32_t * +rawmemelemmove32(uint32_t *restrict d, const uint32_t *restrict s, uint32_t elem) +{ + RAWMEMELEMMOVE(uint32_t); +} + + +static uint64_t * +rawmemelemmove64(uint64_t *restrict d, const uint64_t *restrict s, uint64_t elem) +{ + RAWMEMELEMMOVE(uint64_t); +} + + +static char * +rawmemelemmovex(char *restrict d, const char *restrict s, const char *restrict elem, size_t size) +{ + char *p; + size_t i, n; + if (d <= s) { + for (;; s += size) { + for (i = 0; i < size; i++) + d[i] = s[i]; + for (i = 0; i < size; i++) + if (d[i] != elem[i]) + goto next_forwards; + d += size; + return d; + next_forwards: + d += size; + } + } else { + for (p = *(char **)(void *)&s;;) { + for (i = 0; i < size; i++) + if (p[i] != elem[i]) + goto next_backwards; + p += size; + break; + next_backwards: + p += size; + } + n = (size_t)(p - s); + p = &d[n]; + while (n) { + n--; + d[n] = s[n]; + } + return p; + } +} + + +void * +libsimple_rawmemelemmove(void *d, const void *s, const void *restrict elem, size_t size) /* TODO man */ +{ + switch (size) { + case 0: + return d; + case 1: + return rawmemcmove(d, s, *(const char *)elem); + case 2: + return rawmemelemmove16(d, s, *(const uint16_t *)elem); + case 4: + return rawmemelemmove32(d, s, *(const uint32_t *)elem); + case 8: + return rawmemelemmove64(d, s, *(const uint64_t *)elem); + default: + return rawmemelemmovex(d, s, elem, size); + } +} + + +#else +#include "test.h" + +int +main(void) +{ + char buf[1024]; + + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "hello")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "", 0) == &buf[5]); + assert(!strncmp(buf, "-----hello-", 11)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "hello")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "", 0) == &buf[3]); + assert(!strncmp(buf, "-----hello-", 11)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "hello")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[5], &buf[3], "", 0) == &buf[5]); + assert(!strncmp(buf, "-----hello-", 11)); + + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "hello")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "o", 1) == &buf[5 + 5]); + assert(!strncmp(buf, "-----hello-", 11)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "hello")[0] = '-';; + assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "l", 1) == &buf[5 + 3]); + assert(!strncmp(buf, "-----hello-", 11)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "hello")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "o", 1) == &buf[3 + 5]); + assert(!strncmp(buf, "---hellolo-", 11)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "hello")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "l", 1) == &buf[3 + 3]); + assert(!strncmp(buf, "---helello-", 11)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "hello")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "o", 1) == &buf[8 + 5]); + assert(!strncmp(buf, "-----helhello-", 14)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "hello")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "l", 1) == &buf[8 + 3]); + assert(!strncmp(buf, "-----helhel-", 12)); + + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".h.e.l.l.o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[5], &buf[5], ".o", 2) == &buf[5 + 5 * 2]); + assert(!strncmp(buf, "-----.h.e.l.l.o-", 16)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".h.e.l.l.o")[0] = '-';; + assert(libsimple_rawmemelemmove(&buf[5], &buf[5], ".l", 2) == &buf[5 + 3 * 2]); + assert(!strncmp(buf, "-----.h.e.l.l.o-", 16)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".h.e.l.l.o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[3], &buf[5], ".o", 2) == &buf[3 + 5 * 2]); + assert(!strncmp(buf, "---.h.e.l.l.o.o-", 16)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".h.e.l.l.o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[3], &buf[5], ".l", 2) == &buf[3 + 3 * 2]); + assert(!strncmp(buf, "---.h.e.l.l.l.o-", 16)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".h.e.l.l.o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[8], &buf[5], ".o", 2) == &buf[8 + 5 * 2]); + assert(!strncmp(buf, "-----.h..h.e.l.l.o-", 19)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".h.e.l.l.o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[8], &buf[5], ".l", 2) == &buf[8 + 3 * 2]); + assert(!strncmp(buf, "-----.h..h.e.lo-", 16)); + + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "..h..e..l..l..o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "..o", 3) == &buf[5 + 5 * 3]); + assert(!strncmp(buf, "-----..h..e..l..l..o-", 21)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "..h..e..l..l..o")[0] = '-';; + assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "..l", 3) == &buf[5 + 3 * 3]); + assert(!strncmp(buf, "-----..h..e..l..l..o-", 21)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "..h..e..l..l..o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "..o", 3) == &buf[3 + 5 * 3]); + assert(!strncmp(buf, "---..h..e..l..l..o.o-", 21)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "..h..e..l..l..o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "..l", 3) == &buf[3 + 3 * 3]); + assert(!strncmp(buf, "---..h..e..l.l..l..o-", 21)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "..h..e..l..l..o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "..o", 3) == &buf[8 + 5 * 3]); + assert(!strncmp(buf, "-----..h..h..e..l..l..o-", 24)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "..h..e..l..l..o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "..l", 3) == &buf[8 + 3 * 3]); + assert(!strncmp(buf, "-----..h..h..e..l..o-", 21)); + + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "...h...e...l...l...o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "...o", 4) == &buf[5 + 5 * 4]); + assert(!strncmp(buf, "-----...h...e...l...l...o-", 26)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "...h...e...l...l...o")[0] = '-';; + assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "...l", 4) == &buf[5 + 3 * 4]); + assert(!strncmp(buf, "-----...h...e...l...l...o-", 26)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "...h...e...l...l...o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "...o", 4) == &buf[3 + 5 * 4]); + assert(!strncmp(buf, "---...h...e...l...l...o.o-", 26)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "...h...e...l...l...o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "...l", 4) == &buf[3 + 3 * 4]); + assert(!strncmp(buf, "---...h...e...l.l...l...o-", 26)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "...h...e...l...l...o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "...o", 4) == &buf[8 + 5 * 4]); + assert(!strncmp(buf, "-----......h...e...l...l...o-", 29)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "...h...e...l...l...o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "...l", 4) == &buf[8 + 3 * 4]); + assert(!strncmp(buf, "-----......h...e...ll...o-", 26)); + + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".......h.......e.......l.......l.......o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[5], &buf[5], ".......o", 8) == &buf[5 + 5 * 8]); + assert(!strncmp(buf, "-----.......h.......e.......l.......l.......o-", 46)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".......h.......e.......l.......l.......o")[0] = '-';; + assert(libsimple_rawmemelemmove(&buf[5], &buf[5], ".......l", 8) == &buf[5 + 3 * 8]); + assert(!strncmp(buf, "-----.......h.......e.......l.......l.......o-", 46)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".......h.......e.......l.......l.......o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[3], &buf[5], ".......o", 8) == &buf[3 + 5 * 8]); + assert(!strncmp(buf, "---.......h.......e.......l.......l.......o.o-", 46)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".......h.......e.......l.......l.......o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[3], &buf[5], ".......l", 8) == &buf[3 + 3 * 8]); + assert(!strncmp(buf, "---.......h.......e.......l.l.......l.......o-", 46)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".......h.......e.......l.......l.......o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[8], &buf[5], ".......o", 8) == &buf[8 + 5 * 8]); + assert(!strncmp(buf, "-----..........h.......e.......l.......l.......o-", 49)); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".......h.......e.......l.......l.......o")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[8], &buf[5], ".......l", 8) == &buf[8 + 3 * 8]); + assert(!strncmp(buf, "-----..........h.......e.......l....l.......o-", 46)); + + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".a.a.aa..a")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "a.", 2) == &buf[5 + 4 * 2]); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".a.a.aa..a")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "a.", 2) == &buf[3 + 4 * 2]); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".a.a.aa..a")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "a.", 2) == &buf[8 + 4 * 2]); + + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "..a..a..aa....a")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "a..", 3) == &buf[5 + 4 * 3]); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "..a..a..aa....a")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "a..", 3) == &buf[3 + 4 * 3]); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "..a..a..aa....a")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "a..", 3) == &buf[8 + 4 * 3]); + + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "...a...a...aa......a")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "a...", 4) == &buf[5 + 4 * 4]); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "...a...a...aa......a")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "a...", 4) == &buf[3 + 4 * 4]); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], "...a...a...aa......a")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "a...", 4) == &buf[8 + 4 * 4]); + + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".......a.......a.......aa..............a")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[5], &buf[5], "a.......", 8) == &buf[5 + 4 * 8]); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".......a.......a.......aa..............a")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[3], &buf[5], "a.......", 8) == &buf[3 + 4 * 8]); + + memset(buf, '-', sizeof(buf)), buf[sizeof(buf) - 1] = '\0'; + stpcpy(&buf[5], ".......a.......a.......aa..............a")[0] = '-'; + assert(libsimple_rawmemelemmove(&buf[8], &buf[5], "a.......", 8) == &buf[8 + 4 * 8]); + + + return 0; +} + +#endif diff --git a/vmemalloc.c b/vmemalloc.c index f79ebb0..8d92035 100644 --- a/vmemalloc.c +++ b/vmemalloc.c @@ -183,7 +183,7 @@ void * libsimple_vmemalloc(size_t n, va_list ap) /* TODO test ([v]{mem,array}alloc) */ { struct memalloc_state state; - size_t misalignment, size, cacheline, min, max; + size_t misalignment, size, cacheline = 64, min, max; void *ptr = NULL; int saved_errno; long int tmp; @@ -225,10 +225,10 @@ libsimple_vmemalloc(size_t n, va_list ap) /* TODO test ([v]{mem,array}alloc) */ if (state.cache_align || !state.cache_split) { #ifdef _SC_LEVEL1_DCACHE_LINESIZE tmp = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); - cacheline = (size_t)(tmp < 1 ? 64L : tmp); + if (tmp >= 1) + cacheline = (size_t)tmp; #else (void) tmp; - cacheline = 64; #endif } -- cgit v1.2.3-70-g09d2