node.jssystem-callsepoll

when does nodejs use epoll_pwait and when it uses epoll_wait


I have noticed that when calling a simple code given below

strace node -e 'setTimeout(()=>{console.log("hola")},10000)'

on arm instance (graviton c7g.2xlarge and Ubuntu 20.04.3 LTS ) with node v18.12.1 it uses epoll_pwait to wait

user@laptop:~$ strace -e epoll_pwait,epoll_wait -c node -e 'setTimeout(()=>{console.log("hola")},10000)' 
hola
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0        10           epoll_pwait
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                    10           total

while on AMD c6a.2xlarge with Ubuntu 20.04.5 LTS with node v18.12.1 same command waits using epoll_wait

user@laptop:~$ strace -e epoll_pwait,epoll_wait -c node -e 'setTimeout(()=>{console.log("hola")},10000)' 
hola
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.000012           1        10           epoll_wait
------ ----------- ----------- --------- --------- ----------------
100.00    0.000012                    10           total

my doubts are

  1. why is nodejs on arm using epoll_pwait vs epoll_wait on x86 architecture
  2. is there any performance hit between using epoll_pwait and epoll_wait
  3. can this behaviour be made uniform using some configuration or am i missing something in my analysis.

Solution

    1. why is nodejs on arm using epoll_pwait vs epoll_wait on x86 architecture

    Linux doesn't have the epoll_wait syscall on ARM64. When the epoll_wait syscall doesn't exist, Glibc implements the epoll_wait function in terms of epoll_pwait instead. This is in accordance with this comment in the Linux kernel:

    As a basic principle, no duplication of functionality should be added, e.g. we don't use lseek when llseek is present. New architectures should use this file and implement the less feature-full calls in user space.


    1. is there any performance hit between using epoll_pwait and epoll_wait

    On ARM64, this isn't a meaningful question, since there is no epoll_wait there to compare to. On x86_64, epoll_pwait does slightly more work than epoll_wait, as you can see in their definitions in the Linux kernel, but I doubt it's significant.


    1. can this behaviour be made uniform using some configuration or am i missing something in my analysis.

    If you really wanted, you could modify the source of nodejs to use epoll_pwait everywhere and then compile it yourself, but I see no benefit to doing this.