From dbe8a4ba45fddb5086ed0393ed16656a390d5e1c Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Sat, 8 Jul 1995 23:26:54 +0000 Subject: (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. --- devio/devpager.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file 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 #include "dev.h" -#include "ptypes.h" /* ---------------------------------------------------------------- */ /* Pager library callbacks; see 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; +} -- cgit v1.2.3