string: Use memcpy() within memmove() when we can
authorPatrick Delaunay <patrick.delaunay@foss.st.com>
Fri, 11 Dec 2020 13:59:23 +0000 (14:59 +0100)
committerTom Rini <trini@konsulko.com>
Sat, 16 Jan 2021 19:49:09 +0000 (14:49 -0500)
A common use of memmove() can be handled by memcpy(). Also memcpy()
includes an optimization for large sizes: it copies a word at a time. So
we can get a speed-up by calling memcpy() to handle our move in this case.

Update memmove() to call also memcpy() if the source don't overlap
the destination (src + count <= dest).

Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
lib/string.c

index ae7835f..73b9841 100644 (file)
@@ -567,7 +567,19 @@ void * memmove(void * dest,const void *src,size_t count)
 {
        char *tmp, *s;
 
-       if (dest <= src) {
+       if (dest <= src || (src + count) <= dest) {
+       /*
+        * Use the fast memcpy implementation (ARCH optimized or lib/string.c) when it is possible:
+        * - when dest is before src (assuming that memcpy is doing forward-copying)
+        * - when destination don't overlap the source buffer (src + count <= dest)
+        *
+        * WARNING: the first optimisation cause an issue, when __HAVE_ARCH_MEMCPY is defined,
+        *          __HAVE_ARCH_MEMMOVE is not defined and if the memcpy ARCH-specific
+        *          implementation is not doing a forward-copying.
+        *
+        * No issue today because memcpy is doing a forward-copying in lib/string.c and for ARM32
+        * architecture; no other arches use __HAVE_ARCH_MEMCPY without __HAVE_ARCH_MEMMOVE.
+        */
                memcpy(dest, src, count);
        } else {
                tmp = (char *) dest + count;