[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 3/9] libports: reduce malloc overhead in _ports_bucket_class_iter
From: |
Justus Winter |
Subject: |
[PATCH 3/9] libports: reduce malloc overhead in _ports_bucket_class_iterate |
Date: |
Mon, 28 Apr 2014 12:19:58 +0200 |
_ports_bucket_class_iterate creates a snapshot of the buckets hash
table. This is done so that the lock protecting the hash table can be
released while we iterate over the snapshot.
Formerly, a linked list was used to store the snapshot. As the
maximal number of items is known, using an array is much simpler.
_ports_bucket_class_iterate implements both ports_bucket_iterate and
ports_class_iterate. For this change might make ports_class_iterate
less efficient memory-wise if the number of ports belonging to the
class is low with respect to the number of ports in the bucket.
However, the array representation is more compact. Furthermore a
survey of the Hurd code revealed that ports_class_iterate is rarely
used, while ports_bucket_iterate is used more often, most prominently
in paging code.
* libports/bucket-iterate.c (_ports_bucket_class_iterate): Use an
array instead of a linked list.
---
libports/bucket-iterate.c | 37 +++++++++++++++++++++----------------
1 file changed, 21 insertions(+), 16 deletions(-)
diff --git a/libports/bucket-iterate.c b/libports/bucket-iterate.c
index dc1c7b1..8e6bdc4 100644
--- a/libports/bucket-iterate.c
+++ b/libports/bucket-iterate.c
@@ -31,40 +31,45 @@ _ports_bucket_class_iterate (struct port_bucket *bucket,
{
/* This is obscenely ineffecient. ihash and ports need to cooperate
more closely to do it efficiently. */
- struct item
- {
- struct item *next;
- void *p;
- } *list = 0;
- struct item *i, *nxt;
+ void **p;
+ size_t i, n;
error_t err;
pthread_mutex_lock (&_ports_lock);
+
+ if (bucket->htable.nr_items == 0)
+ {
+ pthread_mutex_unlock (&_ports_lock);
+ return 0;
+ }
+
+ p = malloc (bucket->htable.nr_items * sizeof *p);
+ if (p == NULL)
+ return ENOMEM;
+
+ n = 0;
HURD_IHASH_ITERATE (&bucket->htable, arg)
{
struct port_info *const pi = arg;
- struct item *j;
if (class == 0 || pi->class == class)
{
- j = malloc (sizeof (struct item));
- j->next = list;
- j->p = pi;
- list = j;
pi->refcnt++;
+ p[n] = pi;
+ n++;
}
}
pthread_mutex_unlock (&_ports_lock);
err = 0;
- for (i = list; i; i = nxt)
+ for (i = 0; i < n; i++)
{
if (!err)
- err = (*fun)(i->p);
- ports_port_deref (i->p);
- nxt = i->next;
- free (i);
+ err = (*fun)(p[i]);
+ ports_port_deref (p[i]);
}
+
+ free (p);
return err;
}
--
1.9.2
- let's make libpager single-threaded, Justus Winter, 2014/04/28
- [PATCH 4/9] exec: abbreviate the task name if necessary, Justus Winter, 2014/04/28
- [PATCH 5/9] ext2fs: fix type of inum, Justus Winter, 2014/04/28
- [PATCH 7/9] ext2fs: use two distinct pager buckets for the disk and file pager, Justus Winter, 2014/04/28
- [PATCH 9/9] libpager: remove all the unused seqno parameters, Justus Winter, 2014/04/28