bug-hurd
[Top][All Lists]
Advanced

[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.)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]