Re: AOO plugin for PD on SGI Irix
Wolfgang Gaggl via Pd-list <[email protected]>
| Newsgroups | gmane.comp.multimedia.puredata.general |
|---|---|
| Message-ID | <[email protected]> |
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, ¤t);
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/