summaryrefslogtreecommitdiff
path: root/libpager
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1996-05-02 15:18:42 +0000
committerMichael I. Bushnell <mib@gnu.org>1996-05-02 15:18:42 +0000
commit4f0593cc021714fbd887dfca79d4328d4cd07199 (patch)
tree19f02db696cd35ef11a9b24e35ddf1d78c42adba /libpager
parentfb671ed18f55d956b661b71db026610b46c3979c (diff)
(pager_offer_page): Make sure we hold lock across operation. Also set
incore bit when operation is complete.
Diffstat (limited to 'libpager')
-rw-r--r--libpager/offer-page.c24
1 files changed, 10 insertions, 14 deletions
diff --git a/libpager/offer-page.c b/libpager/offer-page.c
index a6666087..fe08d3b4 100644
--- a/libpager/offer-page.c
+++ b/libpager/offer-page.c
@@ -30,25 +30,21 @@ pager_offer_page (struct pager *p,
{
char *pm_entry;
- /* The caller expects this to get written back, then our request
- will get ignored and the precious bit won't get set, so flush it
- first */
- if (precious)
+ 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)
{
- 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)
- {
- mutex_unlock (&p->interlock);
- pager_flush_some (p, offset, vm_page_size, 1);
- }
- else
- mutex_unlock (&p->interlock);
+ mutex_unlock (&p->interlock);
+ pager_flush_some (p, offset, vm_page_size, 1);
+ goto try_again;
}
+ *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);
}