diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-05-03 03:53:41 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-09-29 17:03:57 +0200 |
commit | b2ae574d39adfe283c61a3ec0c766e8780f345af (patch) | |
tree | 994d77346507f28b621a4a573f87f1f1e890e097 /libports/reallocate-port.c | |
parent | 02c47da17b716bfff20bfafe2d5958b2b720ff49 (diff) |
libports: use a global hash table for the lookups
Previously, libports used a hash table per port bucket. This makes
looking up a port difficult if one does not know the port bucket, as
one has to iterate over all buckets and do a hash table lookup each.
Having to iterate over the buckets makes it necessary to keep a list
of all buckets, which has to be updated and protected by a lock as
well.
Also, the current code in _ports_bucket_class_iterate iterates over
the hash table associated with the bucket given. When
ports_class_iterate calls this common function, it obtains a reference
to the bucket from one of the ports in the given class. This will not
work if a class contains ports in different port buckets. This
limitation is not documented as far as I can see. Again, having to
maintain this list has its cost and requires serialization.
Use a global hash table for lookups instead. Keep the per-bucket hash
tables for efficient iteration over buckets. Furthermore, serialize
access to all hash tables using a separate lock. Remove the linked
lists of all buckets and all ports in a class.
* libports/bucket-iterate.c (ports_bucket_iterate): Acquire
_ports_htable_lock. Also, generalize ports_bucket_iterate so that it
takes a pointer to a hash table as first argument.
(ports_bucket_iterate): Ajust call to former function accordingly.
* libports/class-iterate.c (ports_class_iterate): Just call the
generalized _ports_bucket_class_iterate with the global hash table as
argument.
* libports/ports.h (struct port_info): Remove the port class links.
(struct port_bucket): Remove the hash table, and the all buckets link.
(_ports_all_buckets): Remove declaration.
(_ports_htable): New global hash table.
(_ports_htable_lock): Protected by this lock.
* libports/claim-right.c: Adjust accordingly.
* libports/complete-deallocate.c: Likewise.
* libports/create-bucket.c: Likewise.
* libports/create-class.c: Likewise.
* libports/create-internal.c: Likewise.
* libports/destroy-right.c: Likewise.
* libports/import-port.c: Likewise.
* libports/lookup-port.c: Likewise.
* libports/reallocate-from-external.c: Likewise.
* libports/reallocate-port.c: Likewise.
* libports/transfer-right.c: Likewise.
* libports/inhibit-all-rpcs.c: Iterate over the hash table.
* libports/inhibit-bucket-rpcs.c: Likewise, but filter using bucket.
* libports/inhibit-class-rpcs.c: Likewise, but filter using class.
* libports/init.c (_ports_htable): Initialize.
(_ports_htable_lock): Likewise.
Diffstat (limited to 'libports/reallocate-port.c')
-rw-r--r-- | libports/reallocate-port.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/libports/reallocate-port.c b/libports/reallocate-port.c index d2adaebb..cc534eb4 100644 --- a/libports/reallocate-port.c +++ b/libports/reallocate-port.c @@ -36,7 +36,10 @@ ports_reallocate_port (void *portstruct) MACH_PORT_RIGHT_RECEIVE, -1); assert_perror (err); + pthread_rwlock_wrlock (&_ports_htable_lock); + hurd_ihash_locp_remove (&_ports_htable, pi->ports_htable_entry); hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry); + pthread_rwlock_unlock (&_ports_htable_lock); err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &pi->port_right); @@ -48,9 +51,13 @@ ports_reallocate_port (void *portstruct) } pi->cancel_threshold = 0; pi->mscount = 0; - err = hurd_ihash_add (&pi->bucket->htable, pi->port_right, pi); + pthread_rwlock_wrlock (&_ports_htable_lock); + err = hurd_ihash_add (&_ports_htable, pi->port_right, pi); assert_perror (err); + err = hurd_ihash_add (&pi->bucket->htable, pi->port_right, pi); + pthread_rwlock_unlock (&_ports_htable_lock); pthread_mutex_unlock (&_ports_lock); + assert_perror (err); err = mach_port_move_member (mach_task_self (), pi->port_right, pi->bucket->portset); |