* string/Makefile (distribute): Add pagecopy.h.
authorRoland McGrath <roland@gnu.org>
Tue, 21 Feb 1995 08:07:34 +0000 (08:07 +0000)
committerRoland McGrath <roland@gnu.org>
Tue, 21 Feb 1995 08:07:34 +0000 (08:07 +0000)
* sysdeps/mach/pagecopy.h: New file.
* sysdeps/generic/pagecopy.h: New file.
* sysdeps/generic/memcpy.c: Include pagecopy.h; call
  PAGE_COPY_FWD_MAYBE first when word aligned.
* sysdeps/generic/memmove.c: Likewise.

ChangeLog
string/Makefile
sysdeps/generic/memcpy.c
sysdeps/generic/memmove.c
sysdeps/generic/pagecopy.h [new file with mode: 0644]
sysdeps/mach/pagecopy.h [new file with mode: 0644]

index ea275a0..9fb069a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 Tue Feb 21 00:10:50 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
+       * string/Makefile (distribute): Add pagecopy.h.
+       * sysdeps/mach/pagecopy.h: New file.
+       * sysdeps/generic/pagecopy.h: New file.
+       * sysdeps/generic/memcpy.c: Include pagecopy.h; call
+       PAGE_COPY_FWD_MAYBE first when word aligned.
+       * sysdeps/generic/memmove.c: Likewise.
+
        * misc/bsd-compat.c (longjmp, setjmp): Functions removed.
        (getpgrp): Call __getpgid instead of __getpgrp.
 
index a4ba83b..1fa63c2 100644 (file)
@@ -33,7 +33,7 @@ routines      := strcat strchr strcmp strcoll strcpy strcspn strdup   \
                   swab strfry memfrob memmem
 
 tests          := tester testcopy test-ffs
-distribute     := memcopy.h
+distribute     := memcopy.h pagecopy.h
 
 
 include ../Rules
index 222d358..e1a1ade 100644 (file)
@@ -21,6 +21,7 @@ Cambridge, MA 02139, USA.  */
 #include <ansidecl.h>
 #include <string.h>
 #include <memcopy.h>
+#include <pagecopy.h>
 
 PTR
 DEFUN(memcpy, (dstpp, srcpp, len),
@@ -38,10 +39,14 @@ DEFUN(memcpy, (dstpp, srcpp, len),
       len -= (-dstp) % OPSIZ;
       BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
 
-      /* Copy from SRCP to DSTP taking advantage of the known
-        alignment of DSTP.  Number of bytes remaining is put
-        in the third argumnet, i.e. in LEN.  This number may
-        vary from machine to machine.  */
+      /* Copy whole pages from SRCP to DSTP by virtual address manipulation,
+        as much as possible.  */
+
+      PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
+
+      /* Copy from SRCP to DSTP taking advantage of the known alignment of
+        DSTP.  Number of bytes remaining is put in the third argument,
+        i.e. in LEN.  This number may vary from machine to machine.  */
 
       WORD_COPY_FWD (dstp, srcp, len, len);
 
index e301681..8ef6f04 100644 (file)
@@ -1,6 +1,6 @@
 /* memmove -- copy memory to memory until the specified number of bytes
    has been copied.  Overlap is handled correctly.
-   Copyright (C) 1991 Free Software Foundation, Inc.
+   Copyright (C) 1991, 1995 Free Software Foundation, Inc.
    Contributed by Torbjorn Granlund (tege@sics.se).
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -21,6 +21,7 @@ Cambridge, MA 02139, USA.  */
 #include <ansidecl.h>
 #include <string.h>
 #include <memcopy.h>
+#include <pagecopy.h>
 
 /* All this is so that bcopy.c can #include
    this file after defining some things.  */
@@ -55,6 +56,11 @@ DEFUN(memmove, (a1, a2, len),
          len -= (-dstp) % OPSIZ;
          BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
 
+         /* Copy whole pages from SRCP to DSTP by virtual address
+            manipulation, as much as possible.  */
+
+         PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
+
          /* Copy from SRCP to DSTP taking advantage of the known
             alignment of DSTP.  Number of bytes remaining is put
             in the third argumnet, i.e. in LEN.  This number may
diff --git a/sysdeps/generic/pagecopy.h b/sysdeps/generic/pagecopy.h
new file mode 100644 (file)
index 0000000..07202a3
--- /dev/null
@@ -0,0 +1,74 @@
+/* Macros for copying by pages; used in memcpy, memmove.  Generic macros.
+Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/* This file defines the macro:
+
+   PAGE_COPY_FWD_MAYBE (dstp, srcp, nbytes_left, nbytes)
+
+   which is invoked like WORD_COPY_FWD et al.  The pointers should be at
+   least word aligned.  This will check if virtual copying by pages can and
+   should be done and do it if so.
+
+   System-specific pagecopy.h files should define these macros and then
+   #include this file:
+
+   PAGE_COPY_THRESHOLD
+   -- Minimum size for which virtual copying by pages is worthwhile.
+
+   PAGE_SIZE
+   -- Size of a page.
+
+   PAGE_COPY_FWD (dstp, srcp, nbytes_left, nbytes)
+   -- Macro to perform the virtual copy operation.
+   The pointers will be aligned to PAGE_SIZE bytes.
+*/
+
+
+#if PAGE_COPY_THRESHOLD
+
+#define PAGE_COPY_FWD_MAYBE(dstp, srcp, nbytes_left, nbytes)                 \
+  do                                                                         \
+    {                                                                        \
+      if ((nbytes) >= PAGE_COPY_THRESHOLD &&                                 \
+         PAGE_OFFSET (dstp) == PAGE_OFFSET (srcp))                           \
+       {                                                                     \
+         /* The amount to copy is past the threshold for copying             \
+            pages virtually with kernel VM operations, and the               \
+            source and destination addresses have the same alignment.  */    \
+         size_t nbytes_before = PAGE_OFFSET (PAGE_SIZE - PAGE_OFFSET (dstp));\
+         if (nbytes_before != 0)                                             \
+           {                                                                 \
+             /* First copy the words before the first page boundary.  */     \
+             WORD_COPY_FWD (dstp, srcp, nbytes_left, nbytes_before);         \
+             nbytes_before -= nbytes_left;                                   \
+             nbytes -= nbytes_before;                                        \
+           }                                                                 \
+         if (nbytes_before == 0)                                             \
+           PAGE_COPY_FWD (dstp, srcp, nbytes_left, nbytes);                  \
+       }                                                                     \
+    } while (0)
+
+/* The page size is always a power of two, so we can avoid modulo division.  */
+#define PAGE_OFFSET(n) ((n) & (PAGE_SIZE - 1))
+
+#else
+
+#define PAGE_COPY_FWD_MAYBE(dstp, srcp, nbytes_left, nbytes) /* nada */
+
+#endif
diff --git a/sysdeps/mach/pagecopy.h b/sysdeps/mach/pagecopy.h
new file mode 100644 (file)
index 0000000..e75c064
--- /dev/null
@@ -0,0 +1,36 @@
+/* Macros for copying by pages; used in memcpy, memmove.  Mach version.
+Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <mach.h>
+
+/* Threshold at which vm_copy is more efficient than well-optimized copying
+   by words.  This parameter should be tuned as necessary.  */
+#define PAGE_THRESHOLD         (2 * PAGE_SIZE) /* XXX ? */
+
+#define PAGE_SIZE              __vm_page_size
+#define PAGE_COPY_FWD(dstp, srcp, nbytes_left, nbytes)                       \
+  ((nbytes_left) = ((nbytes) -                                               \
+                   (__vm_copy (__mach_task_self (),                          \
+                               (vm_address_t) srcp, trunc_page (nbytes),     \
+                               (vm_address_t) dstp) == KERN_SUCCESS          \
+                    ? trunc_page (nbytes)                                    \
+                    : 0)))
+
+/* Get the generic macro.  */
+#include_next <pagecopy.h>