summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--string/Makefile2
-rw-r--r--sysdeps/generic/memcpy.c13
-rw-r--r--sysdeps/generic/memmove.c8
-rw-r--r--sysdeps/generic/pagecopy.h74
-rw-r--r--sysdeps/mach/pagecopy.h36
6 files changed, 134 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index ea275a0833..9fb069a143 100644
--- 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.
diff --git a/string/Makefile b/string/Makefile
index a4ba83b465..1fa63c24d2 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -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
diff --git a/sysdeps/generic/memcpy.c b/sysdeps/generic/memcpy.c
index 222d358224..e1a1ade057 100644
--- a/sysdeps/generic/memcpy.c
+++ b/sysdeps/generic/memcpy.c
@@ -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);
diff --git a/sysdeps/generic/memmove.c b/sysdeps/generic/memmove.c
index e3016819d9..8ef6f04cbe 100644
--- a/sysdeps/generic/memmove.c
+++ b/sysdeps/generic/memmove.c
@@ -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
index 0000000000..07202a3119
--- /dev/null
+++ b/sysdeps/generic/pagecopy.h
@@ -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
index 0000000000..e75c064f06
--- /dev/null
+++ b/sysdeps/mach/pagecopy.h
@@ -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>