mitchellh / libxev

libxev is a cross-platform, high-performance event loop that provides abstractions for non-blocking IO, timers, events, and more and works on Linux (io_uring or epoll), macOS (kqueue), and Wasm + WASI. Available as both a Zig and C API.
MIT License
1.97k stars 65 forks source link

Windows bug? #70

Open rsepassi opened 11 months ago

rsepassi commented 11 months ago

Don't have a clean repro at the moment, but initial check of the Windows support indicated that 2 timers were running sequentially instead of in parallel; could very well have been holding it wrong, but the same code worked fine on Linux and Mac. cc @Corendos

Non-clean repro is the zigcoro test. https://github.com/rsepassi/zigcoro windows branch

Corendos commented 11 months ago

I don't really have a way of checking right now, but from what I get from your message (and if I'm not misunderstanding) I'd say that it's to be expected for the timer to run sequentially.

Since the event-loop is single-threaded, I don't see a way where the timers would run in parallel. Could you point me to the failing test in zigcoro ? :slightly_smiling_face:

rsepassi commented 11 months ago

https://github.com/rsepassi/zigcoro/pull/13

zig build test-aio

Not the cleanest repro. I think a simpler repro would simply start 2 timers in parallel, e.g. 1 for 10ms and another for 20ms, wait for both to complete, and test that no more than ~20ms has passed (i.e. should be <<30ms). The event loop is single-threaded but it can have many in-flight operations going at once.

Corendos commented 11 months ago

I'll try to investigate when possible.

In the meantime, I think it's important to notice that timing on Windows is really hard to get right. If I'm correct, granularity is very high. For example, multiple milliseconds can pass when using the sleep function. Maybe that's similar with the timeout given to the GetQueuedCompletionStatusEx function that I use in the code.

rsepassi commented 11 months ago

Understood, thanks for looking into it! Yeah, maybe test with higher durations like 100ms and 500ms locally just to make sure.

On Fri, Sep 29, 2023 at 2:25 AM Corentin Godeau @.***> wrote:

I'll try to investigate when possible.

In the meantime, I think it's important to notice that timing on Windows is really hard to get right. If I'm correct, granularity is very high. For example, multiple milliseconds can pass when using the sleep function. Maybe that's similar with the timeout given to the GetQueuedCompletionStatusEx function that I use in the code.

— Reply to this email directly, view it on GitHub https://github.com/mitchellh/libxev/issues/70#issuecomment-1740581846, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIQMW3U64DKAS4VA3GEDOTX42HWZANCNFSM6AAAAAA5LH33GM . You are receiving this because you authored the thread.Message ID: @.***>

Corendos commented 10 months ago

Hey @rsepassi

I tried to reproduce the issue at home and it seems to be an issue of granularity. I had some adaptations to make due to latest Zig version.

The "aio sleep run" test is sometimes failing but multiplying the durations by 10 seems to make it work everytime, so I'd say that's more of an issue with what I mentioned earlier about Windows timing precision.

The "aio concurrent sleep" should manifest the same behavior but it's segfaulting currently so I can't be sure.

Unfortunately, I don't really know what can be done currently to improve timing precision on Windows, that was one of the limitation I mentioned in the PR 😕

I tested with Zig 0.12.0-dev.1261+bb0419599

amoldeshpande commented 4 months ago

The way to do higher resolution sleeps/waits in Windows is the multimedia timer API.

This blog post explains a recent change to the framework and gives good information about timer resolutions in the process.

https://randomascii.wordpress.com/2020/10/04/windows-timer-resolution-the-great-rule-change/