summaryrefslogtreecommitdiff
path: root/mach-defpager
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2014-03-05 18:44:10 +0100
committerJustus Winter <4winter@informatik.uni-hamburg.de>2014-03-25 08:55:55 +0100
commit1e981ffc8654910d868bac129c48b1381b935945 (patch)
tree5a833fb7bfeee063e9323790a40b1c4595d1fb6a /mach-defpager
parent71ee95fecd6b8afb2b19914b2395f63c44a8e812 (diff)
mach-defpager: fix receiver lookups
Previously, the receiver lookup was done manually in all the server functions. Use mig translator functions instead. * mach-defpager/mig-decls.h: New file. * mach-defpager/mig-mutate.h: Likewise. * mach-defpager/Makefile (MIGSFLAGS): Include mig-mutate.h. * mach-defpager/mach-defpager.c: Fix receiver lookups, move type definitions... * mach-defpager/priv.h: ... here, so that they can be used in mig-decls.h.
Diffstat (limited to 'mach-defpager')
-rw-r--r--mach-defpager/Makefile2
-rw-r--r--mach-defpager/default_pager.c219
-rw-r--r--mach-defpager/mig-decls.h37
-rw-r--r--mach-defpager/mig-mutate.h22
-rw-r--r--mach-defpager/priv.h188
5 files changed, 272 insertions, 196 deletions
diff --git a/mach-defpager/Makefile b/mach-defpager/Makefile
index e38a0bea..c8e33c52 100644
--- a/mach-defpager/Makefile
+++ b/mach-defpager/Makefile
@@ -34,4 +34,4 @@ LDFLAGS += -static
include ../Makeconf
-MIGSFLAGS = -DSEQNOS
+MIGSFLAGS = -DSEQNOS -imacros $(srcdir)/mig-mutate.h
diff --git a/mach-defpager/default_pager.c b/mach-defpager/default_pager.c
index 8f8e13e4..ed0376fc 100644
--- a/mach-defpager/default_pager.c
+++ b/mach-defpager/default_pager.c
@@ -60,6 +60,8 @@
#include "default_pager_S.h"
#include "exc_S.h"
+#include "priv.h"
+
#define debug 0
static char my_name[] = "(default pager):";
@@ -106,47 +108,6 @@ synchronized_printf (const char *fmt, ...)
#define ptoa(p) ((p)*vm_page_size)
#define atop(a) ((a)/vm_page_size)
-/*
- * Bitmap allocation.
- */
-typedef unsigned int bm_entry_t;
-#define NB_BM 32
-#define BM_MASK 0xffffffff
-
-#define howmany(a,b) (((a) + (b) - 1)/(b))
-
-/*
- * Value to indicate no block assigned
- */
-#define NO_BLOCK ((vm_offset_t)-1)
-
-/*
- * 'Partition' structure for each paging area.
- * Controls allocation of blocks within paging area.
- */
-struct part {
- pthread_mutex_t p_lock; /* for bitmap/free */
- vm_size_t total_size; /* total number of blocks */
- vm_size_t free; /* number of blocks free */
- unsigned int id; /* named lookup */
- bm_entry_t *bitmap; /* allocation map */
- boolean_t going_away; /* destroy attempt in progress */
- struct file_direct *file; /* file paged to */
-};
-typedef struct part *partition_t;
-
-struct {
- pthread_mutex_t lock;
- int n_partitions;
- partition_t *partition_list;/* array, for quick mapping */
-} all_partitions; /* list of all such */
-
-typedef unsigned char p_index_t;
-
-#define P_INDEX_INVALID ((p_index_t)-1)
-
-#define no_partition(x) ((x) == P_INDEX_INVALID)
-
partition_t partition_of(x)
int x;
{
@@ -632,81 +593,6 @@ ddprintf ("pager_dealloc_page(%d,%x,%d)\n",pindex,page,lock_it);
}
/*
- * Allocation info for each paging object.
- *
- * Most operations, even pager_write_offset and pager_put_checksum,
- * just need a read lock. Higher-level considerations prevent
- * conflicting operations on a single page. The lock really protects
- * the underlying size and block map memory, so pager_extend needs a
- * write lock.
- *
- * An object can now span multiple paging partitions. The allocation
- * info we keep is a pair (offset,p_index) where the index is in the
- * array of all partition ptrs, and the offset is partition-relative.
- * Size wise we are doing ok fitting the pair into a single integer:
- * the offset really is in pages so we have vm_page_size bits available
- * for the partition index.
- */
-#define DEBUG_READER_CONFLICTS 0
-
-#if DEBUG_READER_CONFLICTS
-int default_pager_read_conflicts = 0;
-#endif
-
-union dp_map {
-
- struct {
- unsigned int p_offset : 24,
- p_index : 8;
- } block;
-
- union dp_map *indirect;
-};
-typedef union dp_map *dp_map_t;
-
-/* quick check for part==block==invalid */
-#define no_block(e) ((e).indirect == (dp_map_t)NO_BLOCK)
-#define invalidate_block(e) ((e).indirect = (dp_map_t)NO_BLOCK)
-
-struct dpager {
- pthread_mutex_t lock; /* lock for extending block map */
- /* XXX should be read-write lock */
-#if DEBUG_READER_CONFLICTS
- int readers;
- boolean_t writer;
-#endif
- dp_map_t map; /* block map */
- vm_size_t size; /* size of paging object, in pages */
- vm_size_t limit; /* limit (bytes) allowed to grow to */
- vm_size_t byte_limit; /* limit, which wasn't
- rounded to page boundary */
- p_index_t cur_partition;
-#ifdef CHECKSUM
- vm_offset_t *checksum; /* checksum - parallel to block map */
-#define NO_CHECKSUM ((vm_offset_t)-1)
-#endif /* CHECKSUM */
-};
-typedef struct dpager *dpager_t;
-
-/*
- * A paging object uses either a one- or a two-level map of offsets
- * into a paging partition.
- */
-#define PAGEMAP_ENTRIES 64
- /* number of pages in a second-level map */
-#define PAGEMAP_SIZE(npgs) ((npgs)*sizeof(vm_offset_t))
-
-#define INDIRECT_PAGEMAP_ENTRIES(npgs) \
- ((((npgs)-1)/PAGEMAP_ENTRIES) + 1)
-#define INDIRECT_PAGEMAP_SIZE(npgs) \
- (INDIRECT_PAGEMAP_ENTRIES(npgs) * sizeof(vm_offset_t *))
-#define INDIRECT_PAGEMAP(size) \
- (size > PAGEMAP_ENTRIES)
-
-#define ROUNDUP_TO_PAGEMAP(npgs) \
- (((npgs) + PAGEMAP_ENTRIES - 1) & ~(PAGEMAP_ENTRIES - 1))
-
-/*
* Object sizes are rounded up to the next power of 2,
* unless they are bigger than a given maximum size.
*/
@@ -1885,40 +1771,6 @@ default_has_page(ds, offset)
return ( ! no_block(pager_read_offset(ds, offset)) );
}
-/*
- * Mapping between pager port and paging object.
- */
-struct dstruct {
- queue_chain_t links; /* Link in pager-port list */
-
- pthread_mutex_t lock; /* Lock for the structure */
- pthread_cond_t
- waiting_seqno, /* someone waiting on seqno */
- waiting_read, /* someone waiting on readers */
- waiting_write, /* someone waiting on writers */
- waiting_refs; /* someone waiting on refs */
-
- memory_object_t pager; /* Pager port */
- mach_port_seqno_t seqno; /* Pager port sequence number */
- mach_port_t pager_request; /* Request port */
- mach_port_urefs_t request_refs; /* Request port user-refs */
- mach_port_t pager_name; /* Name port */
- mach_port_urefs_t name_refs; /* Name port user-refs */
- boolean_t external; /* Is an external object? */
-
- unsigned int readers; /* Reads in progress */
- unsigned int writers; /* Writes in progress */
-
- /* This is the reply port of an outstanding
- default_pager_object_set_size call. */
- mach_port_t lock_request;
-
- unsigned int errors; /* Pageout error count */
- struct dpager dpager; /* Actual pager */
-};
-typedef struct dstruct * default_pager_t;
-#define DEFAULT_PAGER_NULL ((default_pager_t)0)
-
#if PARALLEL
#define dstruct_lock_init(ds) pthread_mutex_init(&ds->lock, NULL)
#define dstruct_lock(ds) pthread_mutex_lock(&ds->lock)
@@ -1960,17 +1812,6 @@ void pager_port_list_insert(port, ds)
pthread_mutex_unlock(&all_pagers.lock);
}
-/* given a data structure return a good port-name to associate it to */
-#define pnameof(_x_) (((vm_offset_t)(_x_))+1)
-/* reverse, assumes no-odd-pointers */
-#define dnameof(_x_) (((vm_offset_t)(_x_))&~1)
-
-/* The magic typecast */
-#define pager_port_lookup(_port_) \
- ((! MACH_PORT_VALID(_port_) || \
- ((default_pager_t)dnameof(_port_))->pager != (_port_)) ? \
- DEFAULT_PAGER_NULL : (default_pager_t)dnameof(_port_))
-
void pager_port_list_delete(ds)
default_pager_t ds;
{
@@ -2450,15 +2291,14 @@ memory_object_copy_strategy_t default_pager_copy_strategy =
MEMORY_OBJECT_COPY_DELAY;
kern_return_t
-seqnos_memory_object_init(pager, seqno, pager_request, pager_name,
+seqnos_memory_object_init(ds, seqno, pager_request, pager_name,
pager_page_size)
- mach_port_t pager;
+ default_pager_t ds;
mach_port_seqno_t seqno;
mach_port_t pager_request;
mach_port_t pager_name;
vm_size_t pager_page_size;
{
- default_pager_t ds;
kern_return_t kr;
static char here[] = "%sinit";
@@ -2466,7 +2306,6 @@ seqnos_memory_object_init(pager, seqno, pager_request, pager_name,
assert(MACH_PORT_VALID(pager_name));
assert(pager_page_size == vm_page_size);
- ds = pager_port_lookup(pager);
if (ds == DEFAULT_PAGER_NULL)
panic(here, my_name);
pager_port_lock(ds, seqno);
@@ -2498,13 +2337,12 @@ seqnos_memory_object_init(pager, seqno, pager_request, pager_name,
}
kern_return_t
-seqnos_memory_object_terminate(pager, seqno, pager_request, pager_name)
- mach_port_t pager;
+seqnos_memory_object_terminate(ds, seqno, pager_request, pager_name)
+ default_pager_t ds;
mach_port_seqno_t seqno;
mach_port_t pager_request;
mach_port_t pager_name;
{
- default_pager_t ds;
static char here[] = "%sterminate";
/*
@@ -2512,7 +2350,6 @@ seqnos_memory_object_terminate(pager, seqno, pager_request, pager_name)
* not send rights.
*/
- ds = pager_port_lookup(pager);
if (ds == DEFAULT_PAGER_NULL)
panic(here, my_name);
ddprintf ("seqnos_memory_object_terminate <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n",
@@ -2578,7 +2415,7 @@ void default_pager_no_senders(pager, seqno, mscount)
*/
- ds = pager_port_lookup(pager);
+ ds = begin_using_default_pager(pager);
if (ds == DEFAULT_PAGER_NULL)
panic(here,my_name);
pager_port_lock(ds, seqno);
@@ -2639,16 +2476,15 @@ int default_pager_pageout_count = 0;
static __thread default_pager_thread_t *dpt;
kern_return_t
-seqnos_memory_object_data_request(pager, seqno, reply_to, offset,
+seqnos_memory_object_data_request(ds, seqno, reply_to, offset,
length, protection_required)
- memory_object_t pager;
+ default_pager_t ds;
mach_port_seqno_t seqno;
mach_port_t reply_to;
vm_offset_t offset;
vm_size_t length;
vm_prot_t protection_required;
{
- default_pager_t ds;
vm_offset_t addr;
unsigned int errors;
kern_return_t rc;
@@ -2657,7 +2493,6 @@ seqnos_memory_object_data_request(pager, seqno, reply_to, offset,
if (length != vm_page_size)
panic(here,my_name);
- ds = pager_port_lookup(pager);
if (ds == DEFAULT_PAGER_NULL)
panic(here,my_name);
ddprintf ("seqnos_memory_object_data_request <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n",
@@ -2742,9 +2577,9 @@ ddprintf ("seqnos_memory_object_data_request <%p>: pager_port_unlock: <%p>[s:%d,
* also assumes that the default_pager is single-threaded.
*/
kern_return_t
-seqnos_memory_object_data_initialize(pager, seqno, pager_request,
+seqnos_memory_object_data_initialize(ds, seqno, pager_request,
offset, addr, data_cnt)
- memory_object_t pager;
+ default_pager_t ds;
mach_port_seqno_t seqno;
mach_port_t pager_request;
register
@@ -2754,14 +2589,12 @@ seqnos_memory_object_data_initialize(pager, seqno, pager_request,
vm_size_t data_cnt;
{
vm_offset_t amount_sent;
- default_pager_t ds;
static char here[] = "%sdata_initialize";
#ifdef lint
pager_request++;
#endif /* lint */
- ds = pager_port_lookup(pager);
if (ds == DEFAULT_PAGER_NULL)
panic(here,my_name);
ddprintf ("seqnos_memory_object_data_initialize <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n",
@@ -2804,9 +2637,9 @@ ddprintf ("seqnos_memory_object_data_initialize <%p>: pager_port_unlock: <%p>[s:
* into individual pages and pass them off to default_write.
*/
kern_return_t
-seqnos_memory_object_data_write(pager, seqno, pager_request,
+seqnos_memory_object_data_write(ds, seqno, pager_request,
offset, addr, data_cnt)
- memory_object_t pager;
+ default_pager_t ds;
mach_port_seqno_t seqno;
mach_port_t pager_request;
register
@@ -2817,7 +2650,6 @@ seqnos_memory_object_data_write(pager, seqno, pager_request,
{
register
vm_size_t amount_sent;
- default_pager_t ds;
static char here[] = "%sdata_write";
int err;
@@ -2828,7 +2660,6 @@ seqnos_memory_object_data_write(pager, seqno, pager_request,
if ((data_cnt % vm_page_size) != 0)
panic(here,my_name);
- ds = pager_port_lookup(pager);
if (ds == DEFAULT_PAGER_NULL)
panic(here,my_name);
@@ -2888,7 +2719,7 @@ seqnos_memory_object_data_write(pager, seqno, pager_request,
kern_return_t
seqnos_memory_object_copy(old_memory_object, seqno, old_memory_control,
offset, length, new_memory_object)
- memory_object_t old_memory_object;
+ default_pager_t old_memory_object;
mach_port_seqno_t seqno;
memory_object_control_t
old_memory_control;
@@ -2903,7 +2734,7 @@ seqnos_memory_object_copy(old_memory_object, seqno, old_memory_control,
/* We get this when our memory_object_lock_request has completed
after we truncated an object. */
kern_return_t
-seqnos_memory_object_lock_completed (memory_object_t pager,
+seqnos_memory_object_lock_completed (default_pager_t ds,
mach_port_seqno_t seqno,
mach_port_t pager_request,
vm_offset_t offset,
@@ -2916,7 +2747,7 @@ seqnos_memory_object_lock_completed (memory_object_t pager,
kern_return_t
seqnos_memory_object_data_unlock(pager, seqno, pager_request,
offset, length, protection_required)
- memory_object_t pager;
+ default_pager_t pager;
mach_port_seqno_t seqno;
mach_port_t pager_request;
vm_offset_t offset;
@@ -2928,10 +2759,10 @@ seqnos_memory_object_data_unlock(pager, seqno, pager_request,
}
kern_return_t
-seqnos_memory_object_supply_completed(pager, seqno, pager_request,
+seqnos_memory_object_supply_completed(ds, seqno, pager_request,
offset, length,
result, error_offset)
- memory_object_t pager;
+ default_pager_t ds;
mach_port_seqno_t seqno;
mach_port_t pager_request;
vm_offset_t offset;
@@ -2949,10 +2780,10 @@ seqnos_memory_object_supply_completed(pager, seqno, pager_request,
* into individual pages and pass them off to default_write.
*/
kern_return_t
-seqnos_memory_object_data_return(pager, seqno, pager_request,
+seqnos_memory_object_data_return(ds, seqno, pager_request,
offset, addr, data_cnt,
dirty, kernel_copy)
- memory_object_t pager;
+ default_pager_t ds;
mach_port_seqno_t seqno;
mach_port_t pager_request;
vm_offset_t offset;
@@ -2962,13 +2793,13 @@ seqnos_memory_object_data_return(pager, seqno, pager_request,
boolean_t kernel_copy;
{
- return seqnos_memory_object_data_write (pager, seqno, pager_request,
+ return seqnos_memory_object_data_write (ds, seqno, pager_request,
offset, addr, data_cnt);
}
kern_return_t
-seqnos_memory_object_change_completed(pager, seqno, may_cache, copy_strategy)
- memory_object_t pager;
+seqnos_memory_object_change_completed(ds, seqno, may_cache, copy_strategy)
+ default_pager_t ds;
mach_port_seqno_t seqno;
boolean_t may_cache;
memory_object_copy_strategy_t copy_strategy;
@@ -3756,14 +3587,12 @@ S_default_pager_object_pages (mach_port_t pager,
kern_return_t
-S_default_pager_object_set_size (mach_port_t pager,
+S_default_pager_object_set_size (default_pager_t ds,
mach_port_seqno_t seqno,
vm_size_t limit)
{
kern_return_t kr = KERN_SUCCESS;
- default_pager_t ds;
- ds = pager_port_lookup(pager);
if (ds == DEFAULT_PAGER_NULL)
return KERN_INVALID_ARGUMENT;
diff --git a/mach-defpager/mig-decls.h b/mach-defpager/mig-decls.h
new file mode 100644
index 00000000..f63fef20
--- /dev/null
+++ b/mach-defpager/mig-decls.h
@@ -0,0 +1,37 @@
+/*
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ Written by Justus Winter.
+
+ 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 the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef __MACH_DEFPAGER_MIG_DECLS_H__
+#define __MACH_DEFPAGER_MIG_DECLS_H__
+
+#include "priv.h"
+
+/* Called by server stub functions. */
+
+static inline struct dstruct * __attribute__ ((unused))
+begin_using_default_pager (mach_port_t port)
+{
+ if (! MACH_PORT_VALID(port)
+ || ((default_pager_t) dnameof(port))->pager != (port))
+ return DEFAULT_PAGER_NULL;
+
+ return (default_pager_t) dnameof(port);
+}
+
+#endif /* __MACH_DEFPAGER_MIG_DECLS_H__ */
diff --git a/mach-defpager/mig-mutate.h b/mach-defpager/mig-mutate.h
new file mode 100644
index 00000000..54aeeba6
--- /dev/null
+++ b/mach-defpager/mig-mutate.h
@@ -0,0 +1,22 @@
+/*
+ Copyright (C) 2014 Free Software Foundation, Inc.
+ Written by Justus Winter.
+
+ 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 the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
+
+#define MEMORY_OBJECT_INTRAN default_pager_t begin_using_default_pager (mach_port_t)
+#define MEMORY_OBJECT_IMPORTS import "mig-decls.h";
+#define DEFAULT_PAGER_IMPORTS import "mig-decls.h";
diff --git a/mach-defpager/priv.h b/mach-defpager/priv.h
new file mode 100644
index 00000000..20711b2c
--- /dev/null
+++ b/mach-defpager/priv.h
@@ -0,0 +1,188 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1989 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+#ifndef __MACH_DEFPAGER_PRIV_H__
+#define __MACH_DEFPAGER_PRIV_H__
+
+#include <mach.h>
+#include <queue.h>
+
+/*
+ * Bitmap allocation.
+ */
+typedef unsigned int bm_entry_t;
+#define NB_BM 32
+#define BM_MASK 0xffffffff
+
+#define howmany(a,b) (((a) + (b) - 1)/(b))
+
+/*
+ * Value to indicate no block assigned
+ */
+#define NO_BLOCK ((vm_offset_t)-1)
+
+/*
+ * 'Partition' structure for each paging area.
+ * Controls allocation of blocks within paging area.
+ */
+struct part {
+ pthread_mutex_t p_lock; /* for bitmap/free */
+ vm_size_t total_size; /* total number of blocks */
+ vm_size_t free; /* number of blocks free */
+ unsigned int id; /* named lookup */
+ bm_entry_t *bitmap; /* allocation map */
+ boolean_t going_away; /* destroy attempt in progress */
+ struct file_direct *file; /* file paged to */
+};
+typedef struct part *partition_t;
+
+struct {
+ pthread_mutex_t lock;
+ int n_partitions;
+ partition_t *partition_list;/* array, for quick mapping */
+} all_partitions; /* list of all such */
+
+typedef unsigned char p_index_t;
+
+#define P_INDEX_INVALID ((p_index_t)-1)
+
+#define no_partition(x) ((x) == P_INDEX_INVALID)
+
+/*
+ * Allocation info for each paging object.
+ *
+ * Most operations, even pager_write_offset and pager_put_checksum,
+ * just need a read lock. Higher-level considerations prevent
+ * conflicting operations on a single page. The lock really protects
+ * the underlying size and block map memory, so pager_extend needs a
+ * write lock.
+ *
+ * An object can now span multiple paging partitions. The allocation
+ * info we keep is a pair (offset,p_index) where the index is in the
+ * array of all partition ptrs, and the offset is partition-relative.
+ * Size wise we are doing ok fitting the pair into a single integer:
+ * the offset really is in pages so we have vm_page_size bits available
+ * for the partition index.
+ */
+#define DEBUG_READER_CONFLICTS 0
+
+#if DEBUG_READER_CONFLICTS
+int default_pager_read_conflicts = 0;
+#endif
+
+union dp_map {
+
+ struct {
+ unsigned int p_offset : 24,
+ p_index : 8;
+ } block;
+
+ union dp_map *indirect;
+};
+typedef union dp_map *dp_map_t;
+
+/* quick check for part==block==invalid */
+#define no_block(e) ((e).indirect == (dp_map_t)NO_BLOCK)
+#define invalidate_block(e) ((e).indirect = (dp_map_t)NO_BLOCK)
+
+struct dpager {
+ pthread_mutex_t lock; /* lock for extending block map */
+ /* XXX should be read-write lock */
+#if DEBUG_READER_CONFLICTS
+ int readers;
+ boolean_t writer;
+#endif
+ dp_map_t map; /* block map */
+ vm_size_t size; /* size of paging object, in pages */
+ vm_size_t limit; /* limit (bytes) allowed to grow to */
+ vm_size_t byte_limit; /* limit, which wasn't
+ rounded to page boundary */
+ p_index_t cur_partition;
+#ifdef CHECKSUM
+ vm_offset_t *checksum; /* checksum - parallel to block map */
+#define NO_CHECKSUM ((vm_offset_t)-1)
+#endif /* CHECKSUM */
+};
+typedef struct dpager *dpager_t;
+
+/*
+ * A paging object uses either a one- or a two-level map of offsets
+ * into a paging partition.
+ */
+#define PAGEMAP_ENTRIES 64
+ /* number of pages in a second-level map */
+#define PAGEMAP_SIZE(npgs) ((npgs)*sizeof(vm_offset_t))
+
+#define INDIRECT_PAGEMAP_ENTRIES(npgs) \
+ ((((npgs)-1)/PAGEMAP_ENTRIES) + 1)
+#define INDIRECT_PAGEMAP_SIZE(npgs) \
+ (INDIRECT_PAGEMAP_ENTRIES(npgs) * sizeof(vm_offset_t *))
+#define INDIRECT_PAGEMAP(size) \
+ (size > PAGEMAP_ENTRIES)
+
+#define ROUNDUP_TO_PAGEMAP(npgs) \
+ (((npgs) + PAGEMAP_ENTRIES - 1) & ~(PAGEMAP_ENTRIES - 1))
+
+/*
+ * Mapping between pager port and paging object.
+ */
+struct dstruct {
+ queue_chain_t links; /* Link in pager-port list */
+
+ pthread_mutex_t lock; /* Lock for the structure */
+ pthread_cond_t
+ waiting_seqno, /* someone waiting on seqno */
+ waiting_read, /* someone waiting on readers */
+ waiting_write, /* someone waiting on writers */
+ waiting_refs; /* someone waiting on refs */
+
+ memory_object_t pager; /* Pager port */
+ mach_port_seqno_t seqno; /* Pager port sequence number */
+ mach_port_t pager_request; /* Request port */
+ mach_port_urefs_t request_refs; /* Request port user-refs */
+ mach_port_t pager_name; /* Name port */
+ mach_port_urefs_t name_refs; /* Name port user-refs */
+ boolean_t external; /* Is an external object? */
+
+ unsigned int readers; /* Reads in progress */
+ unsigned int writers; /* Writes in progress */
+
+ /* This is the reply port of an outstanding
+ default_pager_object_set_size call. */
+ mach_port_t lock_request;
+
+ unsigned int errors; /* Pageout error count */
+ struct dpager dpager; /* Actual pager */
+};
+typedef struct dstruct * default_pager_t;
+#define DEFAULT_PAGER_NULL ((default_pager_t)0)
+
+/* given a data structure return a good port-name to associate it to */
+#define pnameof(_x_) (((vm_offset_t) (_x_)) + 1)
+/* reverse, assumes no-odd-pointers */
+#define dnameof(_x_) (((vm_offset_t) (_x_)) & ~1)
+
+#endif /* __MACH_DEFPAGER_PRIV_H__ */