* 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