From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
To: linux-rt-users@vger.kernel.org
Cc: John Kacur <jkacur@redhat.com>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Subject: [PATCH 2/5] cyclictest: Acquire a lock before invoking pthread_cond_signal()
Date: Wed, 26 Aug 2026 15:21:49 +0200 [thread overview]
Message-ID: <20260826132153.2476006-3-bigeasy@linutronix.de> (raw)
In-Reply-To: <20260826132153.2476006-1-bigeasy@linutronix.de>
With the -M option the output is updated once there is a new max value.
On system with many threads (say 64) and aligned wake up (all threads
wake at the same time) it is possible that all of them have a new
maximal latency and all of them invoke pthread_cond_signal()
simultaneously. They all will block in the kernel in the futex syscall
on the same lock. And each of them will wake the printing thread one by
one. This is not *that* visible with just a few threads and a quick
CPU. But with many CPUs on a slower system this gets worse.
Acquire refresh_on_max_lock with a trylock before invoking
pthread_cond_signal(). This ensures that only one thread will send a
waking request at a time. Should the lock be contained then delay the
signalling until the next iteration.
Make refresh_on_max_lock a PI lock. This shouldn't make much of a
difference here given the try_lock usage in the RT thread but the
unconditional locking will lead to complains by the RV-monitor.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
src/cyclictest/cyclictest.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c
index 960c905606684..29ddf2d98bbe1 100644
--- a/src/cyclictest/cyclictest.c
+++ b/src/cyclictest/cyclictest.c
@@ -198,7 +198,7 @@ static int smi = 0;
#endif
static pthread_cond_t refresh_on_max_cond = PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t refresh_on_max_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t refresh_on_max_lock;
static pthread_mutex_t break_thread_id_lock = PTHREAD_MUTEX_INITIALIZER;
static pid_t break_thread_id = 0;
@@ -640,6 +640,7 @@ static void *timerthread(void *param)
struct itimerval itimer;
struct itimerspec tspec;
struct thread_stat *stat = par->stats;
+ bool need_refresh_max = false;
int stopped = 0;
cpu_set_t mask;
pthread_t thread;
@@ -834,7 +835,14 @@ static void *timerthread(void *param)
if (diff > stat->max) {
stat->max = diff;
if (refresh_on_max)
+ need_refresh_max = true;
+ }
+ if (need_refresh_max) {
+ if (!pthread_mutex_trylock(&refresh_on_max_lock)) {
pthread_cond_signal(&refresh_on_max_cond);
+ pthread_mutex_unlock(&refresh_on_max_lock);
+ need_refresh_max = false;
+ }
}
stat->avg += (double) diff;
@@ -1910,6 +1918,7 @@ static void set_main_thread_affinity(struct bitmask *cpumask)
int main(int argc, char **argv)
{
+ pthread_mutexattr_t mattr;
sigset_t sigset;
int signum = SIGALRM;
int mode;
@@ -1946,6 +1955,10 @@ int main(int argc, char **argv)
}
}
+ pthread_mutexattr_init(&mattr);
+ pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT);
+ pthread_mutex_init(&refresh_on_max_lock, &mattr);
+
/* lock all memory (prevent swapping) */
if (lockall)
if (mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
--
2.55.0
next prev parent reply other threads:[~2026-08-26 13:21 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-26 13:21 [PATCH 0/5] cyclictest: Little tweaks here and there Sebastian Andrzej Siewior
2026-08-26 13:21 ` [PATCH 1/5] rt-tests: cyclicdeadline: Remove unused `alloverflows' Sebastian Andrzej Siewior
2026-08-31 16:40 ` John Kacur
2026-08-26 13:21 ` Sebastian Andrzej Siewior [this message]
2026-08-31 16:41 ` [PATCH 2/5] cyclictest: Acquire a lock before invoking pthread_cond_signal() John Kacur
2026-09-01 8:19 ` D, Suneeth
2026-09-01 8:34 ` Tomas Glozar
2026-09-01 8:39 ` Sebastian Andrzej Siewior
2026-08-26 13:21 ` [PATCH 3/5] cyclictest: Make break_thread_id_lock a PI lock Sebastian Andrzej Siewior
2026-08-31 16:42 ` John Kacur
2026-08-26 13:21 ` [PATCH 4/5] cyclictest: Make trigger_lock " Sebastian Andrzej Siewior
2026-08-31 16:43 ` John Kacur
2026-08-26 13:21 ` [PATCH 5/5] cyclictest: Add a timestamp of the last update Sebastian Andrzej Siewior
2026-08-28 14:26 ` John Kacur
2026-08-28 16:10 ` Sebastian Andrzej Siewior
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260826132153.2476006-3-bigeasy@linutronix.de \
--to=bigeasy@linutronix.de \
--cc=jkacur@redhat.com \
--cc=linux-rt-users@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.