10 Jan 2022

Thoughts about time - part one

Not all clocks are equal

Talk about working with “time” with software engineers and you’re pretty much guaranteed someone is going to post a meme. I was recently talking with a co-worker about managing “simulated time” for a project and we ended up discussing why handling time is so complicated. This post attempts to (non-exhaustively) highlight how “time” works for a computer and some fun gotchas software engineers might have to deal with.

Time in double quotes

Without going into quantum physics to define time, let’s talk about how to measure time in way that is useful for computer science.

Ideally, we’d want to embed Atomic Clocks - the gold standard for measuring time accessible to humans in every computer. But this is not feasible in terms cost and I am not familiar enough with the manufacturing challenges. A quick Google does seem to suggest there are some manufacturers selling something like this.

Without access to embedded Atomic Clocks, we want something that can generate a consistent “tick” signal. What properties would we want in this signal?

  • Always spaced apart by the same duration
  • High resolution (at least more than what you might need)
  • Consistent under changing temperature, voltage and system load
  • Keeps time even when the computer is switched off

This is solved by a quartz crystal embedded in the motherboard circuit - called an RTC (Real Time Clock). The main purpose of RTC is to keep time when the computer isn’t turned on via a small battery. Let’s focus on how the OS handles time.

Time keeping in Linux

When the computer boots, it reads the time from the RTC and then the kernel syncs its own “software clock” based on the RTC.

At this point, we have 3 streams of “time” already:

  • The real time, ie the human time
  • The RTC time
  • The Software clock time

And they can all drift from each other!

Linux has certain system calls that can be used to adjust these clocks based on the drift factors. And since the drift can be either forward or backward, things get complicated. More about that in a bit.

How do we solve this? What if we had a “central” time source we all agreed upon and sync’d everything to it? Well, that exists and it utilizes Atomic Clocks we talked about earlier. These clocks are run by various research labs and military systems that have access to Atomic Clocks.

Modern, internet-connected systems use NTP - the Network Time Protocol designed to let computers sync time over a network, to query these atomic clocks remotely and adjust their own clocks.

Drift: Backwards/Forwards

This is a fun topic to think about: how should the OS adjust the clocks when it’s told by NTP that it’s time keeping has been shoddy? Let’s tackle the backwards drift first.

If the local clock is falling behind, it can be fast-forwarded ahead with relative ease so that it catches up with the “real” time. But what if you have written a program that alarms at 6:00:00pm but your computer adjusted the clock from 5:59:55pm straight to 6:00:25pm? Time keeping systems (NTP) have to take care of adjusting the time in small enough increments so that something like this doesn’t happen - NTP uses sub-second increments while adjusting the clock forward and conversely, slows down the clock if the local time is ahead.