aboutsummaryrefslogtreecommitdiff
path: root/libpager
diff options
context:
space:
mode:
Diffstat (limited to 'libpager')
-rw-r--r--libpager/ChangeLog374
-rw-r--r--libpager/Makefile3
-rw-r--r--libpager/data-init.c34
-rw-r--r--libpager/data-request.c38
-rw-r--r--libpager/data-return.c57
-rw-r--r--libpager/data-unlock.c13
-rw-r--r--libpager/demuxer.c16
-rw-r--r--libpager/lock-object.c21
-rw-r--r--libpager/mark-error.c24
-rw-r--r--libpager/notify-stubs.c43
-rw-r--r--libpager/object-create.c73
-rw-r--r--libpager/object-terminate.c22
-rw-r--r--libpager/offer-page.c30
-rw-r--r--libpager/pagemap.c38
-rw-r--r--libpager/pager-memcpy.c195
-rw-r--r--libpager/pager.h10
-rw-r--r--libpager/priv.h35
-rw-r--r--libpager/seqnos.c26
-rw-r--r--libpager/stubs.c18
19 files changed, 396 insertions, 674 deletions
diff --git a/libpager/ChangeLog b/libpager/ChangeLog
deleted file mode 100644
index ed8e3cca..00000000
--- a/libpager/ChangeLog
+++ /dev/null
@@ -1,374 +0,0 @@
-Thu May 9 11:10:11 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * pager-create.c: Get rid of link warning.
-
- * pager-create.c (pager_create): ports_allocate_port ->
- ports_create_port; if we get an error return a null structure.
-
-Thu May 2 11:17:17 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * offer-page.c (pager_offer_page): Make sure we hold lock across
- operation. Also set incore bit when operation is complete.
-
-Tue Apr 30 12:40:33 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * lock-object.c (_pager_lock_object): Eliminate spurious extra
- lock acquisition around pagemap frobbing.
-
-Sun Apr 28 15:46:12 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
-
- * pager-create.c (pager_create): Add link warning.
-
-Thu Apr 18 13:03:55 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * data-return.c (_pager_do_write_request): If kernel didn't keep a
- copy, turn off INCORE bit. Don't track INIT bit for now.
- * lock-object.c (_pager_lock_object): If SYNC and SHOULD_FLUSH,
- then turn off PM_INCORE bits when flush is complete.
- * data-request.c (_pager_seqnos_memory_object_data_request): Set
- PM_INCORE.
- * priv.h (PM_INIT): Comment out.
- (PM_INCORE): New bit.
- * offer-page.c: New file.
- * Makefile (SRCS): Add offer-page.c.
- * pager.h (pager_offer_page): New function.
-
-Thu Apr 11 17:50:57 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * pager-memcpy.c (pager_memcpy [copy]): Return error_t so that
- this function has the proper type as an arg for
- hurd_catch_signal.
- (pager_memcpy): Cast FAULT to proper type in call to
- hurd_catch_signal.
-
-Tue Mar 26 15:38:06 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * lock-completed.c: Include <stdio.h>.
-
- * data-return.c (_pager_do_write_request): Delete unused label
- `out'.
-
- * pager-sync.c (pager_sync, pager_sync_some): Ask for RETURN_ALL
- and not just RETURN_DIRTY, because we treat precious pages as
- dirty in this library.
- * pager-return.c (pager_return, pager_return_some): Likewise.
-
-Mon Mar 18 13:10:32 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * pager.h (pager_return, pager_return_some): New declarations.
- * Makefile (SRCS): Add pager-return.c.
- * pager-return.c: New file.
-
- * pager-flush.c (pager_flush): Lock request should be
- VM_PROT_NO_CHANGE, not VM_PROT_NONE.
- (pager_flush_some): Likewise.
-
-Wed Mar 6 17:53:20 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * lock-object.c (_pager_lock_object): Correctly remove LR from
- P's linked list of lock requests.
- * pager-attr.c (pager_change_attributes): Likewise for attributes.
-
- * lock-object.c (_pager_lock_object): Don't barf anymore.
- * lock-completed.c (_pager_seqnos_memory_object_lock_completed): Ditto.
- * Makefile (SRCS): Remove barf.c.
-
-Wed Feb 21 14:15:26 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * lock-completed.c (_pager_seqnos_memory_object_lock_completed):
- Get rid of bletcherous semi.
- Make barf more voluminous.
-
- * lock-completed.c (_pager_seqnos_memory_object_lock_completed):
- Be picky about always releasing SEQNO.
- * object-init.c (_pager_seqnos_memory_object_init): Likewise.
-
-Tue Feb 20 17:44:59 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * lock-object.c (_pager_lock_object): Use barf instead of printf.
- * lock-completed.c (_pager_seqnos_memory_object_lock_completed): Ditto.
- * Makefile (SRCS): Add barf.c.
-
- * data-return.c (_pager_do_write_request): Always wait for and
- release SEQNO if OBJECT is a valid pager.
- * data-request.c (_pager_seqnos_memory_object_data_request): Likewise.
- * object-terminate.c (_pager_seqnos_memory_object_terminate): Likewise.
-
-Tue Feb 20 16:05:42 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu>
-
- * lock-object.c (_pager_lock_object): Print debugging message when
- SYNC.
- * lock-completed.c (_pager_seqnos_memory_object_lock_completed):
- Print a notice when an incoming lock completion corresponds to no
- outstanding lock request.
-
-Tue Feb 20 15:10:29 1996 Miles Bader <miles@gnu.ai.mit.edu>
-
- * lock-object.c (_pager_lock_object): Remove `sync = 0'.
-
-Fri Jan 5 17:09:43 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * pager-memcpy.c: New file.
- * Makefile (SRCS): Add pager-memcpy.c.
-
-Thu Jan 4 15:37:21 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * pager.h: Declare pager_memcpy.
-
-Mon Oct 9 14:57:48 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * priv.h: Declare _pager_page_errors extern, not common.
-
- * Makefile: Specify shared library dependencies.
-
-Wed Sep 13 14:49:53 1995 Michael I. Bushnell, p/BSG <mib@duality.gnu.ai.mit.edu>
-
- * lock-completed.c (_pager_seqnos_memory_object_lock_completed):
- Don't push the locks_pending field negative in the case where the
- pager was terminated before we get called.
-
-Tue Sep 5 15:50:12 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * chg-compl.c (_pager_seqnos_memory_object_change_completed):
- Don't push the attrs_pending field negative in the case where the
- pager was terminated before we get called.
-
-Wed Aug 23 15:00:46 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * Makefile (SRCS): Make this the main list of files, from which
- the others are derived.
- (COBJS, REMHDRS): Removed.
- (OBJS): Derived mostly from $(SRCS).
-
-Fri Jul 21 16:43:19 1995 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * object-create.c (_pager_seqnos_memory_object_create): Drop
- initial reference created by ports_intern_external_reference when
- we're done with P.
-
-Thu Jul 6 15:36:36 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * Makefile: Removed dependencies that are now automatically
- generated.
-
-Mon Jun 26 20:15:03 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * get-upi.c: New file.
- * pager.h (pager_get_upi): New function.
- * Makefile (COBJS): Add get-upi.o.
-
-Thu Jun 22 11:43:15 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * object-init.c (_pager_seqnos_memory_object_init): Rather than an
- empty `if' body and an unconditional return, how about a real
- test?
-
- * notify-stubs.c: New file.
- * Makefile (COBJS): Add notify-stubs.o.
-
-Tue Jun 20 12:44:22 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu>
-
- * chg-compl.c (_pager_seqnos_memory_object_change_completed): Use
- new ports routines.
- * pager-shutdown.c (pager_shutdown): Likewise.
- * object-terminate.c (_pager_free_structure): Likewise.
- * object-init.c (_pager_seqnos_memory_object_init): Likewise.
- * lock-completed.c (_pager_seqnos_memory_object_lock_completed):
- Likewise.
- * data-unlock.c (_pager_seqnos_memory_object_data_unlock): Likewise.
- * data-return.c (_pager_do_write_request): Likewise.
- * data-request.c (_pager_seqnos_memory_object_data_request):
- Likewise.
- * pager-create.c (pager_create): New parm BUCKET. Allocate port
- using new ports interface. Arrange to have _pager_class
- initialized at startup.
- * clean.c, dropweak.c: New files.
- * no-senders.c: Rename pager_no_senders to
- _pager_do_seqnos_mach_notify_no_senders. Lookup up port right
- ourselves. Remove function pager_clean (now in clean.c).
- * priv.h (_pager_class): New var.
- (_pager_clean, _pager_real_dropweak): New decls.
- * Makefile (COBJS): Delete reference.o. Add clean.o and dropweak.o
- (OBJS): Add notifyServer.o.
- (demuxer.o): Depend on notify_S.h.
- * demuxer.c: Include "notify_S.h".
- (pager_demuxer): Declare and use _pager_seqnos_notify_server.
- * pager.h: Include <hurd/ports.h>.
- (pager_no_senders, pager_reference, pager_unreference,
- pager_port_type, pager_clean): Remove declarations.
- (pager_create): New parm BUCKET.
- (pager_clean): Doc fix.
- (pager_dropweak): New decl.
- * reference.c: Deleted file.
-
-Thu May 11 11:19:44 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
-
- * priv.h (PM_NEXTERROR, SET_PM_NEXTERROR): Mask 2-bit error code
- with 0x3, not 0x2!
-
- * mark-error.c (_pager_mark_next_request_error,
- _pager_mark_object_error): Put the error code in the correct place
- in the pagemap rather than always at the beginning.
- (pager_get_error): Get the error code from the pagemap rather than
- just using the pagemap offset!
-
-Wed Nov 23 00:28:19 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
-
- * demuxer.c (pager_demuxer): Call
- _pager_seqnos_memory_object_server, not
- seqnos_memory_object_server.
-
-Tue Nov 8 14:15:01 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * lock-object.c (_pager_lock_object): Hammer SYNC to zero for now;
- there's some deadlock bug in noticing when the sync finishes.
-
-Tue Aug 30 17:55:34 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * data-return.c: Include <assert.h>.
- (_pager_seqnos_memory_object_data_return): Use return correctly.
-
-Mon Aug 29 17:30:52 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * priv.h (PM_INIT): New pagemap bit.
- * data-return.c (_pager_do_write-request): Set PM_INIT for
- affected pages. New var `omitdata' hold a bitmap of the
- pages that we are not actually writing. Set accordingly
- while looking through pagemap before starting I/O. Don't
- actually call I/O on these pages or frob the page map with them
- later.
-
- * data-return.c (_pager_seqnos_memory_object_data_return): Split
- into two functions; _pager_do_write_request does the real work
- now.
-
- * object-create.c: New file.
- * data-init.c: New file.
-
-Fri Jul 22 11:54:05 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu>
-
- * Makefile: Rewritten to use new scheme.
- * data-request.c: Include "memory_object_S.h" instead of
- "memory_object.h".
- * data-return.c: Likewise.
- * data-unlock.c: Likewise.
- * lock-completed: Likewise.
- * stubs.c: Likewise.
- * object-init.c: Likewise.
- * demuxer.c: Likewise.
- * object-terminate.c: Likewise.
-
-Tue Jul 5 14:14:17 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * Makefile (TAGSHDRS): New variable.
-
-Wed Jun 1 11:41:24 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * pager-attr.c (pager_change_attributes): Return immediately
- if we are already in the requested state.
-
- * lock-completed.c (_pager_seqnos_memory_object_lock_completed):
- Call ports_done_with_port before returning to free reference
- created by ports_check_port_type.
- * chg-compl.c (_pager_seqnos_memory_object_change_completed):
- Likewise.
-
- * seqnos.c (_pager_release_seqno): New second arg SEQNO.
- Set p->seqno here. All callers changed.
- (_pager_wait_for_seqno): Don't set p->seqno here; then it
- might get released before we actually call _pager_release_seqno.
- * priv.h (_pager_release_seqno): Declare new second arg.
-
- * priv.h (KERNEL_INIT_RACE): New compilation option. All the
- changes in this block are conditionalized by this macro.
- * priv.h (struct pager): New members init_head and init_tail.
- (struct pending_init): New type.
- * object-init.c (_pager_seqnos_memory_object_init): If the object
- is not ready for init, then queue the init for later processing.
- * object-terminate.c (_pager_seqnos_memory_object_terminate): If
- there is a pending init, return it here.
- * no-senders.c (pager_clean): Destroy all pending inits here.
-
- * object-terminate.c (_pager_free_structure): Don't unlock
- interlock or free the seqno here.
- (_pager_seqnos_memory_object_terminate): Unlock interlock and
- free seqno after calling _pager_free_structure.
- * no-senders.c (pager_clean): Unlock interlock after calling
- _pager_free_structure. Don't free seqno here at all.
-
-Tue May 24 15:25:54 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * data-return.c (_pager_seqnos_memory_object_data_return): New
- vars NPAGES, I, and PAGERRS. Rename var PM_ENTRY to be
- PM_ENTRIES. Deal with multiple-page data_return calls by dealing
- with multiple pagemap slots and calling pager_write_page multiple
- times.
-
- * data-return.c (_pager_seqnos_memory_object_data_return): Fix
- printf messages; include length in bogus length messages.
-
- *data-unlock (_pager_seqnos_memory_object_data_unlock): Likewise.
-
-Mon May 23 13:06:31 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
-
- * data-request.c (_pager_seqnos_memory_object_data_request):
- Report length in bogus arg messages; terminate messages with
- newlines.
-
- * chg-compl.c: Include <stdio.h>.
-
- * priv.h (struct pager [may_cache, copy_strategy]): New members.
- * pager.h (pager_create_pager): Added new args MAY_CACHE and
- COPY_STRATEGY.
- (pager_report_attributes): Deleted declaration.
- * object-init.c (_pager_seqnos_memory_object_init): Set attributes
- from values in P rather than by calling pager_report_attributes.
- * pager-attr.c (pager_change_attributes): Don't panic if the
- pager isn't yet initialized by the kernel; record the provided
- values in may_cache and copy_strategy.
-
- * pager-attr.c: Spelling fix.
- Include <assert.h>.
- * Makefile (COBJS): Added pager-attr.o.
-
-Fri May 20 15:41:12 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * lock-completed.c (_pager_seqnos_memory_object_lock_completed):
- Delete unneeded variable wakeup. Break out of loop as soon
- as we find the right record. Call condition_broadcast only
- if we need bother.
-
- * pager.h (pager_change_attributes, pager_report_attributes):
- New declarations.
- * priv.h (struct attribute_request): New structure.
- (struct pager [attribute_requests]): New member.
- * pager-create.c (pager_create): Initialize new member.
- * object-init.c (_pager_seqnos_memory_object_init): Call
- pager_report_attributes for correct args to memory_object_ready.
- * pager-attr.c: New file.
- * object-terminate.c (_pager_free_structure): Wakeup pending
- pager_change_attribute requests.
- * stubs.c (_pager_seqnos_memory_object_change_completed): Deleted
- function.
- * chg-compl.c: New file.
- * Makefile (COBJS): Added chg-compl.o.
-
-Thu May 5 07:49:21 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
-
- * stubs.c (_pager_seqnos_memory_object_supply_completed): Change
- RESULT arg to type kern_return_t; error_t is not compatible.
-
- * demuxer.c (pager_demuxer): Declare seqnos_memory_object_server.
-
- * stubs.c, lock-completed.c: Changed return type of all RPC server
- functions to kern_return_t. error_t is not compatible with the
- declarations in the mig-generated header files.
-
- * Makefile: Change uses of $(headers) to $(includedir).
-
-Tue Apr 26 15:08:57 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
-
- * object-init.c (_pager_seqnos_memory_object_init): Only check
- for inits of active objects AFTER waiting for seqno; otherwise we
- could race against a prior terminate.
-
diff --git a/libpager/Makefile b/libpager/Makefile
index f8c0999a..fc23364a 100644
--- a/libpager/Makefile
+++ b/libpager/Makefile
@@ -29,6 +29,7 @@ SRCS = data-request.c data-return.c data-unlock.c pager-port.c \
LCLHDRS = pager.h priv.h
installhdrs = pager.h
+HURDLIBS= threads ports
OBJS = $(SRCS:.c=.o) memory_objectServer.o notifyServer.o
MIGSFLAGS = -DSEQNOS
@@ -36,5 +37,3 @@ MIGCOMSFLAGS = -prefix _pager_
include ../Makeconf
-libpager.so: $(foreach lib,threads ports,\
- ../lib$(lib)/lib$(lib).so)
diff --git a/libpager/data-init.c b/libpager/data-init.c
deleted file mode 100644
index f411a938..00000000
--- a/libpager/data-init.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Initial contents of memory object (default pager only)
- Copyright (C) 1994 Free Software Foundation, Inc.
- Written by Michael I. Bushnell.
-
- This file is part of the GNU Hurd.
-
- The GNU Hurd is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- The GNU Hurd 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
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "priv.h"
-#include "memory_object_default_S.h"
-
-kern_return_t
-_pager_seqnos_memory_object_data_initialize (mach_port_t object,
- mach_port_seqno_t seqno,
- mach_port_t control,
- vm_offset_t offset,
- pointer_t data,
- vm_size_t datalen)
-{
- _pager_do_write_request (object, seqno, control, offset, data,
- datalen, 1, 0, 1);
-}
diff --git a/libpager/data-request.c b/libpager/data-request.c
index 341fb924..36725b11 100644
--- a/libpager/data-request.c
+++ b/libpager/data-request.c
@@ -1,5 +1,5 @@
/* Implementation of memory_object_data_request for pager library
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1994,95,96,97,2000,02,10 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -22,7 +22,7 @@
/* Implement pagein callback as described in <mach/memory_object.defs>. */
kern_return_t
-_pager_seqnos_memory_object_data_request (mach_port_t object,
+_pager_seqnos_memory_object_data_request (mach_port_t object,
mach_port_seqno_t seqno,
mach_port_t control,
vm_offset_t offset,
@@ -30,7 +30,7 @@ _pager_seqnos_memory_object_data_request (mach_port_t object,
vm_prot_t access)
{
struct pager *p;
- char *pm_entry;
+ short *pm_entry;
int doread, doerror;
error_t err;
vm_address_t page;
@@ -43,7 +43,7 @@ _pager_seqnos_memory_object_data_request (mach_port_t object,
/* Acquire the right to meddle with the pagemap */
mutex_lock (&p->interlock);
_pager_wait_for_seqno (p, seqno);
-
+
/* sanity checks -- we don't do multi-page requests yet. */
if (control != p->memobjcntl)
{
@@ -52,7 +52,7 @@ _pager_seqnos_memory_object_data_request (mach_port_t object,
}
if (length != __vm_page_size)
{
- printf ("incg data request: bad length size %d\n", length);
+ printf ("incg data request: bad length size %zd\n", length);
goto release_out;
}
if (offset % __vm_page_size)
@@ -61,18 +61,18 @@ _pager_seqnos_memory_object_data_request (mach_port_t object,
goto release_out;
}
- _pager_block_termination (p); /* prevent termination until
+ _pager_block_termination (p); /* prevent termination until
mark_object_error is done */
if (p->pager_state != NORMAL)
{
printf ("pager in wrong state for read\n");
- _pager_release_seqno (p, seqno);
- mutex_unlock (&p->interlock);
- goto allow_term_out;
+ goto allow_release_out;
}
- _pager_pagemap_resize (p, offset + length);
+ err = _pager_pagemap_resize (p, offset + length);
+ if (err)
+ goto allow_release_out; /* Can't do much about the actual error. */
/* If someone is paging this out right now, the disk contents are
unreliable, so we have to wait. It is too expensive (right now) to
@@ -97,9 +97,9 @@ _pager_seqnos_memory_object_data_request (mach_port_t object,
if (PM_NEXTERROR (*pm_entry) != PAGE_NOERR && (access & VM_PROT_WRITE))
{
- memory_object_data_error (control, offset, length,
+ memory_object_data_error (control, offset, length,
_pager_page_errors[PM_NEXTERROR (*pm_entry)]);
- _pager_mark_object_error (p, offset, length,
+ _pager_mark_object_error (p, offset, length,
_pager_page_errors[PM_NEXTERROR (*pm_entry)]);
*pm_entry = SET_PM_NEXTERROR (*pm_entry, PAGE_NOERR);
doread = 0;
@@ -117,7 +117,7 @@ _pager_seqnos_memory_object_data_request (mach_port_t object,
err = pager_read_page (p->upi, offset, &page, &write_lock);
if (err)
goto error_read;
-
+
memory_object_data_supply (p->memobjcntl, offset, page, length, 1,
write_lock ? VM_PROT_WRITE : VM_PROT_NONE, 0,
MACH_PORT_NULL);
@@ -128,20 +128,18 @@ _pager_seqnos_memory_object_data_request (mach_port_t object,
ports_port_deref (p);
return 0;
- allow_term_out:
- mutex_lock (&p->interlock);
- _pager_allow_termination (p);
- mutex_unlock (&p->interlock);
- ports_port_deref (p);
- return 0;
-
error_read:
memory_object_data_error (p->memobjcntl, offset, length, EIO);
_pager_mark_object_error (p, offset, length, EIO);
+ allow_term_out:
+ mutex_lock (&p->interlock);
_pager_allow_termination (p);
+ mutex_unlock (&p->interlock);
ports_port_deref (p);
return 0;
+ allow_release_out:
+ _pager_allow_termination (p);
release_out:
_pager_release_seqno (p, seqno);
mutex_unlock (&p->interlock);
diff --git a/libpager/data-return.c b/libpager/data-return.c
index 562af955..a010c6dc 100644
--- a/libpager/data-return.c
+++ b/libpager/data-return.c
@@ -1,5 +1,5 @@
/* Implementation of memory_object_data_return for pager library
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1994,95,96,99,2000,02 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -37,7 +37,7 @@ _pager_do_write_request (mach_port_t object,
int initializing)
{
struct pager *p;
- char *pm_entries;
+ short *pm_entries;
int npages, i;
error_t *pagerrs;
struct lock_request *lr;
@@ -45,7 +45,7 @@ _pager_do_write_request (mach_port_t object,
struct lock_list *next;} *lock_list, *ll;
int wakeup;
int omitdata = 0;
-
+
p = ports_lookup_port (0, object, _pager_class);
if (!p)
return EOPNOTSUPP;
@@ -53,7 +53,7 @@ _pager_do_write_request (mach_port_t object,
/* Acquire the right to meddle with the pagemap */
mutex_lock (&p->interlock);
_pager_wait_for_seqno (p, seqno);
-
+
/* sanity checks -- we don't do multi-page requests yet. */
if (control != p->memobjcntl)
{
@@ -62,7 +62,7 @@ _pager_do_write_request (mach_port_t object,
}
if (length % __vm_page_size)
{
- printf ("incg data return: bad length size %d\n", length);
+ printf ("incg data return: bad length size %zd\n", length);
goto release_out;
}
if (offset % __vm_page_size)
@@ -90,8 +90,21 @@ _pager_do_write_request (mach_port_t object,
pm_entries = &p->pagemap[offset / __vm_page_size];
+ /* Make sure there are no other in-progress writes for any of these
+ pages before we begin. This imposes a little more serialization
+ than we really have to require (because *all* future writes on
+ this object are going to wait for seqno while we wait for the
+ previous write), but the case is relatively infrequent. */
+ retry:
+ for (i = 0; i < npages; i++)
+ if (pm_entries[i] & PM_PAGINGOUT)
+ {
+ pm_entries[i] |= PM_WRITEWAIT;
+ condition_wait (&p->wakeup, &p->interlock);
+ goto retry;
+ }
+
/* Mark these pages as being paged out. */
-#if 0
if (initializing)
{
assert (npages <= 32);
@@ -106,13 +119,10 @@ _pager_do_write_request (mach_port_t object,
else
for (i = 0; i < npages; i++)
pm_entries[i] |= PM_PAGINGOUT | PM_INIT;
-#else
- for (i = 0; i < npages; i++)
- pm_entries[i] |= PM_PAGINGOUT;
+
if (!kcopy)
for (i = 0; i < npages; i++)
pm_entries[i] &= ~PM_INCORE;
-#endif
/* If this write occurs while a lock is pending, record
it. We have to keep this list because a lock request
@@ -140,8 +150,8 @@ _pager_do_write_request (mach_port_t object,
for (i = 0; i < npages; i++)
if (!(omitdata & (1 << i)))
- pagerrs[i] = pager_write_page (p->upi,
- offset + (vm_page_size * i),
+ pagerrs[i] = pager_write_page (p->upi,
+ offset + (vm_page_size * i),
data + (vm_page_size * i));
/* Acquire the right to meddle with the pagemap */
@@ -149,11 +159,15 @@ _pager_do_write_request (mach_port_t object,
_pager_pagemap_resize (p, offset + length);
pm_entries = &p->pagemap[offset / __vm_page_size];
+ wakeup = 0;
for (i = 0; i < npages; i++)
{
if (omitdata & (1 << i))
continue;
-
+
+ if (pm_entries[i] & PM_WRITEWAIT)
+ wakeup = 1;
+
if (pagerrs[i] && ! (pm_entries[i] & PM_PAGEINWAIT))
/* The only thing we can do here is mark the page, and give
errors from now on when it is to be read. This is
@@ -165,23 +179,22 @@ _pager_do_write_request (mach_port_t object,
pm_entries[i] |= PM_INVALID;
if (pm_entries[i] & PM_PAGEINWAIT)
- memory_object_data_supply (p->memobjcntl,
- offset + (vm_page_size * i),
- data + (vm_page_size * i),
+ memory_object_data_supply (p->memobjcntl,
+ offset + (vm_page_size * i),
+ data + (vm_page_size * i),
vm_page_size, 1,
VM_PROT_NONE, 0, MACH_PORT_NULL);
else
- vm_deallocate (mach_task_self (),
- data + (vm_page_size * i),
- vm_page_size);
+ munmap ((caddr_t) (data + (vm_page_size * i)),
+ vm_page_size);
- pm_entries[i] &= ~(PM_PAGINGOUT | PM_PAGEINWAIT);
+ pm_entries[i] &= ~(PM_PAGINGOUT | PM_PAGEINWAIT | PM_WRITEWAIT);
}
- wakeup = 0;
for (ll = lock_list; ll; ll = ll->next)
if (!--ll->lr->pending_writes && !ll->lr->locks_pending)
wakeup = 1;
+
if (wakeup)
condition_broadcast (&p->wakeup);
@@ -201,7 +214,7 @@ _pager_do_write_request (mach_port_t object,
/* Implement pageout call back as described by <mach/memory_object.defs>. */
kern_return_t
-_pager_seqnos_memory_object_data_return (mach_port_t object,
+_pager_seqnos_memory_object_data_return (mach_port_t object,
mach_port_seqno_t seqno,
mach_port_t control,
vm_offset_t offset,
diff --git a/libpager/data-unlock.c b/libpager/data-unlock.c
index a4ef0600..9692f589 100644
--- a/libpager/data-unlock.c
+++ b/libpager/data-unlock.c
@@ -1,5 +1,5 @@
/* Implementation of memory_object_data_unlock for pager library
- Copyright (C) 1994, 1995 Free Software Foundation
+ Copyright (C) 1994,95,2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -19,10 +19,10 @@
#include "memory_object_S.h"
#include <stdio.h>
-/* Implement kernel requests for access as described in
+/* Implement kernel requests for access as described in
<mach/memory_object.defs>. */
kern_return_t
-_pager_seqnos_memory_object_data_unlock (mach_port_t object,
+_pager_seqnos_memory_object_data_unlock (mach_port_t object,
mach_port_seqno_t seqno,
mach_port_t control,
vm_offset_t offset,
@@ -31,7 +31,7 @@ _pager_seqnos_memory_object_data_unlock (mach_port_t object,
{
struct pager *p;
volatile int err;
-
+
p = ports_lookup_port (0, object, _pager_class);
if (!p)
return EOPNOTSUPP;
@@ -65,12 +65,12 @@ _pager_seqnos_memory_object_data_unlock (mach_port_t object,
}
if (length != __vm_page_size)
{
- printf ("incg data unlock: bad length size %d\n", length);
+ printf ("incg data unlock: bad length size %zd\n", length);
goto out;
}
err = pager_unlock_page (p->upi, offset);
-
+
if (!err)
/* We can go ahead and release the lock. */
_pager_lock_object (p, offset, length, MEMORY_OBJECT_RETURN_NONE, 0,
@@ -87,4 +87,3 @@ _pager_seqnos_memory_object_data_unlock (mach_port_t object,
ports_port_deref (p);
return 0;
}
-
diff --git a/libpager/demuxer.c b/libpager/demuxer.c
index f233d1c0..79c0ddc5 100644
--- a/libpager/demuxer.c
+++ b/libpager/demuxer.c
@@ -1,5 +1,5 @@
/* Demuxer for pager library
- Copyright (C) 1994, 1995 Free Software Foundation
+ Copyright (C) 1994, 1995, 2002, 2011 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -20,7 +20,7 @@
#include "notify_S.h"
/* Demultiplex a single message directed at a pager port; INP is the
- message received; fille OUTP with the reply. */
+ message received; fill OUTP with the reply. */
int
pager_demuxer (mach_msg_header_t *inp,
mach_msg_header_t *outp)
@@ -29,8 +29,12 @@ pager_demuxer (mach_msg_header_t *inp,
mach_msg_header_t *outp);
extern int _pager_seqnos_notify_server (mach_msg_header_t *inp,
mach_msg_header_t *outp);
-
- return (_pager_seqnos_memory_object_server (inp, outp)
- || _pager_seqnos_notify_server (inp, outp));
-}
+ int result = _pager_seqnos_memory_object_server (inp, outp)
+ || _pager_seqnos_notify_server (inp, outp);
+ if (!result)
+ /* Synchronize our bookkeeping of the port's seqno with the one consumed by
+ this bogus message. */
+ _pager_update_seqno (inp->msgh_local_port, inp->msgh_seqno);
+ return result;
+}
diff --git a/libpager/lock-object.c b/libpager/lock-object.c
index d2f6da6d..d108666e 100644
--- a/libpager/lock-object.c
+++ b/libpager/lock-object.c
@@ -1,5 +1,5 @@
/* Synchronous wrapper for memory_object_lock_request
- Copyright (C) 1993, 1994, 1996 Free Software Foundation
+ Copyright (C) 1993, 1994, 1996, 1997, 2000 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -30,9 +30,8 @@ _pager_lock_object (struct pager *p,
vm_prot_t lock_value,
int sync)
{
- struct lock_request *lr = 0;
- char *pm_entries;
int i;
+ struct lock_request *lr = 0;
mutex_lock (&p->interlock);
if (p->pager_state != NORMAL)
@@ -85,10 +84,20 @@ _pager_lock_object (struct pager *p,
if (should_flush)
{
+ vm_offset_t pm_offs = offset / __vm_page_size;
+
_pager_pagemap_resize (p, offset + size);
- pm_entries = &p->pagemap[offset / __vm_page_size];
- for (i = 0; i < size / vm_page_size; i++)
- pm_entries[i] &= ~PM_INCORE;
+ if (p->pagemapsize > pm_offs)
+ {
+ short *pm_entries = &p->pagemap[pm_offs];
+ vm_offset_t bound = size / vm_page_size;
+
+ if (bound > p->pagemapsize)
+ bound = p->pagemapsize;
+
+ for (i = 0; i < bound; i++)
+ pm_entries[i] &= ~PM_INCORE;
+ }
}
}
diff --git a/libpager/mark-error.c b/libpager/mark-error.c
index 411d3a7d..5c4e029d 100644
--- a/libpager/mark-error.c
+++ b/libpager/mark-error.c
@@ -1,5 +1,5 @@
/* Recording errors for pager library
- Copyright (C) 1994 Free Software Foundation
+ Copyright (C) 1994, 1997 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -32,7 +32,7 @@ _pager_mark_next_request_error(struct pager *pager,
error_t error)
{
int page_error;
- char *p;
+ short *p;
offset /= __vm_page_size;
length /= __vm_page_size;
@@ -70,7 +70,7 @@ _pager_mark_object_error(struct pager *pager,
error_t error)
{
int page_error = 0;
- char *p;
+ short *p;
offset /= __vm_page_size;
length /= __vm_page_size;
@@ -99,16 +99,24 @@ _pager_mark_object_error(struct pager *pager,
/* Tell us what the error (set with mark_object_error) for
pager P is on page ADDR. */
error_t
-pager_get_error (struct pager *p,
- vm_address_t addr)
+pager_get_error (struct pager *p, vm_address_t addr)
{
error_t err;
mutex_lock (&p->interlock);
- _pager_pagemap_resize (p, addr);
-
- err = _pager_page_errors[PM_ERROR(p->pagemap[addr/__vm_page_size])];
+
+ addr /= vm_page_size;
+
+ /* If there really is no error for ADDR, we should be able to exted the
+ pagemap table; otherwise, if some previous operation failed because it
+ couldn't extend the table, this attempt will *probably* (heh) fail for
+ the same reason. */
+ err = _pager_pagemap_resize (p, addr);
+
+ if (! err)
+ err = _pager_page_errors[PM_ERROR(p->pagemap[addr])];
mutex_unlock (&p->interlock);
+
return err;
}
diff --git a/libpager/notify-stubs.c b/libpager/notify-stubs.c
index 728163e4..2d791aac 100644
--- a/libpager/notify-stubs.c
+++ b/libpager/notify-stubs.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2011 Free Software Foundation, Inc.
Written by Michael I. Bushnell.
This file is part of the GNU Hurd.
@@ -18,58 +18,59 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+#include "priv.h"
#include "notify_S.h"
#include <errno.h>
error_t
-_pager_do_seqnos_mach_notify_port_deleted (mach_port_t notify
- __attribute__ ((unused)),
- mach_port_seqno_t seqno
- __attribute__ ((unused)),
+_pager_do_seqnos_mach_notify_port_deleted (mach_port_t notify,
+ mach_port_seqno_t seqno,
mach_port_t name
__attribute__ ((unused)))
{
+ _pager_update_seqno (notify, seqno);
+
return 0;
}
error_t
-_pager_do_seqnos_mach_notify_msg_accepted (mach_port_t notify
- __attribute__ ((unused)),
- mach_port_seqno_t seqno
- __attribute__ ((unused)),
+_pager_do_seqnos_mach_notify_msg_accepted (mach_port_t notify,
+ mach_port_seqno_t seqno,
mach_port_t name
__attribute__ ((unused)))
{
+ _pager_update_seqno (notify, seqno);
+
return 0;
}
error_t
-_pager_do_seqnos_mach_notify_port_destroyed (mach_port_t notify
- __attribute__ ((unused)),
- mach_port_seqno_t seqno
- __attribute__ ((unused)),
+_pager_do_seqnos_mach_notify_port_destroyed (mach_port_t notify,
+ mach_port_seqno_t seqno,
mach_port_t name
__attribute__ ((unused)))
{
+ _pager_update_seqno (notify, seqno);
+
return 0;
}
error_t
-_pager_do_seqnos_mach_notify_send_once (mach_port_t notify
- __attribute__ ((unused)),
- mach_port_seqno_t seqno
- __attribute__ ((unused)))
+_pager_do_seqnos_mach_notify_send_once (mach_port_t notify,
+ mach_port_seqno_t seqno)
{
+ _pager_update_seqno (notify, seqno);
+
return 0;
}
error_t
-_pager_do_seqnos_mach_notify_dead_name (mach_port_t notify
- __attribute__ ((unused)),
- mach_port_seqno_t seqno
- __attribute__ ((unused)),
+_pager_do_seqnos_mach_notify_dead_name (mach_port_t notify,
+ mach_port_seqno_t seqno,
mach_port_t name
__attribute__ ((unused)))
{
+ _pager_update_seqno (notify, seqno);
+
return 0;
}
diff --git a/libpager/object-create.c b/libpager/object-create.c
deleted file mode 100644
index c8dfe6de..00000000
--- a/libpager/object-create.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Create a new memory object (Default pager only)
- Copyright (C) 1994, 1995 Free Software Foundation, Inc.
- Written by Michael I. Bushnell.
-
- This file is part of the GNU Hurd.
-
- The GNU Hurd is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- The GNU Hurd 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
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-
-#include "priv.h"
-#include "memory_object_create_S.h"
-
-/* Implement the object creation call as described in
- <mach/memory_object_default.defs>. */
-kern_return_t
-_pager_seqnos_memory_object_create (mach_port_t master,
- mach_port_seqno_t seqno,
- mach_port_t newobject,
- vm_size_t objectsize,
- mach_port_t newctl,
- mach_port_t newname,
- vm_size_t objectpagesize)
-{
- struct port_info *masterpi;
- struct pager *p;
-
- if (!pager_support_defpager)
- return EOPNOTSUPP;
-
- if (objectpagesize != vm_page_size)
- return EINVAL;
-
- masterpi = ports_check_port_type (object, pager_master_port_type);
- if (!masterpi)
- return EOPNOTSUPP;
-
- p = ports_intern_external_port (newobject, sizeof (struct pager),
- pager_port_type);
-
- p->pager_state = NORMAL;
- mutex_init (&p->interlock);
- condition_init (&p->wakeup);
- p->lock_requests = 0;
- p->attribute_requests = 0;
- p->may_cache = 0;
- p->copy_strategy = MEMORY_OBJECT_COPY_DELAY;
- p->memobjcntl = newctl;
- p->memobjname = newname;
- p->seqno = -1;
- p->noterm = 0;
- p->waitingforseqno = 0;
- p->pagemap = 0;
- p->pagemapsize = 0;
-
- p->upi = pager_create_upi (p);
-
- ports_port_deref (p);
- return 0;
-}
-
-
diff --git a/libpager/object-terminate.c b/libpager/object-terminate.c
index 8598ab50..dc53541c 100644
--- a/libpager/object-terminate.c
+++ b/libpager/object-terminate.c
@@ -1,5 +1,5 @@
/* Implementation of memory_object_terminate for pager library
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1994, 1995, 1996, 1999, 2000 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -53,6 +53,12 @@ _pager_seqnos_memory_object_terminate (mach_port_t object,
condition_wait (&p->wakeup, &p->interlock);
}
+ /* Destry the ports we received; mark that in P so that it doesn't bother
+ doing it again. */
+ mach_port_destroy (mach_task_self (), control);
+ mach_port_destroy (mach_task_self (), name);
+ p->memobjcntl = p->memobjname = MACH_PORT_NULL;
+
_pager_free_structure (p);
#ifdef KERNEL_INIT_RACE
@@ -104,13 +110,21 @@ _pager_free_structure (struct pager *p)
if (wakeup)
condition_broadcast (&p->wakeup);
- mach_port_deallocate (mach_task_self (), p->memobjcntl);
- mach_port_deallocate (mach_task_self (), p->memobjname);
+ if (p->memobjcntl != MACH_PORT_NULL)
+ {
+ mach_port_deallocate (mach_task_self (), p->memobjcntl);
+ p->memobjcntl = MACH_PORT_NULL;
+ }
+ if (p->memobjname != MACH_PORT_NULL)
+ {
+ mach_port_deallocate (mach_task_self (), p->memobjname);
+ p->memobjname = MACH_PORT_NULL;
+ }
/* Free the pagemap */
if (p->pagemapsize)
{
- vm_deallocate (mach_task_self (), (u_int)p->pagemap, p->pagemapsize);
+ munmap (p->pagemap, p->pagemapsize * sizeof (* p->pagemap));
p->pagemapsize = 0;
p->pagemap = 0;
}
diff --git a/libpager/offer-page.c b/libpager/offer-page.c
index fe08d3b4..aed22197 100644
--- a/libpager/offer-page.c
+++ b/libpager/offer-page.c
@@ -1,5 +1,5 @@
/* Wrapper for unsolicited memory_object_data_supply
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
Written by Michael I. Bushnell, p/BSG.
This file is part of the GNU Hurd.
@@ -28,23 +28,25 @@ pager_offer_page (struct pager *p,
vm_offset_t offset,
vm_address_t buf)
{
- char *pm_entry;
-
- try_again:
mutex_lock (&p->interlock);
- _pager_pagemap_resize (p, offset + vm_page_size);
- pm_entry = &p->pagemap[offset / vm_page_size];
- if (*pm_entry & PM_INCORE)
+
+ if (_pager_pagemap_resize (p, offset + vm_page_size))
{
- mutex_unlock (&p->interlock);
- pager_flush_some (p, offset, vm_page_size, 1);
- goto try_again;
+ short *pm_entry = &p->pagemap[offset / vm_page_size];
+
+ while (*pm_entry & PM_INCORE)
+ {
+ mutex_unlock (&p->interlock);
+ pager_flush_some (p, offset, vm_page_size, 1);
+ mutex_lock (&p->interlock);
+ }
+ *pm_entry |= PM_INCORE;
+
+ memory_object_data_supply (p->memobjcntl, offset, buf, vm_page_size, 0,
+ writelock ? VM_PROT_WRITE : VM_PROT_NONE,
+ precious, MACH_PORT_NULL);
}
- *pm_entry |= PM_INCORE;
- memory_object_data_supply (p->memobjcntl, offset, buf, vm_page_size, 0,
- writelock ? VM_PROT_WRITE : VM_PROT_NONE,
- precious, MACH_PORT_NULL);
mutex_unlock (&p->interlock);
}
diff --git a/libpager/pagemap.c b/libpager/pagemap.c
index 2adbcc0e..b8b3362c 100644
--- a/libpager/pagemap.c
+++ b/libpager/pagemap.c
@@ -1,5 +1,5 @@
/* Pagemap manipulation for pager library
- Copyright (C) 1994 Free Software Foundation
+ Copyright (C) 1994, 1997, 1999, 2000 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -19,21 +19,29 @@
#include <string.h>
/* Grow the pagemap of pager P as necessary to deal with address OFF */
-void
-_pager_pagemap_resize (struct pager *p,
- vm_address_t off)
+error_t
+_pager_pagemap_resize (struct pager *p, vm_address_t off)
{
- void *newaddr;
- int newsize;
+ error_t err = 0;
off /= __vm_page_size;
- if (p->pagemapsize >= off)
- return;
-
- newsize = round_page (off);
- vm_allocate (mach_task_self (), (u_int *)&newaddr, newsize, 1);
- bcopy (p->pagemap, newaddr, p->pagemapsize);
- vm_deallocate (mach_task_self (), (u_int)p->pagemap, p->pagemapsize);
- p->pagemap = newaddr;
- p->pagemapsize = newsize;
+
+ if (p->pagemapsize < off)
+ {
+ void *newaddr;
+ int newsize = round_page (off);
+
+ newaddr = mmap (0, newsize * sizeof (*p->pagemap),
+ PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
+ err = (newaddr == (void *) -1) ? errno : 0;
+ if (! err)
+ {
+ bcopy (p->pagemap, newaddr, p->pagemapsize * sizeof (*p->pagemap));
+ munmap (p->pagemap, p->pagemapsize * sizeof (*p->pagemap));
+ p->pagemap = newaddr;
+ p->pagemapsize = newsize;
+ }
+ }
+
+ return err;
}
diff --git a/libpager/pager-memcpy.c b/libpager/pager-memcpy.c
index 0333c805..f2be5585 100644
--- a/libpager/pager-memcpy.c
+++ b/libpager/pager-memcpy.c
@@ -1,5 +1,5 @@
/* Fault-safe copy into or out of pager-backed memory.
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996,97,99, 2000,01,02 Free Software Foundation, Inc.
Written by Roland McGrath.
This program is free software; you can redistribute it and/or
@@ -16,9 +16,17 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#include "priv.h"
#include "pager.h"
+#include <sys/mman.h>
#include <hurd/sigpreempt.h>
#include <assert.h>
+#include <string.h>
+
+/* Start using vm_copy over memcpy when we have that many page. This is
+ roughly the L1 cache size. (This value *cannot* be less than
+ vm_page_size.) */
+#define VMCOPY_BETTER_THAN_MEMCPY (8*vm_page_size)
/* Try to copy *SIZE bytes between the region OTHER points to
and the region at OFFSET in the pager indicated by PAGER and MEMOBJ.
@@ -27,55 +35,136 @@
*SIZE is always filled in the actual number of bytes successfully copied.
Returns an error code if the pager-backed memory faults;
if there is no fault, returns 0 and *SIZE will be unchanged. */
-
error_t
pager_memcpy (struct pager *pager, memory_object_t memobj,
vm_offset_t offset, void *other, size_t *size,
vm_prot_t prot)
{
- vm_address_t window = 0;
- vm_size_t windowsize = 8 * vm_page_size;
- size_t to_copy = *size;
error_t err;
+ size_t n = *size;
- error_t copy (struct hurd_signal_preempter *preempter)
+#define VMCOPY_WINDOW_DEFAULT_SIZE (32 * vm_page_size)
+#define MEMCPY_WINDOW_DEFAULT_SIZE (32 * vm_page_size)
+ vm_address_t window;
+ vm_size_t window_size;
+
+ error_t do_vm_copy (void)
{
- while (to_copy > 0)
- {
- size_t pageoff = offset & (vm_page_size - 1);
+ assert ((offset & (vm_page_size - 1)) == 0);
+ assert (((vm_address_t) other & (vm_page_size - 1)) == 0);
+ assert (n >= vm_page_size);
- if (window)
- /* Deallocate the old window. */
- vm_deallocate (mach_task_self (), window, windowsize);
+ do
+ {
+ window_size =
+ VMCOPY_WINDOW_DEFAULT_SIZE > n
+ ? (n - (n & (vm_page_size - 1)))
+ : VMCOPY_WINDOW_DEFAULT_SIZE;
+
+ assert (window_size >= VMCOPY_BETTER_THAN_MEMCPY);
+ assert ((window_size & (vm_page_size - 1)) == 0);
+
+ err = vm_map (mach_task_self (), &window, window_size, 0, 1,
+ memobj, offset, 0, prot, prot, VM_INHERIT_NONE);
+ if (err)
+ return err;
- /* Map in and copy a standard-sized window, unless that is
- more than the total left to be copied. */
+ if (prot == VM_PROT_READ)
+ err = vm_copy (mach_task_self (), window, window_size,
+ (vm_address_t) other);
+ else
+ err = vm_copy (mach_task_self (), (vm_address_t) other,
+ window_size, window);
- if (windowsize > pageoff + to_copy)
- windowsize = pageoff + to_copy;
+ vm_deallocate (mach_task_self (), window, window_size);
- window = 0;
- err = vm_map (mach_task_self (), &window, windowsize, 0, 1,
- memobj, offset - pageoff, 0,
- prot, prot, VM_INHERIT_NONE);
if (err)
- return 0;
+ return err;
- /* Realign the fault preempter for the new mapping window. */
- preempter->first = window;
- preempter->last = window + windowsize;
+ other += window_size;
+ offset += window_size;
+ n -= window_size;
+ }
+ while (n >= VMCOPY_BETTER_THAN_MEMCPY);
- if (prot == VM_PROT_READ)
- memcpy (other, (const void *) window + pageoff,
- windowsize - pageoff);
- else
- memcpy ((void *) window + pageoff, other, windowsize - pageoff);
+ return 0;
+ }
- offset += windowsize - pageoff;
- other += windowsize - pageoff;
- to_copy -= windowsize - pageoff;
+ error_t do_copy (struct hurd_signal_preemptor *preemptor)
+ {
+ error_t do_memcpy (size_t to_copy)
+ {
+ window_size = MEMCPY_WINDOW_DEFAULT_SIZE;
+
+ do
+ {
+ size_t pageoff = offset & (vm_page_size - 1);
+ size_t copy_count = window_size - pageoff;
+
+ /* Map in and copy a standard-sized window, unless that is
+ more than the total left to be copied. */
+
+ if (window_size >= round_page (pageoff + to_copy))
+ {
+ copy_count = to_copy;
+ window_size = round_page (pageoff + to_copy);
+ }
+
+ err = vm_map (mach_task_self (), &window, window_size, 0, 1,
+ memobj, offset - pageoff, 0,
+ prot, prot, VM_INHERIT_NONE);
+ if (err)
+ return err;
+
+ /* Realign the fault preemptor for the new mapping window. */
+ preemptor->first = window;
+ preemptor->last = window + window_size;
+
+ if (prot == VM_PROT_READ)
+ memcpy (other, (const void *) window + pageoff, copy_count);
+ else
+ memcpy ((void *) window + pageoff, other, copy_count);
+
+ vm_deallocate (mach_task_self (), window, window_size);
+
+ offset += copy_count;
+ other += copy_count;
+ to_copy -= copy_count;
+ n -= copy_count;
+
+ assert (n >= 0);
+ assert (to_copy >= 0);
+ }
+ while (to_copy > 0);
+
+ return 0;
}
- return 0;
+
+ /* Can we use vm_copy? */
+ if ((((vm_address_t) other & (vm_page_size - 1))
+ == (offset & (vm_page_size - 1)))
+ && (n >= (VMCOPY_BETTER_THAN_MEMCPY + vm_page_size
+ - ((vm_address_t) other & (vm_page_size - 1)))))
+ /* 1) other and offset are aligned with repect to each other;
+ and 2) we have at least VMCOPY_BETTER_THAN_MEMCPY fully
+ aligned pages. */
+ {
+ err = do_memcpy (vm_page_size
+ - ((vm_address_t) other & (vm_page_size - 1)));
+ if (err)
+ return err;
+
+ assert (n >= VMCOPY_BETTER_THAN_MEMCPY);
+
+ err = do_vm_copy ();
+ if (err || n == 0)
+ /* We failed or we finished. */
+ return err;
+
+ assert (n < VMCOPY_BETTER_THAN_MEMCPY);
+ }
+
+ return do_memcpy (n);
}
jmp_buf buf;
@@ -83,19 +172,47 @@ pager_memcpy (struct pager *pager, memory_object_t memobj,
{
assert (scp->sc_error == EKERN_MEMORY_ERROR);
err = pager_get_error (pager, sigcode - window + offset);
- to_copy -= sigcode - window;
+ n -= sigcode - window;
+ vm_deallocate (mach_task_self (), window, window_size);
longjmp (buf, 1);
}
+ if (n == 0)
+ /* Nothing to do. */
+ return 0;
+
+ if (((vm_address_t) other & (vm_page_size - 1)) == 0
+ && (offset & (vm_page_size - 1)) == 0
+ && n >= VMCOPY_BETTER_THAN_MEMCPY)
+ /* 1) the start address is page aligned; 2) the offset is page
+ aligned; and 3) we have more than VMCOPY_BETTER_THAN_MEMCPY
+ pages. */
+ {
+ err = do_vm_copy ();
+ if (err || n == 0)
+ /* We failed or we finished. */
+ {
+ *size -= n;
+ return err;
+ }
+
+ assert (n < VMCOPY_BETTER_THAN_MEMCPY);
+ }
+
+ /* Need to do it the hard way. */
+
+ window = 0;
+ window_size = 0;
+
if (setjmp (buf) == 0)
hurd_catch_signal (sigmask (SIGSEGV) | sigmask (SIGBUS),
- window, window + windowsize,
- &copy, (sighandler_t) &fault);
+ window, window + window_size,
+ &do_copy, (sighandler_t) &fault);
- if (window)
- vm_deallocate (mach_task_self (), window, windowsize);
+ if (! err)
+ assert (n == 0);
- *size -= to_copy;
+ *size -= n;
return err;
}
diff --git a/libpager/pager.h b/libpager/pager.h
index c6bd4971..99fb3845 100644
--- a/libpager/pager.h
+++ b/libpager/pager.h
@@ -1,5 +1,5 @@
/* Definitions for multi-threaded pager library
- Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1994, 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -38,7 +38,7 @@ int pager_demuxer (mach_msg_header_t *inp,
created. MAY_CACHE and COPY_STRATEGY are the original values of
those attributes as for memory_object_ready. Users may create
references to pagers by use of the relevant ports library
- functions. */
+ functions. On errors, return null and set errno. */
struct pager *
pager_create (struct user_pager_info *u_pager,
struct port_bucket *bucket,
@@ -151,7 +151,7 @@ pager_memcpy (struct pager *pager, memory_object_t memobj,
/* The user must define this function. For pager PAGER, read one
page from offset PAGE. Set *BUF to be the address of the page,
and set *WRITE_LOCK if the page must be provided read-only.
- The only permissable error returns are EIO, EDQUOT, and ENOSPC. */
+ The only permissible error returns are EIO, EDQUOT, and ENOSPC. */
error_t
pager_read_page (struct user_pager_info *pager,
vm_offset_t page,
@@ -159,8 +159,8 @@ pager_read_page (struct user_pager_info *pager,
int *write_lock);
/* The user must define this function. For pager PAGER, synchronously
- write one page from BUF to offset PAGE. In addition, vm_deallocate
- (or equivalent) BUF. The only permissable error returns are EIO,
+ write one page from BUF to offset PAGE. In addition, mfree
+ (or equivalent) BUF. The only permissible error returns are EIO,
EDQUOT, and ENOSPC. */
error_t
pager_write_page (struct user_pager_info *pager,
diff --git a/libpager/priv.h b/libpager/priv.h
index 98fca8d4..586bccbf 100644
--- a/libpager/priv.h
+++ b/libpager/priv.h
@@ -1,5 +1,5 @@
/* Private data for pager library.
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1994-1997, 1999, 2000, 2011 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -17,6 +17,7 @@
#include <mach.h>
#include <hurd.h>
+#include <sys/mman.h>
#include "pager.h"
#include <hurd/ports.h>
@@ -35,21 +36,21 @@ struct pager
NORMAL, /* while running */
SHUTDOWN, /* ignore all further requests */
} pager_state;
-
+
struct mutex interlock;
struct condition wakeup;
struct lock_request *lock_requests; /* pending lock requests */
struct attribute_request *attribute_requests; /* pending attr requests */
-
+
boolean_t may_cache;
memory_object_copy_strategy_t copy_strategy;
/* Interface ports */
memory_object_control_t memobjcntl;
memory_object_name_t memobjname;
-
- int seqno;
+
+ mach_port_seqno_t seqno;
int noterm; /* number of threads blocking termination */
@@ -57,15 +58,15 @@ struct pager
int termwaiting:1;
int waitingforseqno:1;
-
+
#ifdef KERNEL_INIT_RACE
/* Out of sequence object_init calls waiting for
terminations. */
struct pending_init *init_head, *init_tail;
#endif
- char *pagemap;
- int pagemapsize;
+ short *pagemap;
+ int pagemapsize; /* number of elements in PAGEMAP */
};
struct lock_request
@@ -107,11 +108,12 @@ extern int _pager_page_errors[];
/* Pagemap format */
/* These are binary state bits */
-/* #define PM_INIT 0x80 data has been written */
-#define PM_INCORE 0x80 /* kernel might have a copy */
-#define PM_PAGINGOUT 0x40 /* being written to disk */
-#define PM_PAGEINWAIT 0x20 /* provide data back when write done */
-#define PM_INVALID 0x10 /* data on disk is irrevocably wrong */
+#define PM_WRITEWAIT 0x0200 /* queue wakeup once write is done */
+#define PM_INIT 0x0100 /* data has been written */
+#define PM_INCORE 0x0080 /* kernel might have a copy */
+#define PM_PAGINGOUT 0x0040 /* being written to disk */
+#define PM_PAGEINWAIT 0x0020 /* provide data back when write done */
+#define PM_INVALID 0x0010 /* data on disk is irrevocably wrong */
/* These take values of enum page_errors */
@@ -129,11 +131,12 @@ extern int _pager_page_errors[];
struct port_class *_pager_class;
-void _pager_wait_for_seqno (struct pager *, int);
-void _pager_release_seqno (struct pager *, int);
+void _pager_wait_for_seqno (struct pager *, mach_port_seqno_t);
+void _pager_release_seqno (struct pager *, mach_port_seqno_t);
+void _pager_update_seqno (mach_port_t, mach_port_seqno_t);
void _pager_block_termination (struct pager *);
void _pager_allow_termination (struct pager *);
-void _pager_pagemap_resize (struct pager *, vm_address_t);
+error_t _pager_pagemap_resize (struct pager *, vm_address_t);
void _pager_mark_next_request_error (struct pager *, vm_address_t,
vm_size_t, error_t);
void _pager_mark_object_error (struct pager *, vm_address_t,
diff --git a/libpager/seqnos.c b/libpager/seqnos.c
index 94cce93b..7d8bcba7 100644
--- a/libpager/seqnos.c
+++ b/libpager/seqnos.c
@@ -1,5 +1,5 @@
/* Sequence number synchronization routines for pager library
- Copyright (C) 1994 Free Software Foundation
+ Copyright (C) 1994, 2011 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -23,7 +23,7 @@
return. */
void
_pager_wait_for_seqno (struct pager *p,
- int seqno)
+ mach_port_seqno_t seqno)
{
while (seqno != p->seqno + 1)
{
@@ -37,7 +37,7 @@ _pager_wait_for_seqno (struct pager *p,
_pager_wait_for_seqno) to be handled. */
void
_pager_release_seqno (struct pager *p,
- int seqno)
+ mach_port_seqno_t seqno)
{
assert (seqno == p->seqno + 1);
p->seqno = seqno;
@@ -47,3 +47,23 @@ _pager_release_seqno (struct pager *p,
condition_broadcast (&p->wakeup);
}
}
+
+
+/* Just update the seqno. */
+void
+_pager_update_seqno (mach_port_t object,
+ mach_port_seqno_t seqno)
+{
+ struct pager *p;
+
+ p = ports_lookup_port (0, object, _pager_class);
+ if (p)
+ {
+ mutex_lock (&p->interlock);
+ _pager_wait_for_seqno (p, seqno);
+ _pager_release_seqno (p, seqno);
+ mutex_unlock (&p->interlock);
+
+ ports_port_deref (p);
+ }
+}
diff --git a/libpager/stubs.c b/libpager/stubs.c
index b455699e..84782120 100644
--- a/libpager/stubs.c
+++ b/libpager/stubs.c
@@ -1,5 +1,5 @@
/* Unused memory object interface stubs
- Copyright (C) 1994 Free Software Foundation
+ Copyright (C) 1994, 2011 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -21,19 +21,22 @@
#include <stdio.h>
kern_return_t
-_pager_seqnos_memory_object_copy (mach_port_t old,
+_pager_seqnos_memory_object_copy (mach_port_t obj,
mach_port_seqno_t seq,
- memory_object_control_t old_ctl,
+ memory_object_control_t obj_ctl,
vm_offset_t off,
vm_size_t len,
mach_port_t new)
{
printf ("m_o_copy called\n");
+
+ _pager_update_seqno (obj, seq);
+
return EOPNOTSUPP;
}
kern_return_t
-_pager_seqnos_memory_object_data_write (mach_port_t old,
+_pager_seqnos_memory_object_data_write (mach_port_t obj,
mach_port_seqno_t seq,
mach_port_t ctl,
vm_offset_t off,
@@ -41,6 +44,9 @@ _pager_seqnos_memory_object_data_write (mach_port_t old,
vm_size_t data_cnt)
{
printf ("m_o_data_write called\n");
+
+ _pager_update_seqno (obj, seq);
+
return EOPNOTSUPP;
}
@@ -54,6 +60,8 @@ _pager_seqnos_memory_object_supply_completed (mach_port_t obj,
vm_offset_t err_off)
{
printf ("m_o_supply_completed called\n");
+
+ _pager_update_seqno (obj, seq);
+
return EOPNOTSUPP;
}
-