←back to thread

345 points splitbrain | 1 comments | | HN request time: 0s | source
Show context
OsrsNeedsf2P ◴[] No.41837682[source]
I love how simple this is- Barely 100 lines or C++ (ignoring comments). That's one thing that makes me prefer X11 over Wayland.
replies(8): >>41837906 #>>41838181 #>>41838339 #>>41838393 #>>41838489 #>>41838500 #>>41838693 #>>41844644 #
asveikau ◴[] No.41838339[source]
The code is a little weird. There is no XLib event loop. It calls sleep(100) in a loop until it hits SIGINT. That will have high cpu usage for no reason.
replies(3): >>41838378 #>>41844664 #>>41848003 #
diath ◴[] No.41838378[source]
It will not, even adding just a 1ms sleep in a loop will drop CPU usage to barely noticeable levels, 10 wakes a second is barely anything for any CPU from the past 3 decades.
replies(5): >>41838399 #>>41839735 #>>41840345 #>>41845898 #>>41848081 #
asveikau ◴[] No.41838399{3}[source]
Not my experience at all. Granted I haven't tried writing a loop like this in 20ish years, because once you spot that mistake you don't tend to make it again, and CPUs are better now.

Another thing to note is when you call sleep with a low value it may decide not to sleep at all, so this loop just might be constantly doing syscalls in a tight loop.

replies(1): >>41838510 #
diath ◴[] No.41838510{4}[source]
> Not my experience at all. Granted I haven't tried writing a loop like this in 20ish years, because once you spot that mistake you don't tend to make it again, and CPUs are better now.

You can trivially verify it by running the following, I have personally been using "sleep for 1ms in a loop to prevent CPU burn" for years and never noticed it having any impact, it's not until I go into microseconds when I can start noticing my CPU doing more busy work.

    // g++ -std=c++20 -osleep sleep.cpp
    #include <thread>
    #include <chrono>

    int main(int, char **)
    {
     while (true) {
     std::this_thread::sleep_for(std::chrono::milliseconds {1});
     }
     return 0;
    }
> Another thing to note is when you call sleep with a low value it may decide not to sleep at all, so this loop just might be constantly doing syscalls in a tight loop.

On what system? AFAIK, if your sleep time is low enough, it will round up to whatever is the OS clock resolution multiple, not skip the sleep call completely. On Linux, it will use nanosleep(2) and I cannot see any mention of the sleep not suspending the thread at all with low values.

replies(2): >>41839461 #>>41843456 #
asveikau ◴[] No.41839461{5}[source]
If memory serves, Windows treats a sleep under the scheduler quantum length as a yield. It may take you off the cpu if there's something else to run but it may not. Meanwhile burning up cycles may prevent low power states.

At any rate, back to the code at hand, there are many ways to block on SIGINT without polling. But it's also hugely odd that this code does not read events from the X11 socket while it does so. This is code smell, and a poorly behaved X client.

replies(1): >>41841429 #
orbisvicis ◴[] No.41841429{6}[source]
I thought that Linux behaved the same, but I'm not finding any proof in `man 2 nanosleep`...
replies(2): >>41842283 #>>41847422 #
1. gpderetta ◴[] No.41847422{7}[source]
It used to be the case that glibc implemented nanosleep for small values below the scheduling quantum with a spin loop. It was explicitly documented to do so.

This was changed sometimes in the last 20 years, probably with battery powered devices becoming more prevalent and CPUs implementing more advanced sleep states.