bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/4] mach-defpager: fix receiver lookups


From: Justus Winter
Subject: [PATCH 2/4] mach-defpager: fix receiver lookups
Date: Wed, 19 Mar 2014 11:31:09 +0100

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




reply via email to

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