maddiemadan
maddiemadan

Reputation: 103

How does select() monitor without using cpu cycles to poll

While I understand that select call basically puts the process in wait until one of the file descriptors passed to monitor is ready. In contrast to constantly checking the file descriptor until it is ready, the select call provides better performance as it doesn't use any cpu cycles for checking the file descriptors. But how does it really work underneath? How does the monitoring part work without constantly checking the file descriptor's status? In case of file descriptor being a socket, the NIC could trigger an interrupt but how would it work for regular files or stdin or stdout streams?

Upvotes: 1

Views: 414

Answers (2)

bazza
bazza

Reputation: 8414

The underlying mechanism relies on CPU interrupts, and interrupt service routines.

When a device like a network interface card receives some data, it can raise an interrupt. This basically means that the device causes a motherboard connection wired to the CPU on a specific pin is switched from zero volts to 5 volts (or, whatever the appropriate logic level is). This causes the CPU to stop what it's doing and run a piece of code (an interrupt service routine) specific to the particular pin on the CPU pin. This code has been installed in the right place in memory by the operating system, in advance.

Broadly speaking, the interrupt service routine contains the code required to cause the operating system kernel to reconsider what is being run. That'll involve some interaction with the device to find out what has actually happened, which will in turn lead to the kernel knowing which socket corresponds to the network traffic that caused the interrupt to be raised. That in turn allows the kernel to check if the socket is involved in a call to selsect(), which in turn prompts the kernel to reschedule the thread that had been stuck on the select() call.

That's basically how it works for physical network connections. Other devices that can be wrapped up in a call to select() includes serial ports (which can also raise interrupts).

Other things like Unix domain sockets work in another way, in that the act of sending data gives the operating system kennel an opportunity to reassess what should be running.

Really, that's what it's all about, somehow grabbing the attention and of the kernel ASAP. Interrupts are a way of doing that. Any file descriptor that represents a physical device relies on an interrupt. Everything else like a pipe is internal to the operating system, and therefore the kernel already knows about the activity related to the descriptor.

Very old unixes and other old operating systems didn't do this, they have to poll the hardware device to see if anything had happened. This took a fair bit of CPU time. Some systems are still done this way. Interrupts cause a problem when it comes to formal proofs of system correctness, because they're asynchronous (you can't test all possible timings). So systems like railway signalling (safety critical, must be correct), tend to be written to poll devices, rather than use interrupts. One can more easily prove / demonstrate adequate polling rates,

Upvotes: 2

Eric Postpischil
Eric Postpischil

Reputation: 222724

The core of select is a system call. It tells the operating system the process wants to wait for activity on the file descriptors.The operating system updates its records to show the process is in a waiting state, not ready to run, and it does not run the process until something happens. It also updates records associated with the file descriptors to note that a process is waiting for them.

Then the operating system goes on to do other things. It runs other processes on the processor(s), it responds to device interrupts, and so on. When a time comes that there is nothing for the system to do—no processes are ready to run (that are not already running on one of the processors) and all interrupts have been serviced, the operating system executes some sort of wait or sleep instruction that lets the processor go dormant for a time.

When the processor is in a wait or sleep state, the hardware will wake it when an interrupt arrives.

When there are changes for the associated file descriptors, the system marks the process ready to run again, and it will run it according to its usual scheduling algorithms.

Upvotes: 2

Related Questions