3 ms·
The crucial operation here is epoll_wait, not epoll_create. Are you saying that the system call is performed on another kernel thread while goroutine continue
by nsm 3y ago
The crucial operation here is epoll_wait, not epoll_create.
Are you saying that the system call is performed on another kernel thread while goroutine continue running on the GOMAXPROCS threads?
- gpderetta 3y agoSo, I'm not familiar with the go event loop specifically, but I have written a few event loops myself. You can think of an event loop multiplexing across multiple sources of events: for example a local ready queue, a remote queue (for tasks coming from other threads), an io-queue, a timer queue. Epoll is used for the io-queue. If the local ready queue is empty (i.e. there are no runnable coroutines), the event loop will block in the epoll call, possibly until the next timer expiration if any; remote queue operations will wake-up the poll via somethink like event-fd. If the local queue is non-empty, epoll is called with a 0 timeout every N local queue pops (actual scheduling logic and priority is application specific of course). Polling epoll with a 0 timeout is a bit wasteful, for high performance applications you can use io_uring so checking for non-empty queue is very cheap and/or use some network bypass library that makes epoll cheap. There is also old-school readiness notification via signals but I doubt that still see any use. As you suggest, you could also have a dedicated thread per event loop just running poll (for example a sibling hyperthread), but it seems wasteful.
- muxator 3y agoThanks for this comment! It is a very helpful design document for improving one's future event loops architecture!