summaryrefslogtreecommitdiff
path: root/libhurd-mm
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@gnu.org>2008-12-18 22:54:15 +0100
committerNeal H. Walfield <neal@gnu.org>2008-12-18 22:54:15 +0100
commit207770cea7fece43bf5517fec7abd88a3a7d6146 (patch)
tree6f41abd1dc4782f34b339b00da956d0c778ef1b7 /libhurd-mm
parentf5cfa7cbb8a2fff68cf87a3a685428507ce977b4 (diff)
Support batching requests for object_discarded_clear.
libviengoos/ 2008-12-18 Neal H. Walfield <neal@gnu.org> * viengoos/cap.h (object_discarded_clear): Take additional parameter count. Take multiple object addresses. viengoos/ 2008-12-18 Neal H. Walfield <neal@gnu.org> * server.c (server_loop): Handle multiple objects in object_discarded_clear. libhurd-mm/ 2008-12-18 Neal H. Walfield <neal@gnu.org> * anonymous.c (fault): Batch object discard requests.
Diffstat (limited to 'libhurd-mm')
-rw-r--r--libhurd-mm/ChangeLog4
-rw-r--r--libhurd-mm/anonymous.c66
2 files changed, 64 insertions, 6 deletions
diff --git a/libhurd-mm/ChangeLog b/libhurd-mm/ChangeLog
index a74f7d7..3a9a35b 100644
--- a/libhurd-mm/ChangeLog
+++ b/libhurd-mm/ChangeLog
@@ -1,5 +1,9 @@
2008-12-18 Neal H. Walfield <neal@gnu.org>
+ * anonymous.c (fault): Batch object discard requests.
+
+2008-12-18 Neal H. Walfield <neal@gnu.org>
+
* exceptions.c (hurd_activation_state_alloc): Cast UTCB to a void *.
2008-12-18 Neal H. Walfield <neal@gnu.org>
diff --git a/libhurd-mm/anonymous.c b/libhurd-mm/anonymous.c
index dac8309..a653ae2 100644
--- a/libhurd-mm/anonymous.c
+++ b/libhurd-mm/anonymous.c
@@ -229,6 +229,59 @@ fault (struct pager *pager, uintptr_t offset, int count, bool read_only,
hurd_btree_storage_desc_t *storage_descs;
storage_descs = (hurd_btree_storage_desc_t *) &anon->storage;
+ struct hurd_message_buffer *mb = NULL;
+ int discards = 0;
+ void queue_clear (vg_addr_t addr)
+ {
+ if (mb
+ && (VG_ADDR_IS_VOID (addr)
+ || vg_message_space (mb->request) < sizeof (vg_addr_t)))
+ {
+ hurd_activation_message_register (mb);
+ error_t err = vg_ipc (VG_IPC_RECEIVE | VG_IPC_SEND
+ | VG_IPC_RECEIVE_ACTIVATE
+ | VG_IPC_SEND_SET_THREAD_TO_CALLER
+ | VG_IPC_SEND_SET_ASROOT_TO_CALLERS
+ | VG_IPC_RECEIVE_SET_THREAD_TO_CALLER
+ | VG_IPC_RECEIVE_SET_ASROOT_TO_CALLERS,
+ VG_ADDR_VOID,
+ mb->receiver_strong, VG_ADDR_VOID,
+ VG_ADDR_VOID, VG_ADDR_VOID,
+ mb->sender, VG_ADDR_VOID);
+ if (err)
+ hurd_activation_message_unregister (mb);
+ else
+ {
+ int i;
+ err = vg_object_discarded_clear_reply_unmarshal (mb->reply, &i);
+ assert (! err);
+ assert (i == discards);
+ }
+
+ hurd_message_buffer_free (mb);
+ mb = NULL;
+ discards = 0;
+ }
+
+ if (VG_ADDR_IS_VOID (addr))
+ return;
+
+ if (! mb)
+ {
+ mb = hurd_message_buffer_alloc ();
+
+ vg_object_discarded_clear_receive_marshal (mb->reply);
+ vg_object_discarded_clear_send_marshal (mb->request, addr,
+ mb->receiver);
+ discards = 1;
+ }
+ else
+ {
+ vg_message_append_data (mb->request, sizeof (addr), (void *) &addr);
+ discards ++;
+ }
+ }
+
int i;
for (i = 0; i < count; i ++)
{
@@ -248,14 +301,11 @@ fault (struct pager *pager, uintptr_t offset, int count, bool read_only,
assert (storage_desc);
assert (anon->policy.discardable);
- error_t err;
/* We pass the fault address and not the underlying
storage address as object_discarded_clear also
returns a mapping and we are likely to access the
data at the fault address. */
- err = vg_object_discarded_clear (VG_ADDR_VOID, VG_ADDR_VOID,
- storage_desc->storage);
- assertx (err == 0, "%d", err);
+ queue_clear (storage_desc->storage);
debug (5, "Clearing discarded bit for %p / " VG_ADDR_FMT,
(void *) fault_addr + i * PAGESIZE,
@@ -300,8 +350,9 @@ fault (struct pager *pager, uintptr_t offset, int count, bool read_only,
page.type = vg_cap_page;
VG_CAP_POLICY_SET (&page, anon->policy);
- vg_addr_t addr = vg_addr_chop (VG_PTR_TO_ADDR (fault_addr + i * PAGESIZE),
- PAGESIZE_LOG2);
+ vg_addr_t addr
+ = vg_addr_chop (VG_PTR_TO_ADDR (fault_addr + i * PAGESIZE),
+ PAGESIZE_LOG2);
as_ensure_use
(addr,
@@ -323,6 +374,9 @@ fault (struct pager *pager, uintptr_t offset, int count, bool read_only,
0, PAGESIZE_LOG2));
}
+ /* Flush any pending discards. */
+ queue_clear (VG_ADDR_VOID);
+
#if 0
int faulted;
for (i = 0; i < count; i += faulted)