Re: [PATCH] perf test: waiting.sh: Replace timestamp polling with sleep

From: Ian Rogers

Date: Tue Sep 08 2026 - 13:25:48 EST


On Tue, Sep 8, 2026 at 8:21 AM Adrian Hunter <adrian.hunter@xxxxxxxxx> wrote:
>
> The waiting helpers implement timeouts using:
>
> date +%s%1N
>
> This relies on GNU coreutils date truncating %N to the specified width,
> so %1N yields tenths of a second.
>
> Rust coreutils (uutils) interprets the width differently and does not
> truncate the nanoseconds field. Consequently "date +%1N" returns all
> nine nanosecond digits, causing the elapsed-time calculation to be done
> in nanoseconds while timeout values remain in tenths of a second.
>
> As a result, timeout comparisons succeed immediately and the waiting
> helpers time out on their first iteration. This causes
> test_intel_pt.sh to fail on systems using uutils "date".
>
> Avoid implementation-specific date formatting entirely. Instead, wait
> for 100 ms on each iteration and count the timeout down. Besides fixing
> the portability issue, this removes the busy-waiting behaviour in
> wait_for_perf_to_start(), which could otherwise consume CPU while
> waiting for perf record to start.
>
> Since the timeout is now based on repeated sleeps, it is only
> approximate. Update the comments accordingly. Also make is_running()
> wait for exactly the documented number of tenths by changing its timeout
> test from -gt to the new logic, and quote tm_out in the modified code.
>
> Signed-off-by: Adrian Hunter <adrian.hunter@xxxxxxxxx>

Reviewed-by: Ian Rogers <irogers@xxxxxxxxxx>

Thanks,
Ian

> ---
> tools/perf/tests/shell/lib/waiting.sh | 34 +++++++++++++--------------
> 1 file changed, 16 insertions(+), 18 deletions(-)
>
> diff --git a/tools/perf/tests/shell/lib/waiting.sh b/tools/perf/tests/shell/lib/waiting.sh
> index 3a152892e077..43f4322dbe9e 100644
> --- a/tools/perf/tests/shell/lib/waiting.sh
> +++ b/tools/perf/tests/shell/lib/waiting.sh
> @@ -1,77 +1,75 @@
> #!/bin/bash
> # SPDX-License-Identifier: GPL-2.0
>
> -tenths=date\ +%s%1N
> -
> # Wait for PID $1 to have $2 number of threads started
> -# Time out after $3 tenths of a second or 5 seconds if $3 is ""
> +# Time out after approx. $3 tenths of a second or 5 seconds if $3 is ""
> wait_for_threads()
> {
> tm_out=$3 ; [ -n "${tm_out}" ] || tm_out=50
> - start_time=$($tenths)
> while [ -e "/proc/$1/task" ] ; do
> th_cnt=$(find "/proc/$1/task" -mindepth 1 -maxdepth 1 -printf x | wc -c)
> if [ "${th_cnt}" -ge "$2" ] ; then
> return 0
> fi
> - # Wait at most tm_out tenths of a second
> - if [ $(($($tenths) - start_time)) -ge $tm_out ] ; then
> + if [ "${tm_out}" -le 0 ] ; then
> echo "PID $1 does not have $2 threads"
> return 1
> fi
> + sleep 0.1
> + tm_out=$((tm_out - 1))
> done
> return 1
> }
>
> # Wait for perf record -vvv 2>$2 with PID $1 to start by looking at file $2
> # It depends on capturing perf record debug message "perf record has started"
> -# Time out after $3 tenths of a second or 5 seconds if $3 is ""
> +# Time out after approx. $3 tenths of a second or 5 seconds if $3 is ""
> wait_for_perf_to_start()
> {
> tm_out=$3 ; [ -n "${tm_out}" ] || tm_out=50
> echo "Waiting for \"perf record has started\" message"
> - start_time=$($tenths)
> while [ -e "/proc/$1" ] ; do
> if grep -q "perf record has started" "$2" ; then
> echo OK
> break
> fi
> - # Wait at most tm_out tenths of a second
> - if [ $(($($tenths) - start_time)) -ge $tm_out ] ; then
> + if [ "${tm_out}" -le 0 ] ; then
> echo "perf recording did not start"
> return 1
> fi
> + sleep 0.1
> + tm_out=$((tm_out - 1))
> done
> return 0
> }
>
> # Wait for process PID %1 to exit
> -# Time out after $2 tenths of a second or 5 seconds if $2 is ""
> +# Time out after approx. $2 tenths of a second or 5 seconds if $2 is ""
> wait_for_process_to_exit()
> {
> tm_out=$2 ; [ -n "${tm_out}" ] || tm_out=50
> - start_time=$($tenths)
> while [ -e "/proc/$1" ] ; do
> - # Wait at most tm_out tenths of a second
> - if [ $(($($tenths) - start_time)) -ge $tm_out ] ; then
> + if [ "${tm_out}" -le 0 ] ; then
> echo "PID $1 did not exit as expected"
> return 1
> fi
> + sleep 0.1
> + tm_out=$((tm_out - 1))
> done
> return 0
> }
>
> -# Check if PID $1 is still running after $2 tenths of a second
> +# Check if PID $1 is still running after approx. $2 tenths of a second
> # or 0.3 seconds if $2 is ""
> is_running()
> {
> tm_out=$2 ; [ -n "${tm_out}" ] || tm_out=3
> - start_time=$($tenths)
> while [ -e "/proc/$1" ] ; do
> - # Check for at least tm_out tenths of a second
> - if [ $(($($tenths) - start_time)) -gt $tm_out ] ; then
> + if [ "${tm_out}" -le 0 ] ; then
> return 0
> fi
> + sleep 0.1
> + tm_out=$((tm_out - 1))
> done
> echo "PID $1 exited prematurely"
> return 1
> --
> 2.53.0
>