#52 Ptpd timer subsystem rewrite

All_Versions
open
None
5
2013-10-20
2013-10-18
No

Another patch I dug out of my archive.

The attached patch is a complete rewrite of the timer subsystem, making use of the more modern timer_create, timer_settime etc. With the use of POSIX timer API, the alarming signal can pass data to the signal handler. With this patch, one timer per timer table entry is created and the signal handler does not have to loop - it is told straight away which timer fired by reading its underlying data structure, and that timer is marked as expired. Timers are still asynchronous, but there is no continuous stream of signals being delivered to ptpd - signals are fired only when timers expire.

There are no changes to the timer interface and other ptpd code, only to the function bodies and initialisation / shutdown of the timers.

This patch:

  • Improves performance and allows using as high message rates as desired (bug #57)
  • Ignores timer signals from an external source (bug #58)
  • Adds support for "unlimited" message rates when ptpd compiled with PTPD_EXPERIMENTAL. This allows using ptpd for performance testing out of the box and without modifications.
  • In debug mode, logs names of timers fired

This would need to be checked for compatibility issues on FreeBSD and other non-Linux OSes.

1 Attachments

Discussion

  • Jan Breuer
    Jan Breuer
    2013-10-18

    I just want to play with this after release, but doing different approach similar to "snmp_select_info" function. I don't even know if I finish my attempt so it is not blocker for your patch.

    I have some problems with asynchronous timers on other platforms (currently not supported by PTPd - Microsoft Windows, IntervalZero RTX and FreeRTOS+LwIP) because there is no easy way to interrupt select function but they have ability to set timeout for the select.

     
  • Well - there is the timerfd_* family of functions that allow your timers to wake up poll() or select() - since the main ptpd event loop spins around polling, that is an option. You could also just use a timeout of 62500 us or wharever. When using a timeout you don't need timers at all, you use your old method update_timers like before.

    For those platforms that do interrupt the polls on signals, this patch works really well and gives you a free stress test tool.

    RC1 still hasn't been cut for 2.3 so I'm tempted :)

     
  • Jan Breuer
    Jan Breuer
    2013-10-18

    Your solution is perfect for Linux and FreeBSD (I hope, I can test this on monday). I'm afraid that it will not work in OSX

    http://lists.apple.com/archives/unix-porting/2009/May/msg00004.html

    timerfd_* family of functions are nice but they are Linux specific and we are not linuxptp.

    So, if it is possible to cover new code by

    #if _POSIX_TIMERS && (_POSIX_TIMERS - 200112L) >= 0
    #else
    #endif
    

    inside these functions so timer API will be same for both versions, I'm not against this.

     
    Last edit: Jan Breuer 2013-10-18
  • I gather this is not planned for 2.3, correct?

     
  • George,

    Not necessarily, I'm exploring ptpd improvements, but I'm considering adding a "patches" directory to svn and maybe to the build tarball. Many projects do that, it makes it easier for people to test things or try out new functionality.

    Jan,

    Unfortunately the old system has one advantage: there is only one timer. With this code, at really high rates, the signals are starting to queue up and not all get handled, and eventually the process is stuck in one big signal processing loop - no select() ever succeeds and ptpd starts sitting idly. Ignoring SIGALRM inside the signal handler helps a little, but there is still a breaking point. Basically this patch makes most sense at low rates, because then there is really very little computational expense. Also with this, ptpd2 can do 1024 packets per second easy enough :)

    As to committing this or something similar - currently ptpd2 does not support higher messsage send rates than 16/sec, which basically doesn't meet the standard requirements, which allow up to 2^-7.

    I think that the solution is to keep one timer, but make its rate dynamic: the timer rate should be the interval of the quickest firing timer of all. The interval of all timers is tracked and the shortest interval of all is the delta.

    There is still the problem of an external SIGALRM being able to interfere with ptpd - sigaction handles this by ensuring that the signal came from an alarm.

    We could even get rid of timers completely and use select() timeouts as timers!

     
  • Jan Breuer
    Jan Breuer
    2013-10-18

    We could even get rid of timers completely and use select() timeouts as timers!

    This was my first cryptic comment - doing it like "snmp_select_info"

     
  • ...Or basically we should stop re-inventing the wheel and use libevent for both sockets and timers like everyone else - to stop this "this doesn't work on OSX" nonsense.