diff options
author | Thomas Bushnell <thomas@gnu.org> | 2000-07-25 19:40:27 +0000 |
---|---|---|
committer | Thomas Bushnell <thomas@gnu.org> | 2000-07-25 19:40:27 +0000 |
commit | 2f7e8f040f18b7f9bce6879d4b077094aa7d01c0 (patch) | |
tree | 80be9465da90cda7839b49574a3c232880b8fe49 /libpager/data-return.c | |
parent | 0e0bcad3e157579dbeafec933ac6ccbc00a515a3 (diff) | |
download | hurd-2f7e8f040f18b7f9bce6879d4b077094aa7d01c0.tar.gz hurd-2f7e8f040f18b7f9bce6879d4b077094aa7d01c0.tar.bz2 hurd-2f7e8f040f18b7f9bce6879d4b077094aa7d01c0.zip |
2000-07-25 Thomas Bushnell, BSG <tb@mit.edu>
* priv.h (PM_WRITEWAIT): New pagemap bit.
* data-return.c (_pager_do_write_request): Don't proceed with a
pageout if one is already in progress. Once we finish, wake up
any potential PM_WRITEWAIT waiters.
* priv.h (PM_INIT): Provide value again.
* data-return.c (_pager_do_write_request): Track PM_INIT again.
* priv.h (struct pager): Make pagemap consist of 16-bit elements
instead of only 8 bits.
* data-request.c (_pager_seqnos_memory_object_data_request):
Make PM_ENTRY a short pointer.
* data-return.c (_pager_do_write_request): Make PM_ENTRIES a short
pointer.
* lock-object.c (_pager_lock_object): Make PM_ENTRIES a short
pointer.
* mark-error.c (_pager_mark_next_request_error): Make P a short
pointer.
(_pager_mark_object_error): Likewise.
* offer-page.c (pager_offer_page): Make PM_ENTRY a short pointer.
* object-terminate.c (_pager_free_structure): Interpret
pagemapsize correctly.
* pagemap.c (_pager_pagemap_resize): Likewise.
Diffstat (limited to 'libpager/data-return.c')
-rw-r--r-- | libpager/data-return.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/libpager/data-return.c b/libpager/data-return.c index 9f107793..a83026fc 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, 1999 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 @@ -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; @@ -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 @@ -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 @@ -174,13 +188,13 @@ _pager_do_write_request (mach_port_t object, 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); |