Thanks for checking! In that case, the retry loop is indeed the only reasonable solution I can think of.

On a MIPS4 CPU (R8k and newer) the load-linked/store-conditional (LL/SC) is not 
infallible (like the modern CAS implementation).
That's interesting! This means that a reader-writer-spinlock (instead of a reader-writer-mutex) wouldn't help either because it would still require reliable CAS operations.

I think the retry-loop would be a good idea anyway.

To avoid bombarding the OS/CPU with too many trylocks when the optimizer does 
for-loop-unrolling
I don't think that the compiler is allowed to unroll the spin loop. After all, the try-lock issues at least a compiler barrier, if not a memory barrier. Have you checked the assembly? I would have assumed that a plain (bounded) spin loop with pause instructions would be sufficient. Since the failures are spurious (i.e. the lock is not really contended), the retry-loop should only take a few iterations at most.

Christof

On 8/9/2026 12:17 AM, Wolfgang Gaggl via Pd-list wrote:
I confirmed it is the Irix pthread implementation.
A trylock is not guaranteed to succeed immediately even if it is uncontested.
This is not a bug of the newer gcc implementation as I suspected earlier, but 
also true for the native MipsPro compiler as well.
On a MIPS4 CPU (R8k and newer) the load-linked/store-conditional (LL/SC) is not infallible (like the modern CAS implementation). Also context switches, hardware interrupts, and other stuff can cause spurious failures of trylock. I also found some suggestions that the M:N Hybrid user:kernel space threading for Posix threads on Irix increases the chance of trylock failure.

The solution is exactly that, to try a few times (most times it works at the 
first attempt anyway).

To avoid bombarding the OS/CPU with too many trylocks when the optimizer does 
for-loop-unrolling and the CPU applies things like speculative execution and 
runtime optimization I added a yield() once in a while, which turned out to be 
a not-so-good idea. If the thread priority is normal, overtime it might be 
deprioritized in Irix and yields can add unpredictable amounts of time. On the 
other hand increasing the priority for the AOO process made the yield mostly 
useless since it would not yield most of the time. So I replaced it by a timer 
loop instead now (code sniplet below).

This works well, I have not had any problems since (no clicks or pops with low 
CPU usage), have PD with AOO running on an SGI Octane2 Dual-CPU as frontend, 
and an SGI Origin2200 deskside server with 8 CPUS as compute engine connected 
by dedicated GBit ethernet.

shared_lock lock(update_mutex_, sync::try_to_lock); // reader lock!
#if defined(__sgi) && defined(__mips__)
     for (int i = 0; !lock.owns_lock() && i < kIrixReadTryLockRetries; ++i) {
         sync::pause_cpu();
         if ((i & 7) == 7) {
            struct timespec start, current;
            clock_gettime(CLOCK_SGI_CYCLE, &start);
            long elapsed = 0;
            while (elapsed < RWLOCK_WAIT_TIME) {
                 sync::pause_cpu();
                clock_gettime(CLOCK_SGI_CYCLE, &current);
                elapsed = (current.tv_sec - start.tv_sec) * 1000000000L +
                          (current.tv_nsec - start.tv_nsec);
            }
         }
         lock = shared_lock(update_mutex_, sync::try_to_lock);
     }
#endif
---
[email protected] - the Pure Data mailinglist
https://lists.iem.at/hyperkitty/list/[email protected]/message/Y65QNUEXRONWASJTCUYAM3OP3ZCEJXM3/

To unsubscribe send an email to [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/ZHUF34C7PUYWWC55VY2JOP5RHUVL66KF/

To unsubscribe send an email to [email protected] mailing list
UNSUBSCRIBE and account-management -> https://lists.iem.at/

Reply via email to