diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-12-15 11:53:26 +0100 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-02-17 20:29:15 +0100 |
commit | fb8c531ddeef55c8581d3882bd1b1f501d980a30 (patch) | |
tree | 58ad72469c5176a1bfaad978e9d56f591e26e115 /libports/interrupt-operation.c | |
parent | eceeaeb5a2d40875fd432148b9cf26b41497811d (diff) | |
download | hurd-fb8c531ddeef55c8581d3882bd1b1f501d980a30.tar.gz hurd-fb8c531ddeef55c8581d3882bd1b1f501d980a30.tar.bz2 hurd-fb8c531ddeef55c8581d3882bd1b1f501d980a30.zip |
libports: avoid acquiring global lock in message dispatch
* 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'.
Diffstat (limited to 'libports/interrupt-operation.c')
-rw-r--r-- | libports/interrupt-operation.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/libports/interrupt-operation.c b/libports/interrupt-operation.c index 943bd4f4..5d4b0b7a 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; } |