diff options
author | Miles Bader <miles@gnu.org> | 1995-07-08 23:26:54 +0000 |
---|---|---|
committer | Miles Bader <miles@gnu.org> | 1995-07-08 23:26:54 +0000 |
commit | dbe8a4ba45fddb5086ed0393ed16656a390d5e1c (patch) | |
tree | 04e88f4449ee193173bb7bd7501b749b09b21f5c /devio | |
parent | a064ef82e289f6ca6ba19b13f276fbd31524c899 (diff) |
(dev_stop_paging): New function.
(pager_dropweak): New function.
(pager_port_type): Deleted var.
(pager_port_bucket, pager_port_class): New vars.
(dev_get_memory_object): Moved here from dev.c. Also, call init_dev_pager if
necessary.
(service_paging_requests): New function.
(init_dev_pager): New function.
Diffstat (limited to 'devio')
-rw-r--r-- | devio/devpager.c | 132 |
1 files changed, 127 insertions, 5 deletions
diff --git a/devio/devpager.c b/devio/devpager.c index ab3da34a..9d6e4abb 100644 --- a/devio/devpager.c +++ b/devio/devpager.c @@ -24,15 +24,10 @@ #include <assert.h> #include "dev.h" -#include "ptypes.h" /* ---------------------------------------------------------------- */ /* Pager library callbacks; see <hurd/pager.h> for more info. */ -/* This will be the type used in calls to allocate_port by the pager system. - */ -int pager_port_type = PT_MEMOBJ; - /* For pager PAGER, read one page from offset PAGE. Set *BUF to be the address of the page, and set *WRITE_LOCK if the page must be provided read-only. The only permissable error returns are EIO, EDQUOT, and @@ -150,3 +145,130 @@ void pager_clear_user_data(struct user_pager_info *upi) { } + +/* ---------------------------------------------------------------- */ + +/* A top-level function for the paging thread that just services paging + requests. */ +static void +service_paging_requests (any_t arg) +{ + struct dev *dev = (struct dev *)arg; + for (;;) + ports_manage_port_operations_multithread (dev->pager_port_bucket, + pager_demuxer, + 1000 * 30, 1000 * 60 * 5, + 1, MACH_PORT_NULL); +} + +/* Initialize paging for this device. */ +static void +init_dev_paging (struct dev *dev) +{ + dev->pager_port_bucket = ports_create_bucket (); + + /* Make a thread to service paging requests. */ + cthread_detach (cthread_fork ((cthread_fn_t)service_paging_requests, + (any_t)dev)); +} + +void +pager_dropweak (struct user_pager_info *upi __attribute__ ((unused))) +{ +} + +/* ---------------------------------------------------------------- */ + +/* Try to stop all paging activity on DEV, returning true if we were + successful. If NOSYNC is true, then we won't write back any (kernel) + cached pages to the device. */ +int +dev_stop_paging (struct dev *dev, int nosync) +{ + int success = 1; /* Initially assume success. */ + + io_state_lock(&dev->io_state); + + if (dev->pager != NULL) + { + int num_pagers = ports_count_bucket (dev->pager_port_bucket); + if (num_pagers > 0 && !nosync) + { + error_t block_cache (void *arg) + { + struct pager *p = arg; + pager_change_attributes (p, 0, MEMORY_OBJECT_COPY_DELAY, 1); + return 0; + } + error_t enable_cache (void *arg) + { + struct pager *p = arg; + pager_change_attributes (p, 1, MEMORY_OBJECT_COPY_DELAY, 0); + return 0; + } + + /* Loop through the pagers and turn off caching one by one, + synchronously. That should cause termination of each pager. */ + ports_bucket_iterate (dev->pager_port_bucket, block_cache); + + /* Give it a second; the kernel doesn't actually shutdown + immediately. XXX */ + sleep (1); + + num_pagers = ports_count_bucket (dev->pager_port_bucket); + if (num_pagers > 0) + /* Darn, there are actual honest users. Turn caching back on, + and return failure. */ + { + ports_bucket_iterate (dev->pager_port_bucket, enable_cache); + success = 0; + } + } + + if (success && !nosync) + /* shutdown the pager on DEV. If NOSYNC is set, we don't bother, for + fear that this may result in I/O. In this case we've disabled + rpcs on the pager's ports, so this will result in hanging... What + do we do??? XXXX */ + pager_shutdown (dev->pager); + } + + if (success) + dev->pager = NULL; + + io_state_lock(&dev->io_state); + + return success; +} + +/* ---------------------------------------------------------------- */ + +/* Returns in MEMOBJ the port for a memory object backed by the storage on + DEV. Returns 0 or the error code if an error occurred. */ +error_t +dev_get_memory_object(struct dev *dev, memory_object_t *memobj) +{ + if (dev_is(dev, DEV_SERIAL)) + return ENODEV; + + io_state_lock(&dev->io_state); + if (dev->pager_port_bucket == NULL) + init_dev_paging (dev); + if (dev->pager == NULL) + dev->pager = + pager_create((struct user_pager_info *)dev, dev->pager_port_bucket, + 1, MEMORY_OBJECT_COPY_DELAY); + io_state_unlock(&dev->io_state); + + if (dev->pager == NULL) + return ENODEV; /* XXX ??? */ + + *memobj = pager_get_port(dev->pager); + if (*memobj != MACH_PORT_NULL) + return + mach_port_insert_right(mach_task_self(), + *memobj, *memobj, + MACH_MSG_TYPE_MAKE_SEND); + + return 0; +} |