From 157e44e4f5befe8ba70be069bc8ded43e7c9ed72 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sat, 3 May 2014 04:04:45 +0200 Subject: add libports-per-bucket-hashtable.patch --- debian/patches/libports-per-bucket-hashtable.patch | 1058 ++++++++++++++++++++ debian/patches/series | 1 + 2 files changed, 1059 insertions(+) create mode 100644 debian/patches/libports-per-bucket-hashtable.patch (limited to 'debian') diff --git a/debian/patches/libports-per-bucket-hashtable.patch b/debian/patches/libports-per-bucket-hashtable.patch new file mode 100644 index 00000000..e1406f02 --- /dev/null +++ b/debian/patches/libports-per-bucket-hashtable.patch @@ -0,0 +1,1058 @@ +commit 74ecfb7e8b9249f60deaaf1f516d35a4f825b9dc +Author: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Sat May 3 03:53:41 2014 +0200 + + libports: per-bucket lock for the hash tables + +diff --git a/libports/begin-rpc.c b/libports/begin-rpc.c +index 142af98..de58b06 100644 +--- a/libports/begin-rpc.c ++++ b/libports/begin-rpc.c +@@ -29,14 +29,14 @@ ports_begin_rpc (void *portstruct, mach_msg_id_t msg_id, struct rpc_info *info) + + struct port_info *pi = portstruct; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + + do + { + /* If our receive right is gone, then abandon the RPC. */ + if (pi->port_right == MACH_PORT_NULL) + { +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + return EOPNOTSUPP; + } + +@@ -75,13 +75,13 @@ ports_begin_rpc (void *portstruct, mach_msg_id_t msg_id, struct rpc_info *info) + if (block_flags) + { + *block_flags |= PORTS_BLOCKED; +- if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_lock)) ++ if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_global_lock)) + /* We've been cancelled, just return EINTR. If we were the + only one blocking, PORTS_BLOCKED will still be turned on, + but that's ok, it will just cause a (harmless) extra + pthread_cond_broadcast(). */ + { +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + return EINTR; + } + } +@@ -102,7 +102,7 @@ ports_begin_rpc (void *portstruct, mach_msg_id_t msg_id, struct rpc_info *info) + pi->bucket->rpcs++; + _ports_total_rpcs++; + +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + + return 0; + } +diff --git a/libports/bucket-iterate.c b/libports/bucket-iterate.c +index 38a9f7a..8a306f0 100644 +--- a/libports/bucket-iterate.c ++++ b/libports/bucket-iterate.c +@@ -35,11 +35,11 @@ _ports_bucket_class_iterate (struct port_bucket *bucket, + size_t i, n, nr_items; + error_t err; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&bucket->lock); + + if (bucket->htable.nr_items == 0) + { +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&bucket->lock); + return 0; + } + +@@ -60,7 +60,7 @@ _ports_bucket_class_iterate (struct port_bucket *bucket, + n++; + } + } +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&bucket->lock); + + if (n != nr_items) + { +diff --git a/libports/claim-right.c b/libports/claim-right.c +index 4851ea3..73e383a 100644 +--- a/libports/claim-right.c ++++ b/libports/claim-right.c +@@ -34,19 +34,21 @@ ports_claim_right (void *portstruct) + if (ret == MACH_PORT_NULL) + return ret; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&pi->bucket->lock); + hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry); ++ pthread_mutex_unlock (&pi->bucket->lock); + err = mach_port_move_member (mach_task_self (), ret, MACH_PORT_NULL); + assert_perror (err); ++ pthread_mutex_lock (&_ports_global_lock); + pi->port_right = MACH_PORT_NULL; + if (pi->flags & PORT_HAS_SENDRIGHTS) + { + pi->flags &= ~PORT_HAS_SENDRIGHTS; +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + ports_port_deref (pi); + } + else +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + + return ret; + } +diff --git a/libports/class-iterate.c b/libports/class-iterate.c +index 1f8878a..638dd45 100644 +--- a/libports/class-iterate.c ++++ b/libports/class-iterate.c +@@ -23,13 +23,13 @@ error_t + ports_class_iterate (struct port_class *class, + error_t (*fun)(void *)) + { +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + if (class->ports != 0) + { + struct port_bucket *bucket = class->ports->bucket; +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + return _ports_bucket_class_iterate (bucket, class, fun); + } +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + return 0; + } +diff --git a/libports/complete-deallocate.c b/libports/complete-deallocate.c +index 7e7d467..c08d0ce 100644 +--- a/libports/complete-deallocate.c ++++ b/libports/complete-deallocate.c +@@ -29,13 +29,15 @@ _ports_complete_deallocate (struct port_info *pi) + + if (pi->port_right) + { ++ pthread_mutex_lock (&pi->bucket->lock); + hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry); ++ pthread_mutex_unlock (&pi->bucket->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); ++ pthread_mutex_lock (&_ports_global_lock); + + *pi->prevp = pi->next; + if (pi->next) +@@ -44,7 +46,7 @@ _ports_complete_deallocate (struct port_info *pi) + pi->bucket->count--; + pi->class->count--; + +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + + if (pi->class->clean_routine) + (*pi->class->clean_routine)(pi); +diff --git a/libports/count-bucket.c b/libports/count-bucket.c +index 63feb6b..8e6eadb 100644 +--- a/libports/count-bucket.c ++++ b/libports/count-bucket.c +@@ -25,10 +25,10 @@ ports_count_bucket (struct port_bucket *bucket) + { + int ret; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + ret = bucket->count; + bucket->flags |= PORT_BUCKET_NO_ALLOC; +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + + return ret; + } +diff --git a/libports/count-class.c b/libports/count-class.c +index 0c48b46..5f5dc73 100644 +--- a/libports/count-class.c ++++ b/libports/count-class.c +@@ -25,9 +25,9 @@ ports_count_class (struct port_class *class) + { + int ret; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + ret = class->count; + class->flags |= PORT_CLASS_NO_ALLOC; +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + return ret; + } +diff --git a/libports/create-bucket.c b/libports/create-bucket.c +index 52d50c3..f8a0996 100644 +--- a/libports/create-bucket.c ++++ b/libports/create-bucket.c +@@ -46,13 +46,14 @@ ports_create_bucket () + return NULL; + } + ++ pthread_mutex_init (&ret->lock, NULL); + hurd_ihash_init (&ret->htable, offsetof (struct port_info, hentry)); + ret->rpcs = ret->flags = ret->count = 0; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + ret->next = _ports_all_buckets; + _ports_all_buckets = ret; +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + + return ret; + } +diff --git a/libports/create-internal.c b/libports/create-internal.c +index d56637c..33ee1e1 100644 +--- a/libports/create-internal.c ++++ b/libports/create-internal.c +@@ -62,25 +62,27 @@ _ports_create_port_internal (struct port_class *class, + pi->current_rpcs = 0; + pi->bucket = bucket; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + + loop: + if (class->flags & PORT_CLASS_NO_ALLOC) + { + class->flags |= PORT_CLASS_ALLOC_WAIT; +- if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_lock)) ++ if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_global_lock)) + goto cancelled; + goto loop; + } + if (bucket->flags & PORT_BUCKET_NO_ALLOC) + { + bucket->flags |= PORT_BUCKET_ALLOC_WAIT; +- if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_lock)) ++ if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_global_lock)) + goto cancelled; + goto loop; + } + ++ pthread_mutex_lock (&bucket->lock); + err = hurd_ihash_add (&bucket->htable, port, pi); ++ pthread_mutex_unlock (&bucket->lock); + if (err) + goto lose; + +@@ -91,7 +93,7 @@ _ports_create_port_internal (struct port_class *class, + class->ports = pi; + bucket->count++; + class->count++; +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + + if (install) + { +@@ -107,7 +109,7 @@ _ports_create_port_internal (struct port_class *class, + cancelled: + err = EINTR; + lose: +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + lose_unlocked:; + error_t e; + e = mach_port_mod_refs (mach_task_self (), port, +diff --git a/libports/destroy-right.c b/libports/destroy-right.c +index 65e19c7..b12dec9 100644 +--- a/libports/destroy-right.c ++++ b/libports/destroy-right.c +@@ -30,12 +30,12 @@ ports_destroy_right (void *portstruct) + + if (pi->port_right != MACH_PORT_NULL) + { +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&pi->bucket->lock); + hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry); + err = mach_port_mod_refs (mach_task_self (), pi->port_right, + MACH_PORT_RIGHT_RECEIVE, -1); + assert_perror (err); +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&pi->bucket->lock); + + pi->port_right = MACH_PORT_NULL; + +diff --git a/libports/enable-bucket.c b/libports/enable-bucket.c +index f9c7b85..bf33cf8 100644 +--- a/libports/enable-bucket.c ++++ b/libports/enable-bucket.c +@@ -23,12 +23,12 @@ + void + ports_enable_bucket (struct port_bucket *bucket) + { +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + bucket->flags &= ~PORT_BUCKET_NO_ALLOC; + if (bucket->flags & PORT_BUCKET_ALLOC_WAIT) + { + bucket->flags &= ~PORT_BUCKET_ALLOC_WAIT; + pthread_cond_broadcast (&_ports_block); + } +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + } +diff --git a/libports/enable-class.c b/libports/enable-class.c +index b3894eb..cbddc1a 100644 +--- a/libports/enable-class.c ++++ b/libports/enable-class.c +@@ -23,12 +23,12 @@ + void + ports_enable_class (struct port_class *class) + { +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + class->flags &= ~PORT_CLASS_NO_ALLOC; + if (class->flags & PORT_CLASS_ALLOC_WAIT) + { + class->flags &= ~PORT_CLASS_ALLOC_WAIT; + pthread_cond_broadcast (&_ports_block); + } +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + } +diff --git a/libports/end-rpc.c b/libports/end-rpc.c +index b5dcb3a..9134822 100644 +--- a/libports/end-rpc.c ++++ b/libports/end-rpc.c +@@ -25,7 +25,7 @@ ports_end_rpc (void *port, struct rpc_info *info) + { + struct port_info *pi = port; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + + if (info->notifies) + _ports_remove_notified_rpc (info); +@@ -51,5 +51,5 @@ ports_end_rpc (void *port, struct rpc_info *info) + RPC is now finished anwhow. */ + hurd_check_cancel (); + +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + } +diff --git a/libports/get-right.c b/libports/get-right.c +index 42bfa2b..e0c7853 100644 +--- a/libports/get-right.c ++++ b/libports/get-right.c +@@ -29,11 +29,11 @@ ports_get_right (void *port) + mach_port_t foo; + error_t err; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&pi->bucket->lock); + + if (pi->port_right == MACH_PORT_NULL) + { +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&pi->bucket->lock); + return MACH_PORT_NULL; + } + +@@ -53,6 +53,6 @@ ports_get_right (void *port) + if (foo != MACH_PORT_NULL) + mach_port_deallocate (mach_task_self (), foo); + } +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&pi->bucket->lock); + return pi->port_right; + } +diff --git a/libports/import-port.c b/libports/import-port.c +index 5c66685..1aa422a 100644 +--- a/libports/import-port.c ++++ b/libports/import-port.c +@@ -56,25 +56,27 @@ ports_import_port (struct port_class *class, struct port_bucket *bucket, + pi->current_rpcs = 0; + pi->bucket = bucket; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + + loop: + if (class->flags & PORT_CLASS_NO_ALLOC) + { + class->flags |= PORT_CLASS_ALLOC_WAIT; +- if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_lock)) ++ if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_global_lock)) + goto cancelled; + goto loop; + } + if (bucket->flags & PORT_BUCKET_NO_ALLOC) + { + bucket->flags |= PORT_BUCKET_ALLOC_WAIT; +- if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_lock)) ++ if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_global_lock)) + goto cancelled; + goto loop; + } + ++ pthread_mutex_lock (&bucket->lock); + err = hurd_ihash_add (&bucket->htable, port, pi); ++ pthread_mutex_unlock (&bucket->lock); + if (err) + goto lose; + +@@ -85,7 +87,7 @@ ports_import_port (struct port_class *class, struct port_bucket *bucket, + class->ports = pi; + bucket->count++; + class->count++; +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + + mach_port_move_member (mach_task_self (), port, bucket->portset); + +@@ -107,7 +109,7 @@ ports_import_port (struct port_class *class, struct port_bucket *bucket, + cancelled: + err = EINTR; + lose: +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + free (pi); + + return err; +diff --git a/libports/inhibit-all-rpcs.c b/libports/inhibit-all-rpcs.c +index d4a54ba..337d068 100644 +--- a/libports/inhibit-all-rpcs.c ++++ b/libports/inhibit-all-rpcs.c +@@ -27,7 +27,7 @@ ports_inhibit_all_rpcs () + { + error_t err = 0; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + + if (_ports_flags & (_PORTS_INHIBITED | _PORTS_INHIBIT_WAIT)) + err = EBUSY; +@@ -38,6 +38,7 @@ ports_inhibit_all_rpcs () + + for (bucket = _ports_all_buckets; bucket; bucket = bucket->next) + { ++ pthread_mutex_lock (&bucket->lock); + HURD_IHASH_ITERATE (&bucket->htable, portstruct) + { + struct rpc_info *rpc; +@@ -53,12 +54,13 @@ ports_inhibit_all_rpcs () + hurd_thread_cancel (rpc->thread); + } + } ++ pthread_mutex_unlock (&bucket->lock); + } + + while (_ports_total_rpcs > this_one) + { + _ports_flags |= _PORTS_INHIBIT_WAIT; +- if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_lock)) ++ if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_global_lock)) + /* We got cancelled. */ + { + err = EINTR; +@@ -71,7 +73,7 @@ ports_inhibit_all_rpcs () + _ports_flags |= _PORTS_INHIBITED; + } + +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + + return err; + } +diff --git a/libports/inhibit-bucket-rpcs.c b/libports/inhibit-bucket-rpcs.c +index 965aa03..d55798e 100644 +--- a/libports/inhibit-bucket-rpcs.c ++++ b/libports/inhibit-bucket-rpcs.c +@@ -27,7 +27,7 @@ ports_inhibit_bucket_rpcs (struct port_bucket *bucket) + { + error_t err = 0; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + + if (bucket->flags & (PORT_BUCKET_INHIBITED | PORT_BUCKET_INHIBIT_WAIT)) + err = EBUSY; +@@ -35,6 +35,7 @@ ports_inhibit_bucket_rpcs (struct port_bucket *bucket) + { + int this_one = 0; + ++ pthread_mutex_lock (&bucket->lock); + HURD_IHASH_ITERATE (&bucket->htable, portstruct) + { + struct rpc_info *rpc; +@@ -49,12 +50,12 @@ ports_inhibit_bucket_rpcs (struct port_bucket *bucket) + hurd_thread_cancel (rpc->thread); + } + } +- ++ pthread_mutex_unlock (&bucket->lock); + + while (bucket->rpcs > this_one) + { + bucket->flags |= PORT_BUCKET_INHIBIT_WAIT; +- if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_lock)) ++ if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_global_lock)) + /* We got cancelled. */ + { + err = EINTR; +@@ -67,7 +68,7 @@ ports_inhibit_bucket_rpcs (struct port_bucket *bucket) + bucket->flags |= PORT_BUCKET_INHIBITED; + } + +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + + return err; + } +diff --git a/libports/inhibit-class-rpcs.c b/libports/inhibit-class-rpcs.c +index 7ee8653..fe26f27 100644 +--- a/libports/inhibit-class-rpcs.c ++++ b/libports/inhibit-class-rpcs.c +@@ -26,7 +26,7 @@ ports_inhibit_class_rpcs (struct port_class *class) + { + error_t err = 0; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + + if (class->flags & (PORT_CLASS_INHIBITED | PORT_CLASS_INHIBIT_WAIT)) + err = EBUSY; +@@ -49,7 +49,7 @@ ports_inhibit_class_rpcs (struct port_class *class) + while (class->rpcs > this_one) + { + class->flags |= PORT_CLASS_INHIBIT_WAIT; +- if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_lock)) ++ if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_global_lock)) + /* We got cancelled. */ + { + err = EINTR; +@@ -62,7 +62,7 @@ ports_inhibit_class_rpcs (struct port_class *class) + class->flags |= PORT_CLASS_INHIBITED; + } + +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + + return err; + } +diff --git a/libports/inhibit-port-rpcs.c b/libports/inhibit-port-rpcs.c +index b741eeb..f712ca9 100644 +--- a/libports/inhibit-port-rpcs.c ++++ b/libports/inhibit-port-rpcs.c +@@ -27,7 +27,7 @@ ports_inhibit_port_rpcs (void *portstruct) + error_t err = 0; + struct port_info *pi = portstruct; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + + if (pi->flags & (PORT_INHIBITED | PORT_INHIBIT_WAIT)) + err = EBUSY; +@@ -50,7 +50,7 @@ ports_inhibit_port_rpcs (void *portstruct) + && !(pi->current_rpcs == this_rpc && ! this_rpc->next)) + { + pi->flags |= PORT_INHIBIT_WAIT; +- if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_lock)) ++ if (pthread_hurd_cond_wait_np (&_ports_block, &_ports_global_lock)) + /* We got cancelled. */ + { + err = EINTR; +@@ -63,7 +63,7 @@ ports_inhibit_port_rpcs (void *portstruct) + pi->flags |= PORT_INHIBITED; + } + +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + + return err; + } +diff --git a/libports/init.c b/libports/init.c +index 3ef5388..36e42a0 100644 +--- a/libports/init.c ++++ b/libports/init.c +@@ -20,7 +20,7 @@ + + #include "ports.h" + +-pthread_mutex_t _ports_lock = PTHREAD_MUTEX_INITIALIZER; ++pthread_mutex_t _ports_global_lock = PTHREAD_MUTEX_INITIALIZER; + pthread_cond_t _ports_block = PTHREAD_COND_INITIALIZER; + struct port_bucket *_ports_all_buckets; + int _ports_total_rpcs; +diff --git a/libports/interrupt-notified-rpcs.c b/libports/interrupt-notified-rpcs.c +index 49a15d0..06f1c1f 100644 +--- a/libports/interrupt-notified-rpcs.c ++++ b/libports/interrupt-notified-rpcs.c +@@ -36,7 +36,7 @@ ports_interrupt_notified_rpcs (void *object, + { + struct ports_notify *np; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + for (np = _ports_notifications; np; np = np->next) + if (np->port == port && np->what == what) + { +@@ -49,7 +49,7 @@ ports_interrupt_notified_rpcs (void *object, + } + break; + } +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + } + } + +diff --git a/libports/interrupt-on-notify.c b/libports/interrupt-on-notify.c +index b358e84..7b93429 100644 +--- a/libports/interrupt-on-notify.c ++++ b/libports/interrupt-on-notify.c +@@ -34,13 +34,13 @@ ports_interrupt_rpc_on_notification (void *object, + struct rpc_notify *new_req, *req; + struct port_info *pi = object; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + + if (! MACH_PORT_VALID (port)) + /* PORT is already dead or bogus, so interrupt the rpc immediately. */ + { + hurd_thread_cancel (rpc->thread); +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + return 0; + } + +@@ -53,11 +53,11 @@ ports_interrupt_rpc_on_notification (void *object, + time we'll add a new structure, so we malloc while we don't have the + lock, and free it if we're wrong. */ + { +- pthread_mutex_unlock (&_ports_lock); /* Don't hold the lock during malloc. */ ++ pthread_mutex_unlock (&_ports_global_lock); /* Don't hold the lock during malloc. */ + new_req = malloc (sizeof (struct rpc_notify)); + if (! new_req) + return ENOMEM; +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + } + + /* Find any existing entry for PORT/WHAT. */ +@@ -80,7 +80,7 @@ ports_interrupt_rpc_on_notification (void *object, + { + new_req->next = _ports_free_rpc_notifies; + _ports_free_rpc_notifies = new_req; +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + return ENOMEM; + } + } +@@ -138,7 +138,7 @@ ports_interrupt_rpc_on_notification (void *object, + if (req_notify) + pthread_mutex_lock (&pn->lock); + +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + + if (req_notify) + { +@@ -170,11 +170,11 @@ ports_interrupt_self_on_notification (void *object, + struct port_info *pi = object; + thread_t thread = hurd_thread_self (); + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) + if (rpc->thread == thread) + break; +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + + assert (rpc); + +diff --git a/libports/interrupt-operation.c b/libports/interrupt-operation.c +index 943bd4f..940ae27 100644 +--- a/libports/interrupt-operation.c ++++ b/libports/interrupt-operation.c +@@ -29,10 +29,10 @@ ports_S_interrupt_operation (struct port_info *pi, + { + if (!pi) + return EOPNOTSUPP; +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + if (pi->cancel_threshold < seqno) + pi->cancel_threshold = seqno; +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + ports_interrupt_rpcs (pi); + return 0; + } +diff --git a/libports/interrupt-rpcs.c b/libports/interrupt-rpcs.c +index 42f51a5..3dc3777 100644 +--- a/libports/interrupt-rpcs.c ++++ b/libports/interrupt-rpcs.c +@@ -27,7 +27,7 @@ ports_interrupt_rpcs (void *portstruct) + struct port_info *pi = portstruct; + struct rpc_info *rpc; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + + for (rpc = pi->current_rpcs; rpc; rpc = rpc->next) + { +@@ -35,5 +35,5 @@ ports_interrupt_rpcs (void *portstruct) + _ports_record_interruption (rpc); + } + +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + } +diff --git a/libports/lookup-port.c b/libports/lookup-port.c +index 289369f..c919266 100644 +--- a/libports/lookup-port.c ++++ b/libports/lookup-port.c +@@ -27,26 +27,32 @@ ports_lookup_port (struct port_bucket *bucket, + struct port_class *class) + { + struct port_info *pi = 0; +- +- pthread_mutex_lock (&_ports_lock); + + if (bucket) +- pi = hurd_ihash_find (&bucket->htable, port); ++ { ++ pthread_mutex_lock (&bucket->lock); ++ pi = hurd_ihash_find (&bucket->htable, port); ++ pthread_mutex_unlock (&bucket->lock); ++ } + else +- for (bucket = _ports_all_buckets; bucket; bucket = bucket->next) +- { +- pi = hurd_ihash_find (&bucket->htable, port); +- if (pi) +- break; +- } +- ++ { ++ pthread_mutex_lock (&_ports_global_lock); ++ for (bucket = _ports_all_buckets; bucket; bucket = bucket->next) ++ { ++ pthread_mutex_lock (&bucket->lock); ++ pi = hurd_ihash_find (&bucket->htable, port); ++ pthread_mutex_unlock (&bucket->lock); ++ if (pi) ++ break; ++ } ++ pthread_mutex_unlock (&_ports_global_lock); ++ } ++ + if (pi && class && pi->class != class) + pi = 0; + + if (pi) + ports_port_ref (pi); + +- pthread_mutex_unlock (&_ports_lock); +- + return pi; + } +diff --git a/libports/manage-multithread.c b/libports/manage-multithread.c +index 2067cba..3ef4f4e 100644 +--- a/libports/manage-multithread.c ++++ b/libports/manage-multithread.c +@@ -173,10 +173,10 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, + } + else + { +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + if (inp->msgh_seqno < pi->cancel_threshold) + hurd_thread_cancel (link.thread); +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + status = demuxer (inp, outheadp); + ports_end_rpc (pi, &link); + } +diff --git a/libports/no-senders.c b/libports/no-senders.c +index 1a6084b..77d033f 100644 +--- a/libports/no-senders.c ++++ b/libports/no-senders.c +@@ -29,10 +29,10 @@ ports_no_senders (void *portstruct, + int dealloc; + mach_port_t old; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + if ((pi->flags & PORT_HAS_SENDRIGHTS) == 0) + { +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + return; + } + if (mscount >= pi->mscount) +@@ -53,8 +53,8 @@ ports_no_senders (void *portstruct, + mach_port_deallocate (mach_task_self (), old); + dealloc = 0; + } +- pthread_mutex_unlock (&_ports_lock); +- ++ pthread_mutex_unlock (&_ports_global_lock); ++ + if (dealloc) + { + ports_interrupt_notified_rpcs (portstruct, pi->port_right, +diff --git a/libports/ports.h b/libports/ports.h +index 7088b2d..c5bf8eb 100644 +--- a/libports/ports.h ++++ b/libports/ports.h +@@ -67,6 +67,8 @@ struct port_bucket + int rpcs; + int flags; + int count; ++ pthread_mutex_t lock; ++ + struct port_bucket *next; + }; + /* FLAGS above are the following: */ +@@ -402,7 +404,7 @@ extern kern_return_t + ports_do_mach_notify_send_once (struct port_info *pi); + + /* Private data */ +-extern pthread_mutex_t _ports_lock; ++extern pthread_mutex_t _ports_global_lock; + extern pthread_cond_t _ports_block; + extern struct port_bucket *_ports_all_buckets; + extern int _ports_total_rpcs; +diff --git a/libports/reallocate-from-external.c b/libports/reallocate-from-external.c +index 4dfc59c..84fecc9 100644 +--- a/libports/reallocate-from-external.c ++++ b/libports/reallocate-from-external.c +@@ -34,17 +34,19 @@ ports_reallocate_from_external (void *portstruct, mach_port_t receive) + + err = mach_port_get_receive_status (mach_task_self (), receive, &stat); + assert_perror (err); +- +- pthread_mutex_lock (&_ports_lock); +- ++ ++ pthread_mutex_lock (&_ports_global_lock); ++ + assert (pi->port_right); + + err = mach_port_mod_refs (mach_task_self (), pi->port_right, + MACH_PORT_RIGHT_RECEIVE, -1); + assert_perror (err); + ++ pthread_mutex_lock (&pi->bucket->lock); + hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry); +- ++ pthread_mutex_unlock (&pi->bucket->lock); ++ + if ((pi->flags & PORT_HAS_SENDRIGHTS) && !stat.mps_srights) + { + dropref = 1; +@@ -55,15 +57,17 @@ ports_reallocate_from_external (void *portstruct, mach_port_t receive) + pi->flags |= PORT_HAS_SENDRIGHTS; + ports_port_ref (pi); + } +- ++ pthread_mutex_unlock (&_ports_global_lock); ++ + pi->port_right = receive; + pi->cancel_threshold = 0; + pi->mscount = stat.mps_mscount; +- ++ ++ pthread_mutex_lock (&pi->bucket->lock); + err = hurd_ihash_add (&pi->bucket->htable, receive, pi); ++ pthread_mutex_unlock (&pi->bucket->lock); + assert_perror (err); +- pthread_mutex_unlock (&_ports_lock); +- ++ + 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..f68865e 100644 +--- a/libports/reallocate-port.c ++++ b/libports/reallocate-port.c +@@ -29,14 +29,16 @@ ports_reallocate_port (void *portstruct) + error_t err; + int dropref = 0; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + assert (pi->port_right); + + err = mach_port_mod_refs (mach_task_self (), pi->port_right, + MACH_PORT_RIGHT_RECEIVE, -1); + assert_perror (err); + ++ pthread_mutex_lock (&pi->bucket->lock); + hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry); ++ pthread_mutex_unlock (&pi->bucket->lock); + + err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, + &pi->port_right); +@@ -46,11 +48,14 @@ ports_reallocate_port (void *portstruct) + pi->flags &= ~PORT_HAS_SENDRIGHTS; + dropref = 1; + } ++ pthread_mutex_unlock (&_ports_global_lock); ++ + pi->cancel_threshold = 0; + pi->mscount = 0; ++ pthread_mutex_lock (&pi->bucket->lock); + err = hurd_ihash_add (&pi->bucket->htable, pi->port_right, pi); ++ pthread_mutex_unlock (&pi->bucket->lock); + assert_perror (err); +- pthread_mutex_unlock (&_ports_lock); + + err = mach_port_move_member (mach_task_self (), pi->port_right, + pi->bucket->portset); +diff --git a/libports/resume-all-rpcs.c b/libports/resume-all-rpcs.c +index e4befff..e7766a1 100644 +--- a/libports/resume-all-rpcs.c ++++ b/libports/resume-all-rpcs.c +@@ -24,7 +24,7 @@ + void + ports_resume_all_rpcs () + { +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + assert (_ports_flags & _PORTS_INHIBITED); + _ports_flags &= ~_PORTS_INHIBITED; + if (_ports_flags & _PORTS_BLOCKED) +@@ -32,5 +32,5 @@ ports_resume_all_rpcs () + _ports_flags &= ~_PORTS_BLOCKED; + pthread_cond_broadcast (&_ports_block); + } +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + } +diff --git a/libports/resume-bucket-rpcs.c b/libports/resume-bucket-rpcs.c +index cf4db91..1078dac 100644 +--- a/libports/resume-bucket-rpcs.c ++++ b/libports/resume-bucket-rpcs.c +@@ -24,7 +24,7 @@ + void + ports_resume_bucket_rpcs (struct port_bucket *bucket) + { +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + assert (bucket->flags & PORT_BUCKET_INHIBITED); + bucket->flags &= ~PORT_BUCKET_INHIBITED; + if (bucket->flags & PORT_BUCKET_BLOCKED) +@@ -32,5 +32,5 @@ ports_resume_bucket_rpcs (struct port_bucket *bucket) + bucket->flags &= ~PORT_BUCKET_BLOCKED; + pthread_cond_broadcast (&_ports_block); + } +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + } +diff --git a/libports/resume-class-rpcs.c b/libports/resume-class-rpcs.c +index 60a2b12..00ec7de 100644 +--- a/libports/resume-class-rpcs.c ++++ b/libports/resume-class-rpcs.c +@@ -24,7 +24,7 @@ + void + ports_resume_class_rpcs (struct port_class *class) + { +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + assert (class->flags & PORT_CLASS_INHIBITED); + class->flags &= ~PORT_CLASS_INHIBITED; + if (class->flags & PORT_CLASS_BLOCKED) +@@ -32,5 +32,5 @@ ports_resume_class_rpcs (struct port_class *class) + class->flags &= ~PORT_CLASS_BLOCKED; + pthread_cond_broadcast (&_ports_block); + } +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + } +diff --git a/libports/resume-port-rpcs.c b/libports/resume-port-rpcs.c +index 6d71ab5..845c6f1 100644 +--- a/libports/resume-port-rpcs.c ++++ b/libports/resume-port-rpcs.c +@@ -25,9 +25,9 @@ void + ports_resume_port_rpcs (void *portstruct) + { + struct port_info *pi = portstruct; +- +- pthread_mutex_lock (&_ports_lock); +- ++ ++ pthread_mutex_lock (&_ports_global_lock); ++ + assert (pi->flags & PORT_INHIBITED); + pi->flags &= ~PORT_INHIBITED; + if (pi->flags & PORT_BLOCKED) +@@ -35,5 +35,5 @@ ports_resume_port_rpcs (void *portstruct) + pi->flags &= ~PORT_BLOCKED; + pthread_cond_broadcast (&_ports_block); + } +- pthread_mutex_unlock (&_ports_lock); ++ pthread_mutex_unlock (&_ports_global_lock); + } +diff --git a/libports/transfer-right.c b/libports/transfer-right.c +index f4e0c86..01c08e9 100644 +--- a/libports/transfer-right.c ++++ b/libports/transfer-right.c +@@ -35,13 +35,15 @@ ports_transfer_right (void *tostruct, + int hassendrights = 0; + error_t err; + +- pthread_mutex_lock (&_ports_lock); ++ pthread_mutex_lock (&_ports_global_lock); + + /* Fetch the port in FROMPI and clear its use */ + port = frompi->port_right; + if (port != MACH_PORT_NULL) + { ++ pthread_mutex_lock (&frompi->bucket->lock); + hurd_ihash_locp_remove (&frompi->bucket->htable, frompi->hentry); ++ pthread_mutex_unlock (&frompi->bucket->lock); + frompi->port_right = MACH_PORT_NULL; + if (frompi->flags & PORT_HAS_SENDRIGHTS) + { +@@ -54,7 +56,9 @@ ports_transfer_right (void *tostruct, + /* Destroy the existing right in TOPI. */ + if (topi->port_right != MACH_PORT_NULL) + { ++ pthread_mutex_lock (&topi->bucket->lock); + hurd_ihash_locp_remove (&topi->bucket->htable, topi->hentry); ++ pthread_mutex_unlock (&topi->bucket->lock); + err = mach_port_mod_refs (mach_task_self (), topi->port_right, + MACH_PORT_RIGHT_RECEIVE, -1); + assert_perror (err); +@@ -74,10 +78,14 @@ ports_transfer_right (void *tostruct, + topi->port_right = port; + topi->cancel_threshold = frompi->cancel_threshold; + topi->mscount = frompi->mscount; +- ++ ++ pthread_mutex_unlock (&_ports_global_lock); ++ + if (port) + { ++ pthread_mutex_lock (&topi->bucket->lock); + err = hurd_ihash_add (&topi->bucket->htable, port, topi); ++ pthread_mutex_unlock (&topi->bucket->lock); + assert_perror (err); + if (topi->bucket != frompi->bucket) + { +@@ -86,9 +94,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); diff --git a/debian/patches/series b/debian/patches/series index bc5c48b1..14ca54d7 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -47,3 +47,4 @@ fatfs-two-pagers.patch libpager-singlethreaded.patch libpager-drop-seqnos.patch libports-lockless-refcounting.patch +libports-per-bucket-hashtable.patch -- cgit v1.2.3