[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 2/4] mach-defpager: fix receiver lookups
From: |
Samuel Thibault |
Subject: |
Re: [PATCH 2/4] mach-defpager: fix receiver lookups |
Date: |
Tue, 25 Mar 2014 02:54:43 +0100 |
User-agent: |
Mutt/1.5.21+34 (58baf7c9f32f) (2010-12-30) |
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.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__ */
> --
> 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.)
- Another round of receiver lookup fixes, Justus Winter, 2014/03/19
- [PATCH] include: make the memory_object_t types translation functions mutable, Justus Winter, 2014/03/19
- [PATCH 1/4] hurd: fix receiver type, honor DEFAULT_PAGER_IMPORTS, Justus Winter, 2014/03/19
- [PATCH 3/4] mach-defpager: fix local includes, Justus Winter, 2014/03/19
- [PATCH 2/4] mach-defpager: fix receiver lookups, Justus Winter, 2014/03/19
- Re: [PATCH 2/4] mach-defpager: fix receiver lookups,
Samuel Thibault <=
- [PATCH 4/4] mach-defpager: replace the magic typecast with a hash table, Justus Winter, 2014/03/19
- Re: [PATCH 1/4] hurd: fix receiver type, honor DEFAULT_PAGER_IMPORTS, Samuel Thibault, 2014/03/24