OpenEtherCATsociety / SOEM

Simple Open Source EtherCAT Master
Other
1.36k stars 687 forks source link

Incorrect comments about non-blocking IO? #605

Open alokpr opened 2 years ago

alokpr commented 2 years ago

Comments for ecx_outframe and ecx_recvpkt claim non-blocking send and recv respectively: https://github.com/OpenEtherCATsociety/SOEM/blob/master/oshw/linux/nicdrv.c#L264 https://github.com/OpenEtherCATsociety/SOEM/blob/master/oshw/linux/nicdrv.c#L332

However the underlying socket is opened without the SOCK_NONBLOCK flag: https://github.com/OpenEtherCATsociety/SOEM/blob/master/oshw/linux/nicdrv.c#L146

How are send/recv guaranteed to be non-blocking then? Is SOCK_RAW non-blocking by default? If so, how does it interact with SO_RCVTIMEO and SO_SNDTIMEO options? https://github.com/OpenEtherCATsociety/SOEM/blob/master/oshw/linux/nicdrv.c#L150 https://github.com/OpenEtherCATsociety/SOEM/blob/master/oshw/linux/nicdrv.c#L151

alokpr commented 2 years ago

This might not necessarily be a bug. I am just curious about the implementation and wondering if those comments are accurate.

ArthurKetels commented 2 years ago

This subject has a complex history on Linux. Over time various kernels have had different timing behavior with regards to packets on sockets. If you want, you can read a lot about this here.

The current solution is a compromise that has average performance. It is all about finding a balance between responsiveness and CPU usage. Now the performance is good , with low CPU usage, as long there are no or very few drops in data packets. Worst case there is a block of one jiffy.

You could add the SOCK_NONBLOCK flag but then SOEM will start busy-polling and consume much more CPU. The advantage is that the responsiveness is much better as now the high-resolution timer is used.

For the transmission of packets it all does not really matter, if you keep the amount of packets below the line bandwidth there is no blocking no matter what settings are used.

The real underlying issue is that Linux does not provide a networking API that fits the use case of EtherCAT.

alokpr commented 2 years ago

@ArthurKetels Thanks for your response.

You are right about higher cpu usage if we were to busy loop. However SOCK_NONBLOCK is typically used with epoll/select in an event loop. Are you assuming that applications would use SOEM on a dedicated thread. Is that the recommended usage pattern?

I was hoping that SOEM exposed a non-blocking file descriptor that I could stick into the main loop of my application. This is a common pattern followed by many of the networking libraries that fits nicely into application architecture with one main IO thread and multiple worker threads.

nakarlsson commented 2 years ago

@ArthurKetels , I'm trying to conclude a new 1.xx release of SOEM to make a new snapshot release. How should we do with SOCK_NONBLOCK VS ppoll or other solution?