Justus Winter, le Wed 19 Mar 2014 11:31:09 +0100, a écrit : > Previously, the receiver lookup was done manually in all the server > functions. Use mig translator functions instead.
Ack. > * 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. > --- > mach-defpager/Makefile | 2 +- > mach-defpager/default_pager.c | 219 > +++++------------------------------------- > mach-defpager/mig-decls.h | 37 +++++++ > mach-defpager/mig-mutate.h | 22 +++++ > mach-defpager/priv.h | 188 ++++++++++++++++++++++++++++++++++++ > 5 files changed, 272 insertions(+), 196 deletions(-) > create mode 100644 mach-defpager/mig-decls.h > create mode 100644 mach-defpager/mig-mutate.h > create mode 100644 mach-defpager/priv.h > > diff --git a/mach-defpager/Makefile b/mach-defpager/Makefile > index e38a0be..c8e33c5 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 8f8e13e..ed0376f 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 0000000..f63fef2 > --- /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 0000000..54aeeba > --- /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 0000000..20711b2 > --- /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.distribut...@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__ */ > -- > 1.9.0 > -- Samuel How do I type "for i in *.dvi do xdvi i done" in a GUI? (Discussion in comp.os.linux.misc on the intuitiveness of interfaces.)