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

Kernel: Remove select() as a syscall #11229

Merged
merged 9 commits into from Dec 12, 2021

Conversation

boricj
Copy link
Contributor

@boricj boricj commented Dec 12, 2021

Once upon a time, Unix had no provisions for operating on more than one file descriptor at a time per process. There was blocking I/O as far as the eye can see. Then the BSD sockets API came and trouble brewed, for forking a process per file descriptor to handle seemed rather quaint in the age of early networking.

The select() POSIX function is a relic from a past where 20 file descriptors per process was the limit. Then people soon realized that using bitfields to express sets of file descriptors was a quite silly design and poll() soon appeared in 1987. Nearly 35 years later, it's time to invoke statute of limitations and remove that one bit of Unix legacy cruft from the kernel.

This PR removes select() as a kernel syscall and implements it as a compatibility wrapper inside LibC using poll(). This makes poll() currently the one and only native way on SerenityOS to wait for file descriptors to become ready, pending the day someone implements a more modern, higher-performance mechanism. Maintaining two nearly identical yet independent codepaths in the kernel for the exact same functionality is needlessly redundant, along with all the support code around it.

Note that this PR does not migrate Serenity's userland to poll().

@boricj boricj force-pushed the removeSelectSyscall branch 2 times, most recently from 2dc1752 to c781356 Compare December 12, 2021 16:01
Now that the userland has a compatiblity wrapper for select(), the
kernel doesn't need to implement this syscall natively. The poll()
interface been around since 1987, any code still using select()
should be slapped silly.

Note: the SerenityOS source tree mostly uses select() and not poll()
despite SerenityOS having support for poll() since early 2019...
if constexpr (IO_DEBUG || POLL_SELECT_DEBUG)
dbgln("polling on {} fds, timeout={}", fds_info.size(), params.timeout);

if (current_thread->block<Thread::SelectBlocker>(timeout, fds_info).was_interrupted())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we rename this to PollBlocker?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, SelectBlocker isn't actually strongly tied to either select() or poll(), it's really just a generic blocker for events on a set of file descriptors. It was already a dubious name back when SerenityOS only had select(). Furthermore, the Selecting reason is actually worse because until now the thread could be in select(), poll(), pause(), sigsuspend() and who knows what else...

Since these questions are hard and this PR is just about removing the select() syscall from the kernel, I'll refrain from dealing with those for the time being.

@awesomekling
Copy link
Member

Great idea! ⭐

@awesomekling awesomekling merged commit 23257ca into SerenityOS:master Dec 12, 2021
@boricj boricj deleted the removeSelectSyscall branch December 12, 2021 20:49
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