NDDSUtility_sleep() issues on macOS systems

If you are running on a macOS® 10.9 (Mavericks) system (or higher), you may experience timing issues in your calls to NDDSUtility_sleep(). If you request to sleep for a small enough time period, you will notice that the actual sleep time is significantly longer.

In versions 10.9 and higher for the Darwin kernel, Apple introduced and enabled by default a timer coalescing feature. This is a power-saving technique that reduces the precision of software timers, achieving a reduction in CPU usage.

So what effect does this have on your DDS application? Let’s assume you send samples from your publisher at a 5ms rate, using NDDSUtility_sleep() to calculate that wait time. You have a subscriber with a deadline set to 6ms. The timer coalescing feature could make your sleep last much longer than 5-6ms, so when the next sample reaches the subscriber, the deadline period has expired and you will experience missed samples.

If you are having similar issues, see if your kernel has timer coalescing enabled. You can tell by using this command:

user@osx:~$ /usr/sbin/sysctl -a | grep coalescing_enabled

In the reply, a 1 means enabled, 0 means disabled.

kern.timer.coalescing_enabled: 1

To overcome this situation, you must disable timer coalescing in the kernel configuration. Note that you must have sudo or root access to be able to edit this kernel parameter:

user@osx:~$ sudo /usr/sbin/sysctl -w kern.timer.coalescing_enabled=0
kern.timer.coalescing_enabled: 1 -> 0 

This change won’t be permanent though, and will go back to the default when the system is rebooted. To make this change permanent, you need to add the configuration line in the file /etc/sysctl.conf. You can use your favorite editor to do it, or use this command:

user@osx:~$ sudo echo "kern.timer.coalescing_enabled=0" >> /etc/sysctl.conf
Programming Language: