summaryrefslogtreecommitdiff
path: root/ext2fs
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1995-06-24 23:25:11 +0000
committerMiles Bader <miles@gnu.org>1995-06-24 23:25:11 +0000
commit1a26b8ff99f907247687683212479c5037d87965 (patch)
tree8a1e2930be8af06875350fca95e13fd3a58bca78 /ext2fs
parentd35ca2bd419417f6fce172c54a24ee5988f53f3a (diff)
(thread_function): New function.
(create_disk_pager): Make a new thread to service paging requests. (pager_bucket): New variable. (pager_list_lock, file_pager_list): Variables deleted. (create_disk_pager): Create pager_bucket. (create_disk_pager, diskfs_get_filemap): Pass pager_bucket to pager_create. (pager_traverse): Function deleted. (diskfs_get_filemap, pager_clear_user_data): Don't add/remove UPI to/from the pager list, as there isn't any. (diskfs_shutdown_pager, diskfs_sync_everything): Use ports_bucket_iterate on pager_bucket to go through all the pagers, instead of pager_traverse. (diskfs_file_update, pager_traverse, allow_pager_softrefs, drop_pager_softrefs): Change pager [un]ref calls to use the new ports ref calls directly instead. (pager_dropweak): New function (does nothing).
Diffstat (limited to 'ext2fs')
-rw-r--r--ext2fs/pager.c116
1 files changed, 52 insertions, 64 deletions
diff --git a/ext2fs/pager.c b/ext2fs/pager.c
index 96e81c25..56120a51 100644
--- a/ext2fs/pager.c
+++ b/ext2fs/pager.c
@@ -21,8 +21,8 @@
#include <strings.h>
#include "ext2fs.h"
-spin_lock_t pager_list_lock = SPIN_LOCK_INITIALIZER;
-struct user_pager_info *file_pager_list;
+/* A ports bucket to hold pager ports. */
+static struct port_bucket *pager_bucket;
spin_lock_t node_to_page_lock = SPIN_LOCK_INITIALIZER;
@@ -556,13 +556,13 @@ diskfs_file_update (struct node *node, int wait)
spin_lock (&node_to_page_lock);
upi = node->dn->fileinfo;
if (upi)
- pager_reference (upi->p);
+ ports_port_ref (upi->p);
spin_unlock (&node_to_page_lock);
if (upi)
{
pager_sync (upi->p, wait);
- pager_unreference (upi->p);
+ ports_port_deref (upi->p);
}
pokel_sync (&node->dn->indir_pokel, wait);
@@ -602,27 +602,48 @@ pager_clear_user_data (struct user_pager_info *upi)
spin_unlock (&node_to_page_lock);
diskfs_nrele_light (upi->node);
-
- spin_lock (&pager_list_lock);
- *upi->prevp = upi->next;
- if (upi->next)
- upi->next->prevp = upi->prevp;
- spin_unlock (&pager_list_lock);
}
free (upi);
}
+
+/* This will be called when the ports library wants to drop weak references.
+ The pager library creates no weak references itself. If the user doesn't
+ either, then it's OK for this function to do nothing. */
+void
+pager_dropweak (struct user_pager_info *p __attribute__ ((unused)))
+{
+}
/* ---------------------------------------------------------------- */
+/* A top-level function for the paging thread that just services paging
+ requests. */
+static void
+service_paging_requests (any_t foo __attribute__ ((unused)))
+{
+ for (;;)
+ ports_manage_port_operations_multithread (pager_bucket, pager_demuxer,
+ 1000 * 60 * 2, 1000 * 60 * 10,
+ 1, MACH_PORT_NULL);
+}
+
/* Create a the DISK pager, initializing DISKPAGER, and DISKPAGERPORT */
void
create_disk_pager ()
{
+ pager_bucket = ports_create_bucket ();
+
+ /* Make a thread to service paging requests. */
+ cthread_detach (cthread_fork ((cthread_fn_t)service_paging_requests,
+ (any_t)0));
+
disk_pager = malloc (sizeof (struct user_pager_info));
disk_pager->type = DISK;
disk_pager->node = 0;
- disk_pager->p = pager_create (disk_pager, MAY_CACHE, MEMORY_OBJECT_COPY_NONE);
+ disk_pager->p =
+ pager_create (disk_pager, pager_bucket,
+ MAY_CACHE, MEMORY_OBJECT_COPY_NONE);
disk_pager_port = pager_get_port (disk_pager->p);
mach_port_insert_right (mach_task_self (), disk_pager_port, disk_pager_port,
MACH_MSG_TYPE_MAKE_SEND);
@@ -647,16 +668,9 @@ diskfs_get_filemap (struct node *node)
upi->type = FILE_DATA;
upi->node = node;
diskfs_nref_light (node);
- upi->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY);
+ upi->p =
+ pager_create (upi, pager_bucket, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY);
node->dn->fileinfo = upi;
-
- spin_lock (&pager_list_lock);
- upi->next = file_pager_list;
- upi->prevp = &file_pager_list;
- if (upi->next)
- upi->next->prevp = &upi->next;
- file_pager_list = upi;
- spin_unlock (&pager_list_lock);
}
right = pager_get_port (node->dn->fileinfo->p);
spin_unlock (&node_to_page_lock);
@@ -677,13 +691,13 @@ drop_pager_softrefs (struct node *node)
spin_lock (&node_to_page_lock);
upi = node->dn->fileinfo;
if (upi)
- pager_reference (upi->p);
+ ports_port_ref (upi->p);
spin_unlock (&node_to_page_lock);
if (MAY_CACHE && upi)
pager_change_attributes (upi->p, 0, MEMORY_OBJECT_COPY_DELAY, 0);
if (upi)
- pager_unreference (upi->p);
+ ports_port_deref (upi->p);
}
/* Call this when we should turn on caching because it's no longer
@@ -696,13 +710,13 @@ allow_pager_softrefs (struct node *node)
spin_lock (&node_to_page_lock);
upi = node->dn->fileinfo;
if (upi)
- pager_reference (upi->p);
+ ports_port_ref (upi->p);
spin_unlock (&node_to_page_lock);
if (MAY_CACHE && upi)
pager_change_attributes (upi->p, 1, MEMORY_OBJECT_COPY_DELAY, 0);
if (upi)
- pager_unreference (upi->p);
+ ports_port_deref (upi->p);
}
/* Call this to find out the struct pager * corresponding to the
@@ -717,48 +731,18 @@ diskfs_get_filemap_pager_struct (struct node *node)
return node->dn->fileinfo->p;
}
-/* Call function FUNC (which takes one argument, a pager) on each pager, with
- all file pagers being processed before the disk pager. Make the calls
- while holding no locks. */
-static void
-pager_traverse (void (*func)(struct user_pager_info *))
-{
- struct user_pager_info *p;
- struct item {struct item *next; struct user_pager_info *p;} *list = 0;
- struct item *i;
-
- spin_lock (&pager_list_lock);
- for (p = file_pager_list; p; p = p->next)
- /* XXXXXXX THIS CHECK IS A HACK TO MAKE A RACE WITH DEPARTING PAGERS
- RARER, UNTIL MIB FIXES PORTS TO HAVE SOFT REFERENCES!!!! XXXXX */
- if (((struct port_info *)p->p)->refcnt > 0)
- {
- i = alloca (sizeof (struct item));
- i->next = list;
- list = i;
- pager_reference (p->p);
- i->p = p;
- }
- spin_unlock (&pager_list_lock);
-
- for (i = list; i; i = i->next)
- {
- (*func)(i->p);
- pager_unreference (i->p->p);
- }
-
- (*func)(disk_pager);
-}
-
static struct ext2_super_block final_sblock;
/* Shutdown all the pagers. */
void
diskfs_shutdown_pager ()
{
- void shutdown_one (struct user_pager_info *p)
+ error_t shutdown_one (void *v_p)
{
- pager_shutdown (p->p);
+ struct user_pager_info *p = v_p;
+ if (p != disk_pager)
+ pager_shutdown (p->p);
+ return 0;
}
write_all_disknodes ();
@@ -768,21 +752,25 @@ diskfs_shutdown_pager ()
bcopy (sblock, &final_sblock, sizeof (final_sblock));
sblock = &final_sblock;
- pager_traverse (shutdown_one);
+ ports_bucket_iterate (pager_bucket, shutdown_one);
+ pager_shutdown (disk_pager->p);
}
/* Sync all the pagers. */
void
diskfs_sync_everything (int wait)
{
- void sync_one (struct user_pager_info *p)
+ error_t sync_one (void *v_p)
{
+ struct user_pager_info *p = v_p;
if (p != disk_pager)
pager_sync (p->p, wait);
- else
- pokel_sync (&global_pokel, wait);
+ return 0;
}
write_all_disknodes ();
- pager_traverse (sync_one);
+ ports_bucket_iterate (pager_bucket, sync_one);
+
+ /* Do things on the the disk pager. */
+ pokel_sync (&global_pokel, wait);
}