Re: read with very small timeout sometime hand on stdin

2020-11-01 Thread felix
On Thu, Oct 29, 2020 at 01:57:33PM +0100, felix wrote:
> > I can't reproduce this using the following stripped-down reproducer:

Sorry to insist, but... This is not easy because not constant.

For this, I wrote a little script tested on several host, then searching
for installation that was not mine... Tested at https://www.jdoodle.com/ia/3EO

  $ sed <<"eotest" >/tmp/test-timeout-race.sh 's/^//'
#!/bin/bash

declare -p BASH_VERSI{NFO,ON}
uptime
uname -a

po() {
for f in {1..1};do
read -t .01 v
rc=$?
[ $rc -ne 142 ] || [ "$v" ] &&
echo f:$f, v:$v, RC:$rc.
done < <(
for i in {1..1};do sleep 3;echo Timed;done
)
}

exec 2>&1
TIMEFORMAT="U:%U S:%S R:%R"
for test in {1..20};do
time po
done
eotest

If first test don't show strange** output, run test again.
 (** lines begining by `f:`)

-- 
 Félix Hauri  --  http://www.f-hauri.ch



Re: read with very small timeout sometime hand on stdin

2020-10-29 Thread felix
On Wed, Oct 28, 2020 at 09:23:09AM -0400, Chet Ramey wrote:
> 
> I can't reproduce this using the following stripped-down reproducer:

> trap 'echo $f ; exit' SIGINT
> 
> for f in {1..1}; do
>   read -t .01 v
>   if [ $? -ne 142 ]; then
>   echo $f: $?
>   fi
> done
This is strange: $? seem to be alway 142! On my host:
  Debian 10.4 - Intel(R) Core(TM) i5-4570 CPU @ 3.20GHz - 32Gb ram

  $ TIMEFORMAT="U:%U S:%S R:%R"
  $ time for f in {1..1000};do read -t .01 v; [ $? -ne 142 ] &&
  echo f:$f, v:$v, RC:$?. ; done < <(
  for i in {1..1000};do sleep 3;echo;done)
  U:0.206 S:0.032 R:0.240

  $ time for f in {1..1000};do read -t .01 v; [ $? -ne 142 ] &&
  echo f:$f, v:$v, RC:$?. ; done < <(
  for i in {1..1000};do sleep 3;echo;done)
  U:0.167 S:0.068 R:0.236

  $ time for f in {1..1000};do read -t .01 v; [ $? -ne 142 ] &&
  echo f:$f, v:$v, RC:$?. ; done < <(
  for i in {1..1000};do sleep 3;echo;done)
  U:0.207 S:0.049 R:24.152

  $ time for f in {1..1000};do read -t .01 v; [ $? -ne 142 ] &&
  echo f:$f, v:$v, RC:$?. ; done < <(
  for i in {1..1000};do sleep 3;echo;done)
  U:0.177 S:0.067 R:6.233

Where 6 second seem represent two `sleep 3;echo` ...

Same on my raspberry-pi (BCM2835 ARMv6-compatible rev 7 (v6l) - 512M),
  Machine Type: armv6l-unknown-linux-gnueabihf - 5.1.0.rc1

...but with 100 loop and 10 second sleep:


  $ TIMEFORMAT="U:%U S:%S R:%R"
  $ time for f in {1..100};do read -t .01 v; [ $? -ne 142 ] &&
echo f:$f, v:$v, RC:$?. ; done < <(
for i in {1..100};do sleep 10;echo;done ) 
  U:0.447 S:0.021 R:0.995
  
  $ time for f in {1..100};do read -t .01 v; [ $? -ne 142 ] &&
echo f:$f, v:$v, RC:$?. ; done < <(
for i in {1..100};do sleep 10;echo;done ) 
  U:8.589 S:0.108 R:10.918

  $ time for f in {1..100};do read -t .01 v; [ $? -ne 142 ] &&
echo f:$f, v:$v, RC:$?. ; done < <(
for i in {1..100};do sleep 10;echo;done ) 
  U:0.445 S:0.022 R:0.999

  $ time for f in {1..100};do read -t .01 v; [ $? -ne 142 ] &&
echo f:$f, v:$v, RC:$?. ; done < <(
for i in {1..100};do sleep 10;echo;done ) 
  U:0.540 S:0.065 R:10.958

Again, no output! (Result code seem to be alway 142)

But clearly without `sleep 10; echo` loop as input, this test may hang...
until you hit ...  maybe several times...

Nota: None of the host used to make this tests are really ``quiet'':
 My host loadavg: 0.48 0.78 0.91 2/1074 15425
 Raspbery load  : 0.93 1.01 1.12 2/87 28120

This seem harder to reproduce on quiet system
 Other host load: 0.00 0.04 0.00 1/772 468
 U:0.015 S:0.008 R:0.023
 U:0.021 S:0.000 R:0.023
 U:0.021 S:0.000 R:0.022
 U:0.015 S:0.010 R:3.023
 U:0.015 S:0.004 R:0.020
 U:0.018 S:0.004 R:0.023
 U:0.010 S:0.008 R:0.019
 U:0.010 S:0.012 R:0.023
 U:0.023 S:0.000 R:0.024
 U:0.015 S:0.004 R:0.020
 U:0.019 S:0.000 R:0.020
 U:0.015 S:0.008 R:0.023
 U:0.038 S:0.008 R:3.023
 U:0.023 S:0.000 R:0.023
 U:0.030 S:0.000 R:3.025
 U:0.009 S:0.008 R:0.018
 U:0.020 S:0.007 R:3.031


-- 
 Félix Hauri  --  http://www.f-hauri.ch



Re: read with very small timeout sometime hand on stdin

2020-10-28 Thread Chet Ramey
On 10/28/20 7:06 AM, felix wrote:

> Bash Version: 5.1
> Patch Level: 0
> Release Status: rc1
> 
> Description:
> Trying to see limits of timeout with `read -t`, I encounter strange
> and unconstant result: sometime `read -t .01` don't consider
> timeout, when running fastly multiple time.

I can't reproduce this using the following stripped-down reproducer:

trap 'echo $f ; exit' SIGINT

for f in {1..1}; do
read -t .01 v
if [ $? -ne 142 ]; then
echo $f: $?
fi
done


> Ok, then microsecond seem to by smallest value.

Yes, the smallest granularity is microseconds. The code uses interval
timers and timevals.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



read with very small timeout sometime hand on stdin

2020-10-28 Thread felix
Configuration Information:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2 -Wno-parentheses -Wno-format-security
uname output: Linux medium 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) 
x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 5.1
Patch Level: 0
Release Status: rc1

Description:
Trying to see limits of timeout with `read -t`, I encounter strange
and unconstant result: sometime `read -t .01` don't consider
timeout, when running fastly multiple time.

From help:
  -t timeout time out and return failure... may be a fractional...
 ... exit status is greater than 128 if the timeout is exceeded.

Repeat-By:

$ read -t .001 foo ; echo $?
1

$ read -t .01 foo ;echo $?
142

Ok, then microsecond seem to by smallest value.

$ tot=0; for i in {1..100} ;do
rt=${EPOCHREALTIME//.}
read -t .01 foo
((tot+=${EPOCHREALTIME//.}-rt))
sleep .002
  done; echo ${tot:: -2}.${tot: -2}

If this not end after 1 second, hit , wait 1 second
and repeat (and count); You won't hit 100x !
Maybe this return correctly after ~0.2 seconds. If yes, try
again. Mostly I have to hit 3 - 8x for this 100 loop test.

$ tot=0; for i in {1..100} ;do
rt=${EPOCHREALTIME//.}
read -t .01 foo
((tot+=${EPOCHREALTIME//.}-rt))
done < <(
while :;do sleep 1;echo;done
);echo ${tot:: -2}.${tot: -2}

Correct output must be < 1000


-- 
 Félix Hauri  --  http://www.f-hauri.ch