bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[committed hurd] libports: avoid acquiring global lock in message dispat


From: Justus Winter
Subject: [committed hurd] libports: avoid acquiring global lock in message dispatch
Date: Tue, 17 Feb 2015 20:37:58 +0100

* libports/interrupt-operation.c (ports_S_interrupt_operation): Update
`cancel_threshold' using atomic operations.
* libports/manage-multithread.c (internal_demuxer): Avoid taking the lock.
* libports/ports.h (struct port_info): Mention that one needs atomic
operations to access `cancel_threshold'.
---
 libports/interrupt-operation.c | 14 ++++++++++----
 libports/manage-multithread.c  |  8 +++++---
 libports/ports.h               |  2 +-
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/libports/interrupt-operation.c b/libports/interrupt-operation.c
index 943bd4f..5d4b0b7 100644
--- a/libports/interrupt-operation.c
+++ b/libports/interrupt-operation.c
@@ -27,12 +27,18 @@ kern_return_t
 ports_S_interrupt_operation (struct port_info *pi,
                             mach_port_seqno_t seqno)
 {
+  mach_port_seqno_t old;
+
   if (!pi)
     return EOPNOTSUPP;
-  pthread_mutex_lock (&_ports_lock);
-  if (pi->cancel_threshold < seqno)
-    pi->cancel_threshold = seqno;
-  pthread_mutex_unlock (&_ports_lock);
+
+ retry:
+  old = __atomic_load_n (&pi->cancel_threshold, __ATOMIC_SEQ_CST);
+  if (old < seqno
+      && ! __atomic_compare_exchange_n (&pi->cancel_threshold, &old, seqno,
+                                       0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
+       goto retry;
+
   ports_interrupt_rpcs (pi);
   return 0;
 }
diff --git a/libports/manage-multithread.c b/libports/manage-multithread.c
index ad22991..58814d2 100644
--- a/libports/manage-multithread.c
+++ b/libports/manage-multithread.c
@@ -178,10 +178,12 @@ ports_manage_port_operations_multithread (struct 
port_bucket *bucket,
            }
          else
            {
-             pthread_mutex_lock (&_ports_lock);
-             if (inp->msgh_seqno < pi->cancel_threshold)
+             mach_port_seqno_t cancel_threshold =
+               __atomic_load_n (&pi->cancel_threshold, __ATOMIC_SEQ_CST);
+
+             if (inp->msgh_seqno < cancel_threshold)
                hurd_thread_cancel (link.thread);
-             pthread_mutex_unlock (&_ports_lock);
+
              status = demuxer (inp, outheadp);
              ports_end_rpc (pi, &link);
            }
diff --git a/libports/ports.h b/libports/ports.h
index a625b47..f02edb4 100644
--- a/libports/ports.h
+++ b/libports/ports.h
@@ -48,7 +48,7 @@ struct port_info
   struct port_class *class;
   refcounts_t refcounts;
   mach_port_mscount_t mscount;
-  mach_msg_seqno_t cancel_threshold;
+  mach_msg_seqno_t cancel_threshold;   /* needs atomic operations */
   int flags;
   mach_port_t port_right;
   struct rpc_info *current_rpcs;
-- 
2.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]