EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  <20192020  2021  2022  2023  2024  Index 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  <20192020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: epicsThreadSleep and epicsThreadSleepQuantum
From: Mark Rivers via Core-talk <[email protected]>
To: "'Konrad, Martin'" <[email protected]>, "Johnson, Andrew N." <[email protected]>
Cc: "[email protected]" <[email protected]>
Date: Fri, 14 Jun 2019 18:49:00 +0000
I just wrote a little test program to measure the CPU time used when executing a loop for 10 seconds, calling epicsThreadSleep for a user-specified amount of time.  It also prints the value of epicsThreadSleepQuantum().

Here are the results.

The first run sleeps for 0.01 seconds, which is the value of epicsThreadSleepQuantum().  Note that it was 992 loops, close to the 1000 expected.  It used 0.01 seconds of CPU time.
corvette:asyn/testAsynPortDriverApp/src>../../bin/linux-x86_64/testSleep .01
epicsThreadSleepQuantum=0.010000
Sleep time=0.010000
Loops=992, Elapsed time=10.003171, CPU time=0.010000

The second run sleeps for 0.001 seconds.  Note that it was 9295 loops, ~7% fewer than the 10000 expected.  It used 0.14 seconds of CPU time.
corvette:asyn/testAsynPortDriverApp/src>../../bin/linux-x86_64/testSleep .001
epicsThreadSleepQuantum=0.010000
Sleep time=0.001000
Loops=9275, Elapsed time=10.000633, CPU time=0.140000

The third run sleeps for 0.0001 seconds.  Note that it was 60020 loops, ~540% fewer than the 100000 expected.  It used 0.53 seconds of CPU time.
corvette:asyn/testAsynPortDriverApp/src>../../bin/linux-x86_64/testSleep .0001
epicsThreadSleepQuantum=0.010000
Sleep time=0.000100
Loops=60020, Elapsed time=10.000100, CPU time=0.530000

The final run sleeps for 0 seconds.  Note it ran for 183936 loops, and used 0.78 seconds of CPU time.
corvette:asyn/testAsynPortDriverApp/src>../../bin/linux-x86_64/testSleep 0
epicsThreadSleepQuantum=0.010000
Sleep time=0.000000
Loops=183936, Elapsed time=10.000001, CPU time=0.780000

It seems like one of the main uses of epicsThreadSleepQuantum() is when one needs to poll waiting for something that should happen quickly (maybe a few ms).  One wants to minimize both latency and CPU time.  It seems that having some idea of what the minimum effective sleep time is would be better than using 0, since that clearly uses a lot of CPU time.

Mark


-----Original Message-----
From: [email protected] <[email protected]> On Behalf Of Konrad, Martin via Core-talk
Sent: Friday, June 14, 2019 10:10 AM
To: Johnson, Andrew N. <[email protected]>; [email protected]
Subject: Re: epicsThreadSleep and epicsThreadSleepQuantum

Hi Andrew,
> Then epicsThreadSleepQuantum() should return 0 in that case - the 
> AppDevGuide says:
>> If this parameter is unknown or is unpredictable for a particular OS 
>> then it is safe to return zero.
I understand that and it sounds reasonable. The problem is that I have no idea how to detect if _SC_CLK_TCK makes sense or not. Without a way to detect this, epicsThreadSleepQuantum() will return a wrong value on modern Linux machines. I can think of two options:

1. Consider the value unknown on _all_ Linux machines. Modify
epicsThreadSleepQuantum() such that it _always_ returns 0 on Linux.
2. Leave epicsThreadSleepQuantum() as is and mark it deprecated to make it obvious to developers that they are using something that might now work as designed anymore.

-Martin

--
Martin Konrad
Facility for Rare Isotope Beams
Michigan State University
640 South Shaw Lane
East Lansing, MI 48824-1321, USA
Tel. 517-908-7253
Email: [email protected]
#include <stdio.h>
#include <stdlib.h>
#include <epicsThread.h>
#include <epicsTime.h>
#include <time.h>

#define TOTAL_TIME 10.

int main(int argc, char *argv[]) {
  
  epicsTimeStamp startTime, nowTime;
  double timeDiff;
  double sleepTime = atof(argv[1]);
  int numLoops=0;

  printf("epicsThreadSleepQuantum=%f\n", epicsThreadSleepQuantum());
  printf("Sleep time=%f\n", sleepTime);
  epicsTimeGetCurrent(&startTime);
  while (1) {
    epicsThreadSleep(sleepTime);
    epicsTimeGetCurrent(&nowTime);
    timeDiff = epicsTimeDiffInSeconds(&nowTime, &startTime);
    numLoops++;
    if (timeDiff >= TOTAL_TIME) break;
  }
  printf("Loops=%d, Elapsed time=%f, CPU time=%f\n", numLoops, timeDiff, (double)clock()/CLOCKS_PER_SEC);
  return 0;
}

References:
epicsThreadSleep and epicsThreadSleepQuantum Konrad, Martin via Core-talk
Re: epicsThreadSleep and epicsThreadSleepQuantum Konrad, Martin via Core-talk
RE: epicsThreadSleep and epicsThreadSleepQuantum Mark Rivers via Core-talk
Re: epicsThreadSleep and epicsThreadSleepQuantum Michael Davidsaver via Core-talk
Re: epicsThreadSleep and epicsThreadSleepQuantum Konrad, Martin via Core-talk

Navigate by Date:
Prev: Re: epicsThreadSleep and epicsThreadSleepQuantum Konrad, Martin via Core-talk
Next: Re: epicsThreadSleep and epicsThreadSleepQuantum Konrad, Martin via Core-talk
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  <20192020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: epicsThreadSleep and epicsThreadSleepQuantum Konrad, Martin via Core-talk
Next: Re: epicsThreadSleep and epicsThreadSleepQuantum Konrad, Martin via Core-talk
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  <20192020  2021  2022  2023  2024 
ANJ, 14 Jun 2019 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·