summaryrefslogtreecommitdiff
path: root/libpager/lock-object.c
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1994-01-13 20:44:45 +0000
committerMichael I. Bushnell <mib@gnu.org>1994-01-13 20:44:45 +0000
commitd68074b8c460de31fae524b67ff4c19e8e56fc2e (patch)
tree565c8fa4501dbd6fec2603c1347356f757e6932f /libpager/lock-object.c
parentcb92810bfd089c5fbac854b1495c035c7dfd2107 (diff)
Initial revision
Diffstat (limited to 'libpager/lock-object.c')
-rw-r--r--libpager/lock-object.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/libpager/lock-object.c b/libpager/lock-object.c
new file mode 100644
index 00000000..c00f5170
--- /dev/null
+++ b/libpager/lock-object.c
@@ -0,0 +1,82 @@
+/* Synchronous wrapper for memory_object_lock_request
+ Copyright (C) 1993, 1994 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
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program 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. */
+
+
+/* Request a lock from the kernel. Parameters are as for
+ memory_object_lock_request. If SYNC is set, then wait for
+ the operation to fully complete before returning. */
+void
+lock_object (struct pager *p,
+ vm_offset_t offset,
+ vm_size_t size,
+ int should_return,
+ int should_flush,
+ vm_prot_t lock_value,
+ int sync)
+{
+ struct lock_request *lr = 0;
+
+ mutex_lock (&p->interlock);
+ if (p->pager_state != NORMAL)
+ {
+ mutex_unlock (&p->interlock);
+ return;
+ }
+
+ if (sync)
+ {
+ for (lr = p->lock_requests; lr; lr = lr->next)
+ if (lr->start == offset && lr->end == offset + size)
+ {
+ lr->locks_pending++;
+ lr->threads_waiting++;
+ break;
+ }
+ if (!lr)
+ {
+ lr = malloc (sizeof (struct lock_request));
+ lr->start = offset;
+ lr->end = offset + size;
+ lr->pending_writes = 0;
+ lr->locks_pending = 1;
+ lr->threads_waiting = 1;
+ lr->next = p->lock_requests;
+ if (lr->next)
+ lr->next->prevp = &lr->next;
+ lr->prevp = &p->lock_requests;
+ p->lock_requests = lr;
+ }
+ }
+
+ memory_object_lock_request (p->memobjcntl, offset, size, should_return,
+ should_flush, lock_value,
+ sync ? p->port.port : MACH_PORT_NULL);
+
+ if (sync)
+ {
+ while (lr->locks_pending || lr->pending_writes)
+ condition_wait (&p->wakeup, &p->interlock);
+
+ if (!--lr->threads_waiting)
+ {
+ *lr->prevp = lr->next;
+ free (lr);
+ }
+ }
+
+ mutex_unlock (&p->interlock);
+}