Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run the capture thread with real-time priority #116

Merged
merged 4 commits into from
Jun 18, 2022

Conversation

atsampson
Copy link
Collaborator

This uses a couple of techniques common in Linux audio real-time programming: if possible, run the latency-sensitive capture thread with the SCHED_RR scheduling policy so it will preempt other userspace processes, and use mlock to ensure that the disk buffers stay in main memory rather than being paged out.

I tested this on my oldest USB3-capable machine (a Lenovo X220), and it significantly reduces the incidence of test-mode errors when the machine's under deliberately heavy load. On a current machine running a PREEMPT-RT kernel, I ran an 8h test-mode capture without errors while doing large compiles in the background.

This only affects the USB capture side of things - it would be worth thinking about increasing the number of disk buffers as well by default, since the current buffer is only about 3 seconds' worth of capture, and I expect most machines with USB3 can spare a couple of gigs of memory...

Previously, the variables used for synchronisation between threads
during capture were declared as volatile. While this will work on some
platforms and compilers (it's usually safe on x86), it's not strictly
correct for the C++ memory model: you need to update the variable using
an operation with a defined ordering to ensure that other changes to
memory (e.g. data in the buffer) are visible to other threads.

Use atomics instead, with the default sequential-consistency semantics,
which should do the right thing on all platforms.
This sets the scheduling class of the USB capture thread to SCHED_RR
while a capture is in progress. This should give the capture thread a
better chance of reacting quickly to transfers completing, especially if
there are other regular userspace processes competing with it.

If setting the priority fails (e.g. because the system ulimit for
real-time priority isn't high enough), it will print a warning and
continue as usual.
If mlock fails (e.g. because the corresponding ulimit is set too low),
print a warning and continue.

(Note that on some platforms, mlock requires the base address to be
page-aligned; the code doesn't currently try to achieve that because
it's not required on Linux.)
@simoninns simoninns merged commit 1e1aefd into simoninns:master Jun 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants