
How long does your nanosleep() really sleep? (2004) - lkurusa
https://www.dragonflybsd.org/presentations/nanosleep/
======
clarry
This bug is still there in OpenBSD. With the 100Hz tick rate, sleep(10ms)
turns effectively into 15 milliseconds, or -- more likely -- 20 milliseconds
if the system is lightly loaded and the program doesn't spend much of its
timeslice.

Of course, some programs don't expect this.

Fun story, me and my little sister played a game online years ago. The Mana
World. A game with an OpenBSD port. She teamed up with some guy in game. She
also told me that guy had a terrible internet connection & slow PC. So once I
found them, I watched this guy lag and move about in slow motion. I asked if
he's running OpenBSD. He said he's running OpenBSD. I sent him a little patch
and it's like he got a new PC and a new internet connection, just like that..
:-)

~~~
mikroskeem
can you put this patch up somewhere, e.g gist.github.com or something? or
atleast point us where to look exactly? thank you :)

~~~
clarry
Why, do you work on TMW?

Like I said, it was years ago. If I still have the patch, it's got to be on
one of these spinning rust disks sitting in my closet. I'm on a trip so I
really can't look for it now.

Assuming the client is still buggy (things like SDL2 have happened so who
knows?), I'd probably look here first:

[https://gitlab.com/manaplus/manaplus/blob/485e9bb12bf5dda318...](https://gitlab.com/manaplus/manaplus/blob/485e9bb12bf5dda318ac0ccbf1d2a1cd86cf8c70/src/utils/timer.cpp#L64)

The logic won't run right if the timer is implemented with a sleep that ends
up sleeping much longer than intended. If it works like it did back then
(sleep is virtually always 20ms), simply incrementing the tick count by two
every time should be enough to make it smooth on OpenBSD. Of course the
correct fix is to keep track of actual time spent and adjust ticks
accordingly. Or use a timer mechanism that has higher precision. IIRC
setitimer[1] can get you a regular 100Hz alarm on OpenBSD.

[http://man.openbsd.org/setitimer.2](http://man.openbsd.org/setitimer.2)

If I'm not entirely mistaken, the old userspace implementation of pthreads
worked with a 100Hz timer using this mechanism.

~~~
mikroskeem
>Why, do you work on TMW?

oh, no. i'm just curious

------
loeg
On modern FreeBSD, when I run the article's demo program, by default I see
even higher and more variable latency than the author observed in 2004:

    
    
        0.017686
        0.031868
        0.055889
        0.008931
        0.014824
    

However, when I set the kern.timecounter.alloweddeviation sysctl ("Allowed
time interval deviation in percents") to 0 (from the default of 5%), I get
very low and consistently low latency:

    
    
        0.000036
        0.000031
        0.000030
        0.000037
        0.000036
        0.000040
    

There are pros and cons to both defaults.

~~~
macdice
Can you elaborate on the cons?

~~~
loeg
Sure thing.

Why make wakeup imprecise by default? The slop allows for some coalescing of
nearby (in time) events into a single wakeup, saving power[0]. This article
provides some figures that give a good intuition for why this might work:
[https://arstechnica.com/gadgets/2013/06/how-os-x-
mavericks-w...](https://arstechnica.com/gadgets/2013/06/how-os-x-mavericks-
works-its-power-saving-magic/)

See also: tickless kernels in general[1]; FreeBSD switched to a tickless
kernel with coalescing about 5.5 years ago[2].

[0]:
[https://en.wikipedia.org/wiki/Timer_coalescing](https://en.wikipedia.org/wiki/Timer_coalescing)

[1]:
[https://en.wikipedia.org/wiki/Tickless_kernel](https://en.wikipedia.org/wiki/Tickless_kernel)

[2]:
[https://svnweb.freebsd.org/base?view=revision&revision=24777...](https://svnweb.freebsd.org/base?view=revision&revision=247777)

~~~
scoot_718
Yes it's true. This kernel has no tick.

~~~
wyldfire
"Well, that's what I heard!"

------
js2
Solaris 8 briefly had a kernel bug such that usleep() didn't sleep at all. I
don't recall the details, just that after patching the system and rebooting
things were behaving very bizarrely. I eventually realised the sleep command
was returning instantly and from that tracked it to the system call, and then
found a patch for the issue. Google is failing me in digging up any details.
It would've been in the 2000-2004 time frame.

~~~
cryptonector
EDIT: Oy, TFA is from 2004. Never mind my comment about Solaris 8 being
ancient.

