I recently came across an interesting issue on Solaris. I was trying to do something pretty simple:
- Check to see if there’s work to do.
- If there is work to do, then do it and go back to step 1.
- Sleep for a short length of time and go back to step 1.
This worked great on Linux, but not so well on Solaris. Things were getting done in fractions of a millisecond on Linux, but it was taking over ten milliseconds on Solaris. I hypothesized that the sleep might be the problem, and a quick test confirmed it. It turns out that on Solaris in the default configuration you can’t sleep for less than ten milliseconds at a time (at least in Java). This is because on Solaris, the Java sleep method is dependent on system clock ticks, and the default configuration uses 100 ticks per second, or one tick every ten milliseconds. Any attempt to sleep for less than that time will get rounded up to ten milliseconds, and attempts to sleep for a length of time greater than that will be rounded up to the nearest multiple of ten milliseconds.
You can change this behavior by adding the following to the
/etc/system file and rebooting the system:
This will change the default from 100 ticks per second to 1000 (which means you can sleep in increments of one millisecond instead of ten). There is also a way to fine-tune how many ticks per second you want (via
hires_hz), but changing that isn’t supported and every mention of it I can find indicates that you don’t want to increase the frequency anyway because it will probably degrade performance as it will become expensive to update the tick counter too often.
There are, of course, other ways to accomplish the task I had originally set out to do (e.g., blocking queues, semaphores, wait/notify, etc.), but the bigger takeaway here is that you shouldn’t depend on algorithms involving fine-grained sleeping, especially if your application needs to run on Solaris.