Re: AOO plugin for PD on SGI Irix
Christof Ressi via Pd-list <[email protected]>
| Newsgroups | gmane.comp.multimedia.puredata.general |
|---|---|
| Message-ID | <[email protected]> |
On 8/13/2026 12:04 AM, Wolfgang Gaggl via Pd-list wrote:
>>> I have been thinking: how could anyone implement synchronization
> primitives without reliable atomic operations? To me, a bug in the
> pthread_rwlock implementation seems more likely.
>
> Generally, it all seems to work, including atomics.
> I believe there's an issue with the GCC implementation for pthread_rwlock on this platform; as far I can observe only with the try_to_lock shared_lock. There are some mentioned differences (occasionally having to try_to_lock multiple times to get a lock on an uncontested lock) that I can also see on the native MIPSPro compiler.
> But at times it fails to get a reader lock with try_to_lock when another scoped_shared_lock is active which looks like a bug.
> I observed this only in GCC. Since the native MIPSPro compiler supports only C++98 I didn't fully test the exact scenario with the specific timing there.
>
> Since you pointed out that sink.cpp may have concurrent writers active during the stream I chose another way to do this.
>
> std::atomic<uint32_t> process_active_{0};
> std::atomic<uint32_t> writer_gate_{0};
>
> In source_desc::process():
>
> // Writers set writer_gate_ and wait for process_active_ == 0 before mutating
> // This prevents writer/process overlap without using rwlock try_lock in audio path.
> if (writer_gate_.load(std::memory_order_acquire) != 0) {
> if (stream_state_ != stream_state::inactive) {
> LOG_DEBUG("AooSink: process blocked by writer gate");
> add_xrun(1);
> }
> }
>
> // process() sets process_active_ to to set writer block
> sink_process_activity_guard process_guard(process_active_);
>
> // For the extra-cautious, recheck after announcing active status to avoid race condition.
> if (writer_gate_.load(std::memory_order_acquire) != 0) {
> if (stream_state_ != stream_state::inactive) {
> LOG_DEBUG("AooSink: process blocked by writer gate");
> add_xrun(1);
> }
> }
>
> // now do the processing stuff...
> }
>
> For all writer calls:
> // Writer gate guard: blocks new process() entries while a writer is pending.
> sink_writer_gate_guard _writer_gate(writer_gate_);
> // This function loops pause_cpu() while process() is active
> wait_for_sink_process_idle(process_active_);
> // do write stuff...
This looks overly complicated to me. I can't even tell if it's correct
without looking at the implementation of sink_process_activity_guard,
sink_writer_gate_guard and wait_for_sink_process_idle. In general, I
would advice against ad-hoc solutions with atomics. If possible, stick
to standard synchronization patterns.
(BTW, that additional writer_gate_.load(std::memory_order_acquire) is
essential because otherwise you run into the ABA problem.)
As I said, you just need to replace the shared_mutex with a
shared_spinlock. Apart from that you can revert back to the original
code. (The process() method does a try-lock, but because it's now a
simple CAS operation there is no need for a retry-loop. By default, the
readers and writers would do full spinlocks, but you can replace them
with try-lock loops that occasionally sleep for a short time to fight
priority inversion.)
Christof
>
> This method does not block in the process() thread and avoids using the problematic try_to_lock.
> It also uses fewer CPU cycles than looping try_to_lock in process().
>
> As you suggested, I tested it by changing format parameters during the running stream in quick succession to see if I can break it, but it all works without issues.
> ---
> [email protected] - the Pure Data mailinglist
> https://lists.iem.at/hyperkitty/list/[email protected]/message/6323HU2BWSBL2R4RPCZBSRS3XBLWW3P5/
>
> To unsubscribe send an email [email protected] mailing list
> UNSUBSCRIBE and account-management ->https://lists.iem.at/
>
---
[email protected] - the Pure Data mailinglist
https://lists.iem.at/hyperkitty/list/[email protected]/message/T6TL6VSZEPVPZF55H36XAVWY4FJ22RF3/
To unsubscribe send an email to [email protected] mailing list
UNSUBSCRIBE and account-management -> https://lists.iem.at/