Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

sleep and sleep_for on Linux

130 views
Skip to first unread message

Emanuel Berg

unread,
Oct 9, 2014, 9:29:56 PM10/9/14
to
I would like to have the program sleep for a fixed
amount of milliseconds each time a loop iterates.

I tried two approaches, starting from the int variable
"rate" - how many milliseconds the computer should
sleep.

Both seem to work only sleep seems to sleep much
*less* than sleep_for.

With sleep I have 791710 iterations of the loop, and
with sleep_for - 2975!

Can anyone explain this?

What is the correct way to sleep for x milliseconds?

sleep(rate/1000);

std::this_thread::sleep_for(std::chrono::milliseconds(rate));

Help very much appreciated.

--
underground experts united

Jouko Koski

unread,
Oct 10, 2014, 1:49:25 AM10/10/14
to
> "Emanuel Berg" wrote:

> I tried two approaches, starting from the int variable
> "rate" - how many milliseconds the computer should
> sleep.

> sleep(rate/1000);

Considering declaration
unsigned int sleep(unsigned int seconds);
and integer arithmetics, what do you expect rate/1000 to be?

Isn't it obvious that
> std::this_thread::sleep_for(std::chrono::milliseconds(rate));
is the preferred way?

--
Jouko

Geoff

unread,
Oct 10, 2014, 9:39:15 AM10/10/14
to
On Fri, 10 Oct 2014 03:29:51 +0200, Emanuel Berg
<embe...@student.uu.se> wrote:

>I would like to have the program sleep for a fixed
>amount of milliseconds each time a loop iterates.
>
>I tried two approaches, starting from the int variable
>"rate" - how many milliseconds the computer should
>sleep.
>

Time in milliseconds isn't a rate, it's a duration.

>Both seem to work only sleep seems to sleep much
>*less* than sleep_for.
>

The sleep function has units of seconds, why do you think your "rate"
in milliseconds divided by 1000 would change that? The smallest
quantum of sleep() you can get is 1 second.

>With sleep I have 791710 iterations of the loop, and
>with sleep_for - 2975!
>
>Can anyone explain this?
>

man 3 sleep

>What is the correct way to sleep for x milliseconds?

std::this_thread::sleep_for(std::chrono::milliseconds(duration));

Emanuel Berg

unread,
Oct 10, 2014, 3:01:16 PM10/10/14
to
"Jouko Koski" <joukokos...@netti.fi> writes:

> Considering declaration unsigned int sleep(unsigned
> int seconds); and integer arithmetics, what do you
> expect rate/1000 to be?

Aha, I thought it was the same interface as /bin/sleep.

--
underground experts united

Emanuel Berg

unread,
Oct 10, 2014, 3:06:34 PM10/10/14
to
Geoff <ge...@invalid.invalid> writes:

> Time in milliseconds isn't a rate, it's a duration.

Here it is a name of a variable that is read from the
argument the user provides to express the rate "once,
for every...".

--
underground experts united

Ben Bacarisse

unread,
Oct 10, 2014, 3:22:49 PM10/10/14
to
Emanuel Berg <embe...@student.uu.se> writes:

> "Jouko Koski" <joukokos...@netti.fi> writes:
>
>> Considering declaration unsigned int sleep(unsigned
>> int seconds); and integer arithmetics, what do you
>> expect rate/1000 to be?
>
> Aha, I thought it was the same interface as /bin/sleep.

That would not make any difference. You referred to the 'int variable
"rate"' so rate/1000 is an integer no matter what that prototype for the
sleep function is.

--
Ben.

Emanuel Berg

unread,
Oct 10, 2014, 3:24:48 PM10/10/14
to
Ben Bacarisse <ben.u...@bsb.me.uk> writes:

> That would not make any difference. You referred to
> the 'int variable "rate"' so rate/1000 is an integer
> no matter what that prototype for the sleep function
> is.

Yes, I understood, I actually tried stuff like 0.001
as well but got the same (lack of) result.

--
underground experts united

Ike Naar

unread,
Oct 10, 2014, 3:34:10 PM10/10/14
to
On 2014-10-10, Emanuel Berg <embe...@student.uu.se> wrote:
> I would like to have the program sleep for a fixed
> amount of milliseconds each time a loop iterates.

Don't sleep till some time has elapsed.
Do sleep till an intersting event has happened.

Emanuel Berg

unread,
Oct 10, 2014, 4:19:23 PM10/10/14
to
Ike Naar <i...@iceland.freeshell.org> writes:

> Don't sleep till some time has elapsed. Do sleep
> till an intersting event has happened.

Indeed, feel free to help me with that as well!

The purpose is to have the program terminate after a
certain number of LLC misses.

Usage: llc ALLOWED-LLC-MISSES PID POLL-RATE-MS

Here is the poll loop, starting at line 57 in llc.cc:

for (long long polls = 0, count = 0, old_count = -1;
count < max_misses; polls++) {
read(fd, &count, sizeof(count));
if (count != old_count) {
std::cout << "LLC misses after " << polls << " polls: "
<< count << std::endl;
old_count = count;
}
std::this_thread::sleep_for(std::chrono::milliseconds(rate));
}

Here is the program:

http://user.it.uu.se/~embe8573/llc/

--
underground experts united

Geoff

unread,
Oct 10, 2014, 10:56:30 PM10/10/14
to
On Fri, 10 Oct 2014 21:06:34 +0200, Emanuel Berg
<embe...@student.uu.se> wrote:

>Geoff <ge...@invalid.invalid> writes:
>
>> Time in milliseconds isn't a rate, it's a duration.
>
>Here it is a name of a variable that is read from the
>argument the user provides to express the rate "once,
>for every...".

For repetitive events, rate and period have reciprocal relationship.
Your selection of variable name "rate" is inappropriate for code that
is expressing a period of time. A rate of 50Hz has a period of 0.020
seconds, this was the point of my statement.

If you are going to ask your user to select a "rate" then you need to
compute the period for that rate and pass that to your "sleep"
function, whatever that may be. Furthermore, since the quantum of the
POSIX sleep function is 1 second, you cannot use it for your stated
purpose.

Ian Collins

unread,
Oct 10, 2014, 11:10:18 PM10/10/14
to
Emanuel Berg wrote:
> I would like to have the program sleep for a fixed
> amount of milliseconds each time a loop iterates.

Did you try the obvious (for Unix/Linux): usleep()?

--
Ian Collins

Emanuel Berg

unread,
Oct 10, 2014, 11:18:23 PM10/10/14
to
Ian Collins <ian-...@hotmail.com> writes:

>> I would like to have the program sleep for a fixed
>> amount of milliseconds each time a loop iterates.
>
> Did you try the obvious (for Unix/Linux): usleep()?

No. Why, is that better than sleep_for?

--
underground experts united

Ian Collins

unread,
Oct 10, 2014, 11:27:26 PM10/10/14
to
Emanuel Berg wrote:
> Ian Collins <ian-...@hotmail.com> writes:
>
>>> I would like to have the program sleep for a fixed
>>> amount of milliseconds each time a loop iterates.
>>
>> Did you try the obvious (for Unix/Linux): usleep()?
>
> No. Why, is that better than sleep_for?

It's a lot less typing!

I must admit I've been using usleep() and nanosleep() for so long I
haven't looked at the C++ thread alternatives.

--
Ian Collins

Emanuel Berg

unread,
Oct 10, 2014, 11:35:45 PM10/10/14
to
Ian Collins <ian-...@hotmail.com> writes:

> It's a lot less typing!

Ha ha. Right on.

--
underground experts united

Geoff

unread,
Oct 10, 2014, 11:54:43 PM10/10/14
to

I found no difference in the precision of duration of sleeps on my
MacBookPro. Excess time seemed to vary between 110 and 1010us.

Perhaps your system performs differently.

#include <iostream>
#include <thread>
#include <unistd.h> // for sleep()

int main(int argc, const char * argv[])
{
std::chrono::steady_clock::time_point start, end;

start = std::chrono::steady_clock::now();
sleep(1);
end = std::chrono::steady_clock::now();

std::cout << "sleep() took "
<< std::chrono::duration_cast<std::chrono::microseconds>(end -
start).count()
<< "us.\n";

start = std::chrono::steady_clock::now();
usleep(1000000);
end = std::chrono::steady_clock::now();

std::cout << "usleep() took "
<< std::chrono::duration_cast<std::chrono::microseconds>(end -
start).count()
<< "us.\n";


start = std::chrono::steady_clock::now();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
end = std::chrono::steady_clock::now();

std::cout << "sleep_for() took "
<< std::chrono::duration_cast<std::chrono::microseconds>(end -
start).count()
<< "us.\n";

return 0;
}


sleep() took 1000955us.
usleep() took 1000964us.
sleep_for() took 1000970us.

Jorgen Grahn

unread,
Oct 13, 2014, 2:38:57 PM10/13/14
to
On Sat, 2014-10-11, Geoff wrote:
>
> I found no difference in the precision of duration of sleeps on my
> MacBookPro. Excess time seemed to vary between 110 and 1010us.
>
> Perhaps your system performs differently.

Last time I looked, it depended a lot on how the Linux kernel was
configured, e.g. the length of a "tick".

The OP didn't (I think) say what he wanted to accomplish, but the
thing he /did/ do -- wait for a few milliseconds inside a loop -- is
often the wrong solution. Been there, done that.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Jorgen Grahn

unread,
Oct 13, 2014, 4:54:51 PM10/13/14
to
On Fri, 2014-10-10, Emanuel Berg wrote:
> Ike Naar <i...@iceland.freeshell.org> writes:
>
>> Don't sleep till some time has elapsed. Do sleep
>> till an intersting event has happened.
>
> Indeed, feel free to help me with that as well!
>
> The purpose is to have the program terminate after a
> certain number of LLC misses.
>
> Usage: llc ALLOWED-LLC-MISSES PID POLL-RATE-MS

(LLC probably relates to "last-level cache", and the program uses a
Linux mechanism to get the number of data(?) cache misses generated
by a process.)

I still don't see the purpose. To "have the program terminate after a
certain number of LLC misses" is a description of what the program
literally does, but doesn't explain /why/.

OTOH, if this /is/ literally what you want to do and it's important to
not exit a millisecond late, I see no better solution. And the user
controls the poll rate anyway, so ...

I've fought similar problems when I've written packet generators.
Letting a user say e.g. "I want send 13700 UDP packets per second to
10.1.2.3" you have two choices:

- Reply "you can't say that, you can just ask for a delay between
the packets, and then you have to measure the rate yourself".

- Write code to measure the rate and adapt the delay (and burst size)
so you hit the rate on average, and warn if you cannot keep up with
no delay at all.

Emanuel Berg

unread,
Oct 14, 2014, 9:33:06 PM10/14/14
to
>> Indeed, feel free to help me with that as well! The
>> purpose is to have the program terminate after a
>> certain number of LLC misses. Usage: llc
>> ALLOWED-LLC-MISSES PID POLL-RATE-MS
>
> (LLC probably relates to "last-level cache", and the
> program uses a Linux mechanism to get the number of
> data(?) cache misses generated by a process.)

Correct.

> I still don't see the purpose. To "have the program
> terminate after a certain number of LLC misses" is a
> description of what the program literally does, but
> doesn't explain /why/.

Right, OK - this will be a bit difficult to clarify.

It is a real-time system but on a normal Linux
dualcore computer.

On one core, I have a critical scheduler that runs
critical tasks. Scheduling is done periodically
according to the EDF algorithm and task-model. All
that stuff run on the critical core.

The other core is just another normal general-purpose
core but for this situation it is a best-effort core.
There run best-effort processes.

Because the BE-core and critical core share the DRAM
the BE-core can slow down execution of the critical
tasks on the critical core, if there are too much
BE-traffic to the DRAM. That is why for each period
the critical scheduler knows the total number of
allowed BE-memory accesses for that particular
critical task (or group of critical tasks)...

With the method I posted previously, it is possible to
count the number of LLC misses (or DRAM fetches) for
the BE-software. Only optimally that wouldn't be
polled (the sleep - check - sleep - check - ... loop)
but instead possibly be setup as an interrupt.

Right now I don't know what to do except that I'm not
happy with polling.

--
underground experts united

J. Clarke

unread,
Oct 15, 2014, 5:06:09 AM10/15/14
to
In article <87eguaw...@debian.uxu>, embe...@student.uu.se says...
It sounds like what you want to do is set up the performance counters to
trigger an interrupt when a threshold number of LLC misses occurs.

I don't know of a facility in Linux that supports this--you may have to
create or modify an interrupt handler. You can download the docs for
the processors from
http://www.intel.com/content/www/us/en/processors/architectures-
software-developer-manuals.html and you might want to check into "perf",
which doesn't seem to provide an api for you to use to hook the
interrupt but may have pieces that you can modify to suit your need.

J. Clarke

unread,
Oct 15, 2014, 5:06:11 AM10/15/14
to
In article <87eguaw...@debian.uxu>, embe...@student.uu.se says...
>
Forgot to mention, a simpler approach might might be to just turn off
LLC read-caching on the "BE" core, which will slow it down but also
reduce interference with the crtical core. This is also discussed in
the Intel software manual
<http://www.intel.com/content/www/us/en/processors/architectures-
software-developer-manuals.html>

Jorgen Grahn

unread,
Oct 18, 2014, 3:02:09 AM10/18/14
to
Seems to me your problem is based in that you have a system with
- a real-time part
- a best effort part
and they influence each other, yet they aren't under any common
control. Under those conditions, I don't see that you can do anything
very much better than ad hoc stuff like your polling.

(Someone else suggested ways to cut down on the influence.)

Disclaimer: I'm not good at real-time. For the stuff I usually work
with, high throughput, low latency and low resource requirements are a
goal, but I'm not used to hard limits and deadlines.

Emanuel Berg

unread,
Oct 19, 2014, 4:01:00 PM10/19/14
to
Jorgen Grahn <grahn...@snipabacken.se> writes:

> Seems to me your problem is based in that you have a
> system with - a real-time part - a best effort part
> and they influence each other, yet they aren't under
> any common control. Under those conditions, I don't
> see that you can do anything very much better than
> ad hoc stuff like your polling.
>
> (Someone else suggested ways to cut down on the
> influence.)

OK, first, thank you, and thank you to J. Clarke as
well.

You are absolutely right, the problem is that there is
RT and BE and they influence each other. The challenge
is to isolate them except for what cannot be isolated,
which is the shared DRAM.

But, the RT part doesn't have to be isolated from the
BE part, as long as the influence can be bounded. If
it can be bounded, it can be computed, and then
formalized, i.e., the BE influence will be
incorporated and accounted for in the RT part.

At this moment, the RT part knows how many accesses
the BE part can be allowed to make, and this is
communicated to the Linux kernel with a syscall.

The BE processes are told to run exclusively on the BE
core (in userspace) with the tool taskset
('taskset -c CORE') and with this

GRUB_CMDLINE_LINUX_DEFAULT="quiet isolcpus=0"

in /etc/default/grub - it works, they only run there
and this can be confirmed with 'top' or 'ps'.

Do you happen to know how the scheduler can be
modified to, whenever told so (doesn't matter by means
of an interrupt or polling), how the scheduler can be
told to not execute those tasks, i.e. to freeze the BE
core?

Or is that better setup on a process basis, as in a
field in the PCB or something? (I would think that's
where ps and top get their information.)

--
underground experts united
0 new messages