Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kqueue: use EVFILT_USER as wakeup event if available #4330

Open
wants to merge 4 commits into
base: v1.x
Choose a base branch
from

Conversation

panjf2000
Copy link
Contributor

Eliminate the kernel overhead of pipe if we can.

@panjf2000
Copy link
Contributor Author

Huh, a few confusing test failures surface.

@bnoordhuis
Copy link
Member

I experimented with EVFILT_USER around 2013 and I remember it was broken on macos. Looks like it still is?

I'm afraid I don't really remember the details. Possibly it only worked as a oneshot event, although it seems libevent uses it in multishot mode.

@panjf2000
Copy link
Contributor Author

I experimented with EVFILT_USER around 2013 and I remember it was broken on macos. Looks like it still is?

I'm afraid I don't really remember the details. Possibly it only worked as a oneshot event, although it seems libevent uses it in multishot mode.

EVFILT_USER doesn't seem to exist in the macOS man pages anymore. Maybe there is indeed something wrong with EVFILT_USER.

@panjf2000
Copy link
Contributor Author

Besides, it looks like EVFILT_USER is available on NetBSD since this commit.

Unfortunately, FreeBSD and NetBSD are not available with GitHub Actions, but something like cross-platform-actions may come to help.

src/unix/async.c Outdated Show resolved Hide resolved
@vtjnash
Copy link
Member

vtjnash commented Mar 2, 2024

Would it be sensible to try creating a zero-second one shot timer timeout instead?

@panjf2000
Copy link
Contributor Author

Would it be sensible to try creating a zero-second one shot timer timeout instead?

I don't think this is the right path. In that way, we're unable to ensure a real-time interruption to kqueue/epoll/... cuz it needs to wait for the in-flight uv__io_poll() to finish or for the next round to begin.

@vtjnash
Copy link
Member

vtjnash commented Mar 3, 2024

Isn't it waiting for those anyways?

@panjf2000
Copy link
Contributor Author

panjf2000 commented Mar 3, 2024

Isn't it waiting for those anyways?

No, it isn't. And I think that's why async.c was created, to allow other threads to emit real-time interruptions to the main thread, waking it up from the polling immediately. Please correct me if I'm missing something.

@vtjnash
Copy link
Member

vtjnash commented Mar 3, 2024

A zero second timer should wake it immediately too, though I won't claim to know if that is a useful alternative to the existing pipe

@panjf2000
Copy link
Contributor Author

Kindly ping @bnoordhuis

@bnoordhuis
Copy link
Member

After thinking it over, I'm somewhat disinclined to merge this. It's for niche platforms that I personally don't care about, the changes get intermingled with platform code that I do care about, and the real-world performance improvements aren't clear.

I could maybe be persuaded if it gave a really good bump on the async handles benchmarks (grep test/benchmark-list.h for "async") but no promises.

@panjf2000
Copy link
Contributor Author

After thinking it over, I'm somewhat disinclined to merge this. It's for niche platforms that I personally don't care about, the changes get intermingled with platform code that I do care about, and the real-world performance improvements aren't clear.

I could maybe be persuaded if it gave a really good bump on the async handles benchmarks (grep test/benchmark-list.h for "async") but no promises.

From where I stand, well-testing can justify merging code of improvement. Besides, NetBSD may not catch your attention, but FreeBSD is the Tier-2 support of libuv (also the most popular *BSD system). So if we can run the test suite of libuv on FreeBSD and no errors occur, I'd say it is worth going along.

@bnoordhuis
Copy link
Member

Let's see where other maintainers stand on this.

---------

Signed-off-by: Andy Pan <[email protected]>
@panjf2000
Copy link
Contributor Author

panjf2000 commented May 22, 2024

I've finally discovered the root cause that had been failing the tests on macOS before, uv__async_send() might get called before uv__io_poll() with multi-threads, which resulted in an ENOENT returned from kevent() and the process got aborted. I think we can resume this PR now! @bnoordhuis @vtjnash

@panjf2000
Copy link
Contributor Author

There might be some code conflicts with #4400.

---------

Signed-off-by: Andy Pan <[email protected]>
---------

Signed-off-by: Andy Pan <[email protected]>
@panjf2000
Copy link
Contributor Author

panjf2000 commented May 22, 2024

Some references of EVFILT_USER on various platforms:

@vtjnash
Copy link
Member

vtjnash commented May 22, 2024

Okay, it wasn't clear that EVFILT_USER was available on XNU. Makes more sense now that is clear it is available in the XNU sources, just not documented. Could you run the benchmark on this?

@panjf2000
Copy link
Contributor Author

Okay, it wasn't clear that EVFILT_USER was available on XNU. Makes more sense now that is clear it is available in the XNU sources, just not documented. Could you run the benchmark on this?

Environment

 Model : Mac Studio (2022)
    OS : macOS 14.1.2
   CPU : Apple M1 Max, 10-core CPU with 8 performance cores and 2 efficiency cores
Memory : 32GB unified memory

Benchmark command

build/uv_run_benchmarks_a million_async

Benchmark results

Branch: libuv:v1.x

ok 1 - million_async
# 10,348,986 async events in 5.0 seconds (2,069,797/s, 1,048,576 unique handles seen)

Branch: panjf2000:kqueue-wake

ok 1 - million_async
# 12,977,383 async events in 5.0 seconds (2,595,476/s, 1,048,576 unique handles seen)

@vtjnash

@panjf2000 panjf2000 requested a review from vtjnash May 22, 2024 15:56
@saghul
Copy link
Member

saghul commented May 22, 2024

Nice!

@panjf2000 panjf2000 changed the title kqueue: use EVFILT_USER if available kqueue: use EVFILT_USER as wakeup event if available May 22, 2024
---------

Signed-off-by: Andy Pan <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants