A Tale of Two Clocks
In the very first post, I tried (for better or worse) to summarize the purpose of the Windows Time Service. The goal for this service is to keep the clock in sync with whatever time source the user prescribes. In this post, I will take a more abstract view of W32Time and what it tries to acheive.
The ultimate goal of W32time (or any service that implements NTP) is to keep the local clock synchronized. But what do we mean by "the local clock"? For that matter, what is a clock? These two questions have been the basis for a number of questions I have had to answer, since they are both interesting and confusing.
Back to basics
On every computer, in one form or another, there is a hardware-based clock. This physical device is a component on the motherboard, and consists of two parts. These are:
- A timer, to produce a 'tick' at a regular interval
- A chunk of memory, used to store the current 'tick count'.
The way in which a hardware clock is implemented isn't to store the time as "Nov 3, 2007, 12:44:05 PM". This would not only be inefficient, but computing the date every second becomes time-consuming (pun not intended) and would require a microcontroller to do the processing. A much simpler implementation is to simply store the number of 'ticks' (usually in seconds) since a predefined date. This way, the only thing stored in memory is a counter that tell how many ticks have elapsed since the predefined date (known as an epoch). The epoch is usually set by either the motherboard manufacturer or the BIOS manufacturer.
The other issue to consider with hardware clocks is resolution. For every clock (be it hardware or software), the frequency at which is it updated will determine the resolution of the clock. In most systems, the hardware clock is driven by a oscilator running at 32.768 kHz. This frequency is the magical number for computer-based clocks because it is very easly divisible into 1Hz by counting every 2^15 pulse.
The soft clock
Inside of the operating system, you have another (similar) clock. This clock is known as the "system clock", and it is maintained by the kernel of the OS. For all intents and pruposes, this is the clock that you see when you look at the clock in your system tray, or you call the GetSystemTime(...) API function, or just about any other clock you see on the computer. All of these reference the system clock.
In the hardware clock, a timer is used to tell when to increment the clock. The system clock uses a similar contept, but at a higher frequency. Rather than waiting until 2^15 pulses have elapsed to increment the clock, the kernel increments the clock at a much higher interval. By having the kernel increment the clock (in milliseconds) every 32 pulses, you can very easily acheive a clock with 1ms accuracy.
The operating system maintains its own clock in software, but in a different way. Deep within the kernel of the OS, there is a chunk of memory (much in the same way as the hardware clock) that maintains the tick count since the epoch. However, the epoch for an OS is different that of the hardware clock. The epoch for Windows Operating Systems is Jan 1, 1601 at 12:00:00 AM, whereas the epoch or Unix Operating Systems is Jan 1, 1970 at 12:00:00 AM.
Then there was light...
When Windows loads up (or most any other real-time operating system), the kernel has no idea what time it is. System memory gets wiped clean during reboot/shutdown, and storing the time on the hard drive is just a bad idea. During the startup sequence, the kernel will grab time from the hardware clock, and proceed using that time. It will then increment the system clock as explained above. In a perfect world, this would be the end of the story.
However, we don't live in a perfect world. A hardware clock is only accurate to the second, and w32time (or NTP in general) can achieve accuracy better than 1 second, so the clock will always be able to be more accurate than just using the time provided by the hardware clock alone. Let's put this all together to see how the clock behaves when the machine is starting up.
- The machine is off. The current time is held in the hardware clock, and it only accurate to the second
- The machine is turned on. At some point during startup, the kernel reads the time from the hardware clock and starts increments it all on its own.
- Once the machine has been up and running, the w32time service starts and attempts to discipline the clock (to make it more accurate).
- Duing shutdown, the w32time service writes the current time back to the hardware clock, so as to preserve as much of the accuracy as possible that was garnered while w32time was running.
So in this article, we took a look at the basic operations of clock in a computer. Hopefully you have some insight into how these two clocks interact during startup and shutdown. If you have specific thoughts or questions about this post, please feel free to leave a comment. For general questions about w32time, especially if you have problems with your w32time setup, I encourage you to ask them on Windows Vista Applications section of the Microsoft Technet forums.
The information and metrics listed above are general principals I have personally gathered over the years. This information is not to be taken as a guide as to how the Windows kernel operates; they are generic principals used to illustrate the concepts in this article. New advancements in computers, such as High Performance Event Timers (HPET), can change things around quite a bit.