summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@gnu.org>2008-12-18 11:58:27 +0100
committerNeal H. Walfield <neal@gnu.org>2008-12-18 11:58:27 +0100
commit50f56bdeafd7636880c9fc168acdb28bfc805808 (patch)
treef4391d3a7ce8a44d5ed473019b6bd61ce5b58eba
parent854d97b4ba67df0848bfe0115924430fc57cbf5e (diff)
Maintain a reserve of message buffers.
2008-12-18 Neal H. Walfield <neal@gnu.org> * message-buffer.c: Include <hurd/mm.h>. (hurd_message_buffer_free_internal): Remove function. Move body to... (hurd_message_buffer_free): ... this function. Update users. (BUFFERS_HIGH_WATER): New define. (hurd_message_buffer_alloc): If the number of buffers in the reserve dips below BUFFERS_LOW_WATER, allocate enough to BUFFERS_HIGH_WATER.
-rw-r--r--libhurd-mm/ChangeLog11
-rw-r--r--libhurd-mm/message-buffer.c54
2 files changed, 40 insertions, 25 deletions
diff --git a/libhurd-mm/ChangeLog b/libhurd-mm/ChangeLog
index eda3af9..72e5856 100644
--- a/libhurd-mm/ChangeLog
+++ b/libhurd-mm/ChangeLog
@@ -1,3 +1,14 @@
+2008-12-18 Neal H. Walfield <neal@gnu.org>
+
+ * message-buffer.c: Include <hurd/mm.h>.
+ (hurd_message_buffer_free_internal): Remove function. Move body
+ to...
+ (hurd_message_buffer_free): ... this function. Update users.
+ (BUFFERS_HIGH_WATER): New define.
+ (hurd_message_buffer_alloc): If the number of buffers in the
+ reserve dips below BUFFERS_LOW_WATER, allocate enough to
+ BUFFERS_HIGH_WATER.
+
2008-12-17 Neal H. Walfield <neal@gnu.org>
* as-build-custom.c (as_insert_custom): Don't use vg_cap_copy but
diff --git a/libhurd-mm/message-buffer.c b/libhurd-mm/message-buffer.c
index faa15de..461a3a3 100644
--- a/libhurd-mm/message-buffer.c
+++ b/libhurd-mm/message-buffer.c
@@ -24,6 +24,7 @@
#include <hurd/as.h>
#include <hurd/startup.h>
#include <hurd/capalloc.h>
+#include <hurd/mm.h>
extern struct hurd_startup_data *__hurd_startup_data;
@@ -48,7 +49,8 @@ slab_alloc (void *hook, size_t size, void **ptr)
struct storage storage = storage_alloc (meta_data_activity, vg_cap_page,
STORAGE_LONG_LIVED,
- VG_OBJECT_POLICY_DEFAULT, VG_ADDR_VOID);
+ VG_OBJECT_POLICY_DEFAULT,
+ VG_ADDR_VOID);
if (VG_ADDR_IS_VOID (storage.addr))
panic ("Out of space.");
*ptr = VG_ADDR_TO_PTR (vg_addr_extend (storage.addr, 0, PAGESIZE_LOG2));
@@ -154,8 +156,8 @@ hurd_message_buffer_alloc_hard (void)
/* Weaken it. */
#if 0
mb->receiver = capalloc ();
- struct vg_cap receiver_cap = as_cap_lookup (mb->receiver_strong, vg_cap_messenger,
- NULL);
+ struct vg_cap receiver_cap = as_cap_lookup (mb->receiver_strong,
+ vg_cap_messenger, NULL);
assert (receiver_cap.type == vg_cap_messenger);
as_slot_lookup_use
(mb->receiver,
@@ -181,7 +183,8 @@ hurd_message_buffer_alloc_hard (void)
if (VG_ADDR_IS_VOID (storage.addr))
panic ("Out of space.");
- mb->request = VG_ADDR_TO_PTR (vg_addr_extend (storage.addr, 0, PAGESIZE_LOG2));
+ mb->request = VG_ADDR_TO_PTR (vg_addr_extend (storage.addr,
+ 0, PAGESIZE_LOG2));
}
/* And the receive buffer. */
@@ -195,7 +198,8 @@ hurd_message_buffer_alloc_hard (void)
if (VG_ADDR_IS_VOID (storage.addr))
panic ("Out of space.");
- mb->reply = VG_ADDR_TO_PTR (vg_addr_extend (storage.addr, 0, PAGESIZE_LOG2));
+ mb->reply = VG_ADDR_TO_PTR (vg_addr_extend (storage.addr,
+ 0, PAGESIZE_LOG2));
}
@@ -244,9 +248,8 @@ hurd_message_buffer_alloc_hard (void)
static struct hurd_message_buffer *buffers;
static int buffers_count;
-static void
-hurd_message_buffer_free_internal (struct hurd_message_buffer *buffer,
- bool already_accounted)
+void
+hurd_message_buffer_free (struct hurd_message_buffer *buffer)
{
/* XXX We should perhaps free some buffers if we go over a high
water mark. */
@@ -259,20 +262,14 @@ hurd_message_buffer_free_internal (struct hurd_message_buffer *buffer,
if (__sync_val_compare_and_swap (&buffers, buffer->next, buffer)
== buffer->next)
{
- if (! already_accounted)
- __sync_fetch_and_add (&buffers_count, 1);
+ __sync_fetch_and_add (&buffers_count, 1);
return;
}
}
}
-void
-hurd_message_buffer_free (struct hurd_message_buffer *buffer)
-{
- hurd_message_buffer_free_internal (buffer, false);
-}
-
#define BUFFERS_LOW_WATER 4
+#define BUFFERS_HIGH_WATER 8
struct hurd_message_buffer *
hurd_message_buffer_alloc (void)
@@ -280,19 +277,26 @@ hurd_message_buffer_alloc (void)
struct hurd_message_buffer *mb;
do
{
-#if 0
+ static int allocating;
+
if (likely (mm_init_done)
- && unlikely (buffers_count <= BUFFERS_LOW_WATER))
+ && unlikely (buffers_count <= BUFFERS_LOW_WATER)
+ && ! allocating
+ && __sync_val_compare_and_swap (&allocating, 0, 1) == 1)
{
- int i = BUFFERS_LOW_WATER;
- mb = hurd_message_buffer_alloc_hard ();
+ for (;;)
+ {
+ mb = hurd_message_buffer_alloc_hard ();
- if (buffers_count == BUFFERS_LOW_WATER)
- return mb;
+ if (buffers_count == BUFFERS_HIGH_WATER)
+ break;
- hurd_message_buffer_free_internal (buffer, true);
- }
-#endif
+ hurd_message_buffer_free (mb);
+ }
+
+ allocating = 0;
+ return mb;
+ }
mb = buffers;
if (! mb)