aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/generic
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-02-21 08:07:34 +0000
committerRoland McGrath <roland@gnu.org>1995-02-21 08:07:34 +0000
commit67a87b936eaab25dc983e979e5a548256d1a527a (patch)
treecc821a229df7ee0d081df42258c31c241b78c0ef /sysdeps/generic
parent787126fe16e340c8a0c4301d4cab942973d7d85c (diff)
downloadglibc-67a87b936eaab25dc983e979e5a548256d1a527a.zip
glibc-67a87b936eaab25dc983e979e5a548256d1a527a.tar.gz
glibc-67a87b936eaab25dc983e979e5a548256d1a527a.tar.bz2
* 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.
Diffstat (limited to 'sysdeps/generic')
-rw-r--r--sysdeps/generic/memcpy.c13
-rw-r--r--sysdeps/generic/memmove.c8
-rw-r--r--sysdeps/generic/pagecopy.h74
3 files changed, 90 insertions, 5 deletions
diff --git a/sysdeps/generic/memcpy.c b/sysdeps/generic/memcpy.c
index 222d358..e1a1ade 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 e301681..8ef6f04 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 0000000..07202a3
--- /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