diff options
3 files changed, 0 insertions, 1002 deletions
diff --git a/debian/patches/0001-libports-use-a-global-hash-table-for-the-lookups.patch b/debian/patches/0001-libports-use-a-global-hash-table-for-the-lookups.patch deleted file mode 100644 index 9c140dac..00000000 --- a/debian/patches/0001-libports-use-a-global-hash-table-for-the-lookups.patch +++ /dev/null @@ -1,660 +0,0 @@ -From 06639558e5128a3cf4f35a362526248e3b969576 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Sat, 3 May 2014 03:53:41 +0200 -Subject: [PATCH 1/2] 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. ---- - libports/bucket-iterate.c | 16 +++++++++------- - libports/claim-right.c | 5 ++++- - libports/class-iterate.c | 10 +--------- - libports/complete-deallocate.c | 7 +++---- - libports/create-bucket.c | 6 ------ - libports/create-class.c | 1 - - libports/create-internal.c | 19 +++++++++++++------ - libports/destroy-right.c | 5 +++-- - libports/import-port.c | 19 +++++++++++++------ - libports/inhibit-all-rpcs.c | 27 +++++++++++++-------------- - libports/inhibit-bucket-rpcs.c | 3 ++- - libports/inhibit-class-rpcs.c | 27 ++++++++++++++++++--------- - libports/init.c | 7 ++++++- - libports/lookup-port.c | 23 +++++++++-------------- - libports/ports.h | 22 +++++++++++++++++----- - libports/reallocate-from-external.c | 15 +++++++++++---- - libports/reallocate-port.c | 9 ++++++++- - libports/transfer-right.c | 18 ++++++++++++++---- - 18 files changed, 144 insertions(+), 95 deletions(-) - -diff --git a/libports/bucket-iterate.c b/libports/bucket-iterate.c -index 2d1b00d..79b6d72 100644 ---- a/libports/bucket-iterate.c -+++ b/libports/bucket-iterate.c -@@ -25,7 +25,7 @@ - /* Internal entrypoint for both ports_bucket_iterate and ports_class_iterate. - If CLASS is non-null, call FUN only for ports in that class. */ - error_t --_ports_bucket_class_iterate (struct port_bucket *bucket, -+_ports_bucket_class_iterate (struct hurd_ihash *ht, - struct port_class *class, - error_t (*fun)(void *)) - { -@@ -36,23 +36,24 @@ _ports_bucket_class_iterate (struct port_bucket *bucket, - error_t err; - - pthread_mutex_lock (&_ports_lock); -+ pthread_rwlock_rdlock (&_ports_htable_lock); - -- if (bucket->htable.nr_items == 0) -+ if (ht->nr_items == 0) - { -- pthread_mutex_unlock (&_ports_lock); -+ pthread_rwlock_unlock (&_ports_htable_lock); - return 0; - } - -- nr_items = bucket->htable.nr_items; -+ nr_items = ht->nr_items; - p = malloc (nr_items * sizeof *p); - if (p == NULL) - { -- pthread_mutex_unlock (&_ports_lock); -+ pthread_rwlock_unlock (&_ports_htable_lock); - return ENOMEM; - } - - n = 0; -- HURD_IHASH_ITERATE (&bucket->htable, arg) -+ HURD_IHASH_ITERATE (ht, arg) - { - struct port_info *const pi = arg; - -@@ -63,6 +64,7 @@ _ports_bucket_class_iterate (struct port_bucket *bucket, - n++; - } - } -+ pthread_rwlock_unlock (&_ports_htable_lock); - pthread_mutex_unlock (&_ports_lock); - - if (n != 0 && n != nr_items) -@@ -89,5 +91,5 @@ error_t - ports_bucket_iterate (struct port_bucket *bucket, - error_t (*fun)(void *)) - { -- return _ports_bucket_class_iterate (bucket, 0, fun); -+ return _ports_bucket_class_iterate (&bucket->htable, NULL, fun); - } -diff --git a/libports/claim-right.c b/libports/claim-right.c -index 4851ea3..85592ff 100644 ---- a/libports/claim-right.c -+++ b/libports/claim-right.c -@@ -34,10 +34,13 @@ ports_claim_right (void *portstruct) - if (ret == MACH_PORT_NULL) - return ret; - -- pthread_mutex_lock (&_ports_lock); -+ 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_move_member (mach_task_self (), ret, MACH_PORT_NULL); - assert_perror (err); -+ pthread_mutex_lock (&_ports_lock); - pi->port_right = MACH_PORT_NULL; - if (pi->flags & PORT_HAS_SENDRIGHTS) - { -diff --git a/libports/class-iterate.c b/libports/class-iterate.c -index 1f8878a..df33818 100644 ---- a/libports/class-iterate.c -+++ b/libports/class-iterate.c -@@ -23,13 +23,5 @@ error_t - ports_class_iterate (struct port_class *class, - error_t (*fun)(void *)) - { -- pthread_mutex_lock (&_ports_lock); -- if (class->ports != 0) -- { -- struct port_bucket *bucket = class->ports->bucket; -- pthread_mutex_unlock (&_ports_lock); -- return _ports_bucket_class_iterate (bucket, class, fun); -- } -- pthread_mutex_unlock (&_ports_lock); -- return 0; -+ return _ports_bucket_class_iterate (&_ports_htable, class, fun); - } -diff --git a/libports/complete-deallocate.c b/libports/complete-deallocate.c -index 8ce095b..4768dab 100644 ---- a/libports/complete-deallocate.c -+++ b/libports/complete-deallocate.c -@@ -29,16 +29,15 @@ _ports_complete_deallocate (struct port_info *pi) - - if (pi->port_right) - { -+ 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); - mach_port_mod_refs (mach_task_self (), pi->port_right, - MACH_PORT_RIGHT_RECEIVE, -1); - pi->port_right = MACH_PORT_NULL; - } - -- *pi->prevp = pi->next; -- if (pi->next) -- pi->next->prevp = pi->prevp; -- - pi->bucket->count--; - pi->class->count--; - -diff --git a/libports/create-bucket.c b/libports/create-bucket.c -index 52d50c3..2c5f1b6 100644 ---- a/libports/create-bucket.c -+++ b/libports/create-bucket.c -@@ -48,11 +48,5 @@ ports_create_bucket () - - hurd_ihash_init (&ret->htable, offsetof (struct port_info, hentry)); - ret->rpcs = ret->flags = ret->count = 0; -- -- pthread_mutex_lock (&_ports_lock); -- ret->next = _ports_all_buckets; -- _ports_all_buckets = ret; -- pthread_mutex_unlock (&_ports_lock); -- - return ret; - } -diff --git a/libports/create-class.c b/libports/create-class.c -index 12c8add..782f52b 100644 ---- a/libports/create-class.c -+++ b/libports/create-class.c -@@ -39,7 +39,6 @@ ports_create_class (void (*clean_routine)(void *), - cl->dropweak_routine = dropweak_routine; - cl->flags = 0; - cl->rpcs = 0; -- cl->ports = NULL; - cl->count = 0; - cl->uninhibitable_rpcs = ports_default_uninhibitable_rpcs; - -diff --git a/libports/create-internal.c b/libports/create-internal.c -index 8551297..8543986 100644 ---- a/libports/create-internal.c -+++ b/libports/create-internal.c -@@ -81,15 +81,22 @@ _ports_create_port_internal (struct port_class *class, - goto loop; - } - -+ pthread_rwlock_wrlock (&_ports_htable_lock); -+ err = hurd_ihash_add (&_ports_htable, port, pi); -+ if (err) -+ { -+ pthread_rwlock_unlock (&_ports_htable_lock); -+ goto lose; -+ } - err = hurd_ihash_add (&bucket->htable, port, pi); - if (err) -- goto lose; -+ { -+ hurd_ihash_locp_remove (&_ports_htable, pi->ports_htable_entry); -+ pthread_rwlock_unlock (&_ports_htable_lock); -+ goto lose; -+ } -+ pthread_rwlock_unlock (&_ports_htable_lock); - -- pi->next = class->ports; -- pi->prevp = &class->ports; -- if (class->ports) -- class->ports->prevp = &pi->next; -- class->ports = pi; - bucket->count++; - class->count++; - pthread_mutex_unlock (&_ports_lock); -diff --git a/libports/destroy-right.c b/libports/destroy-right.c -index 65e19c7..448b379 100644 ---- a/libports/destroy-right.c -+++ b/libports/destroy-right.c -@@ -30,12 +30,13 @@ ports_destroy_right (void *portstruct) - - if (pi->port_right != MACH_PORT_NULL) - { -- pthread_mutex_lock (&_ports_lock); -+ 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_mod_refs (mach_task_self (), pi->port_right, - MACH_PORT_RIGHT_RECEIVE, -1); - assert_perror (err); -- pthread_mutex_unlock (&_ports_lock); - - pi->port_right = MACH_PORT_NULL; - -diff --git a/libports/import-port.c b/libports/import-port.c -index 226f47e..2660672 100644 ---- a/libports/import-port.c -+++ b/libports/import-port.c -@@ -75,15 +75,22 @@ ports_import_port (struct port_class *class, struct port_bucket *bucket, - goto loop; - } - -+ pthread_rwlock_wrlock (&_ports_htable_lock); -+ err = hurd_ihash_add (&_ports_htable, port, pi); -+ if (err) -+ { -+ pthread_rwlock_unlock (&_ports_htable_lock); -+ goto lose; -+ } - err = hurd_ihash_add (&bucket->htable, port, pi); - if (err) -- goto lose; -+ { -+ hurd_ihash_locp_remove (&_ports_htable, pi->ports_htable_entry); -+ pthread_rwlock_unlock (&_ports_htable_lock); -+ goto lose; -+ } -+ pthread_rwlock_unlock (&_ports_htable_lock); - -- pi->next = class->ports; -- pi->prevp = &class->ports; -- if (class->ports) -- class->ports->prevp = &pi->next; -- class->ports = pi; - bucket->count++; - class->count++; - pthread_mutex_unlock (&_ports_lock); -diff --git a/libports/inhibit-all-rpcs.c b/libports/inhibit-all-rpcs.c -index d4a54ba..27e2ec5 100644 ---- a/libports/inhibit-all-rpcs.c -+++ b/libports/inhibit-all-rpcs.c -@@ -36,24 +36,23 @@ ports_inhibit_all_rpcs () - struct port_bucket *bucket; - int this_one = 0; - -- for (bucket = _ports_all_buckets; bucket; bucket = bucket->next) -+ pthread_rwlock_rdlock (&_ports_htable_lock); -+ HURD_IHASH_ITERATE (&_ports_htable, portstruct) - { -- HURD_IHASH_ITERATE (&bucket->htable, portstruct) -+ struct rpc_info *rpc; -+ struct port_info *pi = portstruct; -+ -+ for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) - { -- struct rpc_info *rpc; -- struct port_info *pi = portstruct; -- -- for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) -- { -- /* Avoid cancelling the calling thread if it's currently -- handling a RPC. */ -- if (rpc->thread == hurd_thread_self ()) -- this_one = 1; -- else -- hurd_thread_cancel (rpc->thread); -- } -+ /* Avoid cancelling the calling thread if it's currently -+ handling a RPC. */ -+ if (rpc->thread == hurd_thread_self ()) -+ this_one = 1; -+ else -+ hurd_thread_cancel (rpc->thread); - } - } -+ pthread_rwlock_unlock (&_ports_htable_lock); - - while (_ports_total_rpcs > this_one) - { -diff --git a/libports/inhibit-bucket-rpcs.c b/libports/inhibit-bucket-rpcs.c -index 965aa03..82efdf5 100644 ---- a/libports/inhibit-bucket-rpcs.c -+++ b/libports/inhibit-bucket-rpcs.c -@@ -35,6 +35,7 @@ ports_inhibit_bucket_rpcs (struct port_bucket *bucket) - { - int this_one = 0; - -+ pthread_rwlock_rdlock (&_ports_htable_lock); - HURD_IHASH_ITERATE (&bucket->htable, portstruct) - { - struct rpc_info *rpc; -@@ -49,7 +50,7 @@ ports_inhibit_bucket_rpcs (struct port_bucket *bucket) - hurd_thread_cancel (rpc->thread); - } - } -- -+ pthread_rwlock_unlock (&_ports_htable_lock); - - while (bucket->rpcs > this_one) - { -diff --git a/libports/inhibit-class-rpcs.c b/libports/inhibit-class-rpcs.c -index 7ee8653..9a87a5f 100644 ---- a/libports/inhibit-class-rpcs.c -+++ b/libports/inhibit-class-rpcs.c -@@ -36,15 +36,24 @@ ports_inhibit_class_rpcs (struct port_class *class) - struct rpc_info *rpc; - int this_one = 0; - -- for (pi = class->ports; pi; pi = pi->next) -- for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) -- { -- /* Avoid cancelling the calling thread. */ -- if (rpc->thread == hurd_thread_self ()) -- this_one = 1; -- else -- hurd_thread_cancel (rpc->thread); -- } -+ pthread_rwlock_rdlock (&_ports_htable_lock); -+ HURD_IHASH_ITERATE (&_ports_htable, portstruct) -+ { -+ struct rpc_info *rpc; -+ struct port_info *pi = portstruct; -+ if (pi->class != class) -+ continue; -+ -+ for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) -+ { -+ /* Avoid cancelling the calling thread. */ -+ if (rpc->thread == hurd_thread_self ()) -+ this_one = 1; -+ else -+ hurd_thread_cancel (rpc->thread); -+ } -+ } -+ pthread_rwlock_unlock (&_ports_htable_lock); - - while (class->rpcs > this_one) - { -diff --git a/libports/init.c b/libports/init.c -index 3ef5388..4a68cb8 100644 ---- a/libports/init.c -+++ b/libports/init.c -@@ -19,9 +19,14 @@ - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - #include "ports.h" -+#include <stddef.h> - - pthread_mutex_t _ports_lock = PTHREAD_MUTEX_INITIALIZER; - pthread_cond_t _ports_block = PTHREAD_COND_INITIALIZER; --struct port_bucket *_ports_all_buckets; -+ -+struct hurd_ihash _ports_htable = -+ HURD_IHASH_INITIALIZER (offsetof (struct port_info, ports_htable_entry)); -+pthread_rwlock_t _ports_htable_lock = PTHREAD_RWLOCK_INITIALIZER; -+ - int _ports_total_rpcs; - int _ports_flags; -diff --git a/libports/lookup-port.c b/libports/lookup-port.c -index f79f6f0..858ee11 100644 ---- a/libports/lookup-port.c -+++ b/libports/lookup-port.c -@@ -26,27 +26,22 @@ ports_lookup_port (struct port_bucket *bucket, - mach_port_t port, - struct port_class *class) - { -- struct port_info *pi = 0; -- -+ struct port_info *pi; -+ - pthread_mutex_lock (&_ports_lock); -+ pthread_rwlock_rdlock (&_ports_htable_lock); - -- if (bucket) -- pi = hurd_ihash_find (&bucket->htable, port); -- else -- for (bucket = _ports_all_buckets; bucket; bucket = bucket->next) -- { -- pi = hurd_ihash_find (&bucket->htable, port); -- if (pi) -- break; -- } -- -- if (pi && class && pi->class != class) -+ pi = hurd_ihash_find (&_ports_htable, port); -+ if (pi -+ && ((class && pi->class != class) -+ || (bucket && pi->bucket != bucket))) - pi = 0; - - if (pi) - pi->refcnt++; - -+ pthread_rwlock_unlock (&_ports_htable_lock); - pthread_mutex_unlock (&_ports_lock); -- -+ - return pi; - } -diff --git a/libports/ports.h b/libports/ports.h -index 7f13124..6922162 100644 ---- a/libports/ports.h -+++ b/libports/ports.h -@@ -48,7 +48,7 @@ struct port_info - struct rpc_info *current_rpcs; - struct port_bucket *bucket; - hurd_ihash_locp_t hentry; -- struct port_info *next, **prevp; /* links on port_class list */ -+ hurd_ihash_locp_t ports_htable_entry; - }; - typedef struct port_info *port_info_t; - -@@ -61,11 +61,12 @@ typedef struct port_info *port_info_t; - struct port_bucket - { - mach_port_t portset; -+ /* Per-bucket hash table used for fast iteration. Access must be -+ serialized using _ports_htable_lock. */ - struct hurd_ihash htable; - int rpcs; - int flags; - int count; -- struct port_bucket *next; - }; - /* FLAGS above are the following: */ - #define PORT_BUCKET_INHIBITED PORTS_INHIBITED -@@ -78,7 +79,6 @@ struct port_class - { - int flags; - int rpcs; -- struct port_info *ports; - int count; - void (*clean_routine) (void *); - void (*dropweak_routine) (void *); -@@ -277,7 +277,7 @@ error_t ports_class_iterate (struct port_class *class, - error_t (*fun)(void *port)); - - /* Internal entrypoint for above two. */ --error_t _ports_bucket_class_iterate (struct port_bucket *bucket, -+error_t _ports_bucket_class_iterate (struct hurd_ihash *ht, - struct port_class *class, - error_t (*fun)(void *port)); - -@@ -402,7 +402,19 @@ extern kern_return_t - /* Private data */ - extern pthread_mutex_t _ports_lock; - extern pthread_cond_t _ports_block; --extern struct port_bucket *_ports_all_buckets; -+ -+/* A global hash table mapping port names to port_info objects. This -+ table is used for port lookups and to iterate over classes. -+ -+ A port in this hash table carries an implicit light reference. -+ When the reference counts reach zero, we call -+ _ports_complete_deallocate. There we reacquire our lock -+ momentarily to check whether someone else reacquired a reference -+ through the hash table. */ -+extern struct hurd_ihash _ports_htable; -+/* Access to the hash table is protected by this lock. */ -+extern pthread_rwlock_t _ports_htable_lock; -+ - extern int _ports_total_rpcs; - extern int _ports_flags; - #define _PORTS_INHIBITED PORTS_INHIBITED -diff --git a/libports/reallocate-from-external.c b/libports/reallocate-from-external.c -index 8cccb2a..9944b39 100644 ---- a/libports/reallocate-from-external.c -+++ b/libports/reallocate-from-external.c -@@ -43,8 +43,11 @@ ports_reallocate_from_external (void *portstruct, mach_port_t receive) - 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); -+ - if ((pi->flags & PORT_HAS_SENDRIGHTS) && !stat.mps_srights) - { - dropref = 1; -@@ -59,11 +62,15 @@ ports_reallocate_from_external (void *portstruct, mach_port_t receive) - pi->port_right = receive; - pi->cancel_threshold = 0; - pi->mscount = stat.mps_mscount; -- -- err = hurd_ihash_add (&pi->bucket->htable, receive, pi); -+ -+ pthread_rwlock_wrlock (&_ports_htable_lock); -+ err = hurd_ihash_add (&_ports_htable, receive, pi); - assert_perror (err); -+ err = hurd_ihash_add (&pi->bucket->htable, receive, pi); -+ pthread_rwlock_unlock (&_ports_htable_lock); - pthread_mutex_unlock (&_ports_lock); -- -+ assert_perror (err); -+ - mach_port_move_member (mach_task_self (), receive, pi->bucket->portset); - - if (stat.mps_srights) -diff --git a/libports/reallocate-port.c b/libports/reallocate-port.c -index d2adaeb..cc534eb 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); -diff --git a/libports/transfer-right.c b/libports/transfer-right.c -index 72488a9..3f48290 100644 ---- a/libports/transfer-right.c -+++ b/libports/transfer-right.c -@@ -41,7 +41,10 @@ ports_transfer_right (void *tostruct, - port = frompi->port_right; - if (port != MACH_PORT_NULL) - { -+ pthread_rwlock_wrlock (&_ports_htable_lock); -+ hurd_ihash_locp_remove (&_ports_htable, frompi->ports_htable_entry); - hurd_ihash_locp_remove (&frompi->bucket->htable, frompi->hentry); -+ pthread_rwlock_unlock (&_ports_htable_lock); - frompi->port_right = MACH_PORT_NULL; - if (frompi->flags & PORT_HAS_SENDRIGHTS) - { -@@ -54,7 +57,10 @@ ports_transfer_right (void *tostruct, - /* Destroy the existing right in TOPI. */ - if (topi->port_right != MACH_PORT_NULL) - { -+ pthread_rwlock_wrlock (&_ports_htable_lock); -+ hurd_ihash_locp_remove (&_ports_htable, topi->ports_htable_entry); - hurd_ihash_locp_remove (&topi->bucket->htable, topi->hentry); -+ pthread_rwlock_unlock (&_ports_htable_lock); - err = mach_port_mod_refs (mach_task_self (), topi->port_right, - MACH_PORT_RIGHT_RECEIVE, -1); - assert_perror (err); -@@ -74,10 +80,16 @@ ports_transfer_right (void *tostruct, - topi->port_right = port; - topi->cancel_threshold = frompi->cancel_threshold; - topi->mscount = frompi->mscount; -- -+ -+ pthread_mutex_unlock (&_ports_lock); -+ - if (port) - { -+ pthread_rwlock_wrlock (&_ports_htable_lock); -+ err = hurd_ihash_add (&_ports_htable, port, topi); -+ assert_perror (err); - err = hurd_ihash_add (&topi->bucket->htable, port, topi); -+ pthread_rwlock_unlock (&_ports_htable_lock); - assert_perror (err); - if (topi->bucket != frompi->bucket) - { -@@ -86,9 +98,7 @@ ports_transfer_right (void *tostruct, - assert_perror (err); - } - } -- -- pthread_mutex_unlock (&_ports_lock); -- -+ - /* Take care of any lowered reference counts. */ - if (dereffrompi) - ports_port_deref (frompi); --- -2.1.0 - diff --git a/debian/patches/0002-libports-lock-less-reference-counting-for-port_info-.patch b/debian/patches/0002-libports-lock-less-reference-counting-for-port_info-.patch deleted file mode 100644 index 792b9a8c..00000000 --- a/debian/patches/0002-libports-lock-less-reference-counting-for-port_info-.patch +++ /dev/null @@ -1,340 +0,0 @@ -From ac71c88e57d35b4d8b1548b661be523d7d137a10 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Sat, 3 May 2014 01:02:35 +0200 -Subject: [PATCH 2/2] libports: lock-less reference counting for port_info - objects - -* libports/ports.h (struct port_info): Use the new type. -* libports/lookup-port.c: No need to lock _ports_lock anymore. -* libports/bucket-iterate.c: Likewise. -* libports/complete-deallocate.c: Check if someone reacquired a -reference through a hash table lookup. -* libports/create-internal.c: Use the new reference counting primitives. -* libports/get-right.c: Likewise. -* libports/import-port.c: Likewise. -* libports/port-deref-weak.c: Likewise. -* libports/port-deref.c: Likewise. -* libports/port-ref-weak.c: Likewise. -* libports/port-ref.c: Likewise. -* libports/reallocate-from-external.c: Likewise. -* libports/transfer-right.c: Likewise. -* utils/rpctrace.c: Likewise. ---- - libports/bucket-iterate.c | 4 +--- - libports/complete-deallocate.c | 14 ++++++++++++++ - libports/create-internal.c | 3 +-- - libports/get-right.c | 2 +- - libports/import-port.c | 3 +-- - libports/lookup-port.c | 4 +--- - libports/port-deref-weak.c | 10 +++------- - libports/port-deref.c | 34 ++++++++++++++++------------------ - libports/port-ref-weak.c | 6 +----- - libports/port-ref.c | 6 +----- - libports/ports.h | 4 ++-- - libports/reallocate-from-external.c | 2 +- - libports/transfer-right.c | 2 +- - utils/rpctrace.c | 10 ++++++++-- - 14 files changed, 52 insertions(+), 52 deletions(-) - -diff --git a/libports/bucket-iterate.c b/libports/bucket-iterate.c -index 79b6d72..b021b99 100644 ---- a/libports/bucket-iterate.c -+++ b/libports/bucket-iterate.c -@@ -35,7 +35,6 @@ _ports_bucket_class_iterate (struct hurd_ihash *ht, - size_t i, n, nr_items; - error_t err; - -- pthread_mutex_lock (&_ports_lock); - pthread_rwlock_rdlock (&_ports_htable_lock); - - if (ht->nr_items == 0) -@@ -59,13 +58,12 @@ _ports_bucket_class_iterate (struct hurd_ihash *ht, - - if (class == 0 || pi->class == class) - { -- pi->refcnt++; -+ refcounts_ref (&pi->refcounts, NULL); - p[n] = pi; - n++; - } - } - pthread_rwlock_unlock (&_ports_htable_lock); -- pthread_mutex_unlock (&_ports_lock); - - if (n != 0 && n != nr_items) - { -diff --git a/libports/complete-deallocate.c b/libports/complete-deallocate.c -index 4768dab..0d852f5 100644 ---- a/libports/complete-deallocate.c -+++ b/libports/complete-deallocate.c -@@ -29,15 +29,29 @@ _ports_complete_deallocate (struct port_info *pi) - - if (pi->port_right) - { -+ struct references result; -+ - pthread_rwlock_wrlock (&_ports_htable_lock); -+ refcounts_references (&pi->refcounts, &result); -+ if (result.hard > 0 || result.weak > 0) -+ { -+ /* A reference was reacquired through a hash table lookup. -+ It's fine, we didn't touch anything yet. */ -+ pthread_mutex_unlock (&_ports_htable_lock); -+ return; -+ } -+ - 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); -+ - mach_port_mod_refs (mach_task_self (), pi->port_right, - MACH_PORT_RIGHT_RECEIVE, -1); - pi->port_right = MACH_PORT_NULL; - } - -+ pthread_mutex_lock (&_ports_lock); -+ - pi->bucket->count--; - pi->class->count--; - -diff --git a/libports/create-internal.c b/libports/create-internal.c -index 8543986..2d85931 100644 ---- a/libports/create-internal.c -+++ b/libports/create-internal.c -@@ -54,8 +54,7 @@ _ports_create_port_internal (struct port_class *class, - } - - pi->class = class; -- pi->refcnt = 1; -- pi->weakrefcnt = 0; -+ refcounts_init (&pi->refcounts, 1, 0); - pi->cancel_threshold = 0; - pi->mscount = 0; - pi->flags = 0; -diff --git a/libports/get-right.c b/libports/get-right.c -index 89050c6..8681f46 100644 ---- a/libports/get-right.c -+++ b/libports/get-right.c -@@ -41,7 +41,7 @@ ports_get_right (void *port) - if ((pi->flags & PORT_HAS_SENDRIGHTS) == 0) - { - pi->flags |= PORT_HAS_SENDRIGHTS; -- pi->refcnt++; -+ refcounts_ref (&pi->refcounts, NULL); - err = mach_port_request_notification (mach_task_self (), - pi->port_right, - MACH_NOTIFY_NO_SENDERS, -diff --git a/libports/import-port.c b/libports/import-port.c -index 2660672..c337c85 100644 ---- a/libports/import-port.c -+++ b/libports/import-port.c -@@ -48,8 +48,7 @@ ports_import_port (struct port_class *class, struct port_bucket *bucket, - return ENOMEM; - - pi->class = class; -- pi->refcnt = 1 + !!stat.mps_srights; -- pi->weakrefcnt = 0; -+ refcounts_init (&pi->refcounts, 1 + !!stat.mps_srights, 0); - pi->cancel_threshold = 0; - pi->mscount = stat.mps_mscount; - pi->flags = stat.mps_srights ? PORT_HAS_SENDRIGHTS : 0; -diff --git a/libports/lookup-port.c b/libports/lookup-port.c -index 858ee11..2f0eee9 100644 ---- a/libports/lookup-port.c -+++ b/libports/lookup-port.c -@@ -28,7 +28,6 @@ ports_lookup_port (struct port_bucket *bucket, - { - struct port_info *pi; - -- pthread_mutex_lock (&_ports_lock); - pthread_rwlock_rdlock (&_ports_htable_lock); - - pi = hurd_ihash_find (&_ports_htable, port); -@@ -38,10 +37,9 @@ ports_lookup_port (struct port_bucket *bucket, - pi = 0; - - if (pi) -- pi->refcnt++; -+ refcounts_unsafe_ref (&pi->refcounts, NULL); - - pthread_rwlock_unlock (&_ports_htable_lock); -- pthread_mutex_unlock (&_ports_lock); - - return pi; - } -diff --git a/libports/port-deref-weak.c b/libports/port-deref-weak.c -index beb4842..8432660 100644 ---- a/libports/port-deref-weak.c -+++ b/libports/port-deref-weak.c -@@ -25,12 +25,8 @@ void - ports_port_deref_weak (void *portstruct) - { - struct port_info *pi = portstruct; -- -- pthread_mutex_lock (&_ports_lock); -- assert (pi->weakrefcnt); -- pi->weakrefcnt--; -- if (pi->refcnt == 0 && pi->weakrefcnt == 0) -+ struct references result; -+ refcounts_deref_weak (&pi->refcounts, &result); -+ if (result.hard == 0 && result.weak == 0) - _ports_complete_deallocate (pi); -- else -- pthread_mutex_unlock (&_ports_lock); - } -diff --git a/libports/port-deref.c b/libports/port-deref.c -index cf9b238..b97dd13 100644 ---- a/libports/port-deref.c -+++ b/libports/port-deref.c -@@ -25,26 +25,24 @@ void - ports_port_deref (void *portstruct) - { - struct port_info *pi = portstruct; -- int trieddroppingweakrefs = 0; -- -- retry: -- -- pthread_mutex_lock (&_ports_lock); -- -- if (pi->refcnt == 1 && pi->weakrefcnt -- && pi->class->dropweak_routine && !trieddroppingweakrefs) -+ struct references result; -+ -+ if (pi->class->dropweak_routine) - { -- pthread_mutex_unlock (&_ports_lock); -- (*pi->class->dropweak_routine) (pi); -- trieddroppingweakrefs = 1; -- goto retry; -+ /* If we need to call the dropweak routine, we need to hold one -+ reference while doing so. We use a weak reference for this -+ purpose, which we acquire by demoting our hard reference to a -+ weak one. */ -+ refcounts_demote (&pi->refcounts, &result); -+ -+ if (result.hard == 0 && result.weak > 1) -+ (*pi->class->dropweak_routine) (pi); -+ -+ refcounts_deref_weak (&pi->refcounts, &result); - } -- -- assert (pi->refcnt); -+ else -+ refcounts_deref (&pi->refcounts, &result); - -- pi->refcnt--; -- if (pi->refcnt == 0 && pi->weakrefcnt == 0) -+ if (result.hard == 0 && result.weak == 0) - _ports_complete_deallocate (pi); -- else -- pthread_mutex_unlock (&_ports_lock); - } -diff --git a/libports/port-ref-weak.c b/libports/port-ref-weak.c -index c7d3c69..3f62dfe 100644 ---- a/libports/port-ref-weak.c -+++ b/libports/port-ref-weak.c -@@ -25,9 +25,5 @@ void - ports_port_ref_weak (void *portstruct) - { - struct port_info *pi = portstruct; -- -- pthread_mutex_lock (&_ports_lock); -- assert (pi->refcnt || pi->weakrefcnt); -- pi->weakrefcnt++; -- pthread_mutex_unlock (&_ports_lock); -+ refcounts_ref_weak (&pi->refcounts, NULL); - } -diff --git a/libports/port-ref.c b/libports/port-ref.c -index 92b7118..9a1c71e 100644 ---- a/libports/port-ref.c -+++ b/libports/port-ref.c -@@ -25,9 +25,5 @@ void - ports_port_ref (void *portstruct) - { - struct port_info *pi = portstruct; -- -- pthread_mutex_lock (&_ports_lock); -- assert (pi->refcnt || pi->weakrefcnt); -- pi->refcnt++; -- pthread_mutex_unlock (&_ports_lock); -+ refcounts_ref (&pi->refcounts, NULL); - } -diff --git a/libports/ports.h b/libports/ports.h -index 6922162..40d3b43 100644 ---- a/libports/ports.h -+++ b/libports/ports.h -@@ -27,6 +27,7 @@ - #include <hurd/ihash.h> - #include <mach/notify.h> - #include <pthread.h> -+#include <refcount.h> - - /* These are global values for common flags used in the various structures. - Not all of these are meaningful in all flag fields. */ -@@ -39,8 +40,7 @@ - struct port_info - { - struct port_class *class; -- int refcnt; -- int weakrefcnt; -+ refcounts_t refcounts; - mach_port_mscount_t mscount; - mach_msg_seqno_t cancel_threshold; - int flags; -diff --git a/libports/reallocate-from-external.c b/libports/reallocate-from-external.c -index 9944b39..7205bd9 100644 ---- a/libports/reallocate-from-external.c -+++ b/libports/reallocate-from-external.c -@@ -56,7 +56,7 @@ ports_reallocate_from_external (void *portstruct, mach_port_t receive) - else if (((pi->flags & PORT_HAS_SENDRIGHTS) == 0) && stat.mps_srights) - { - pi->flags |= PORT_HAS_SENDRIGHTS; -- pi->refcnt++; -+ refcounts_ref (&pi->refcounts, NULL); - } - - pi->port_right = receive; -diff --git a/libports/transfer-right.c b/libports/transfer-right.c -index 3f48290..776a8d2 100644 ---- a/libports/transfer-right.c -+++ b/libports/transfer-right.c -@@ -72,7 +72,7 @@ ports_transfer_right (void *tostruct, - else if (((topi->flags & PORT_HAS_SENDRIGHTS) == 0) && hassendrights) - { - topi->flags |= PORT_HAS_SENDRIGHTS; -- topi->refcnt++; -+ refcounts_ref (&topi->refcounts, NULL); - } - } - -diff --git a/utils/rpctrace.c b/utils/rpctrace.c -index fc913e3..b11fea4 100644 ---- a/utils/rpctrace.c -+++ b/utils/rpctrace.c -@@ -431,7 +431,9 @@ destroy_receiver_info (struct receiver_info *info) - while (send_wrapper) - { - struct sender_info *next = send_wrapper->next; -- assert (TRACED_INFO (send_wrapper)->pi.refcnt == 1); -+ assert ( -+ refcounts_hard_references (&TRACED_INFO (send_wrapper)->pi.refcounts) -+ == 1); - /* Reset the receive_right of the send wrapper in advance to avoid - * destroy_receiver_info is called when the port info is destroyed. */ - send_wrapper->receive_right = NULL; -@@ -848,7 +850,11 @@ rewrite_right (mach_port_t *right, mach_msg_type_name_t *type, - hurd_ihash_locp_remove (&traced_names, receiver_info->locp); - - send_wrapper2 = get_send_wrapper (receiver_info, dest, &rr); -- assert (TRACED_INFO (send_wrapper2)->pi.refcnt == 1); -+ assert ( -+ refcounts_hard_references ( -+ &TRACED_INFO (send_wrapper2)->pi.refcounts) -+ == 1); -+ - name = TRACED_INFO (send_wrapper2)->name; - TRACED_INFO (send_wrapper2)->name = NULL; - /* send_wrapper2 isn't destroyed normally, so we need to unlink --- -2.1.0 - diff --git a/debian/patches/series b/debian/patches/series index 0421e32e..b69b0416 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -55,5 +55,3 @@ fix-net_rcv_msg.patch #pp-random.patch #refcount-use-after-free.patch -0001-libports-use-a-global-hash-table-for-the-lookups.patch -0002-libports-lock-less-reference-counting-for-port_info-.patch |