My operating system targets x86-64 and is a microkernel.
I'm looking for timer source that I can read relatively quickly from user-space in an event loop. For example, measure the delta time since the last frame update so I can update the UI animations.
I read through https://wiki.osdev.org/Time_And_Date and also about PIT and HPET. I'm leaning towards HPET since I believe I can read it from user-code vs. having to query an IO port (which means I'll have to RPC to a driver to do it).
What do you all use?
Delta time sources (x86-64)
- AndrewAPrice
- Member
- Posts: 2300
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Delta time sources (x86-64)
My OS is Perception.
-
- Member
- Posts: 5568
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Delta time sources (x86-64)
Why poll the timer when the timer could send interrupts to you?AndrewAPrice wrote: ↑Fri Jul 19, 2024 3:17 pmI'm looking for timer source that I can read relatively quickly from user-space in an event loop. For example, measure the delta time since the last frame update so I can update the UI animations.
If you really need a timer that's easy to poll and doesn't have RPC overhead, you could use the TSC. On some older CPUs, it's not very accurate as a time source, so you might also need a fallback.
Some (old?) x86-64 PCs don't support HPET.
You can set up the IOPB to access IO ports from ring 3, if you really need that.AndrewAPrice wrote: ↑Fri Jul 19, 2024 3:17 pmsince I believe I can read it from user-code vs. having to query an IO port (which means I'll have to RPC to a driver to do it).
Re: Delta time sources (x86-64)
An overview of time sources is available here: https://wiki.osdev.org/Timer_Interrupt_SourcesAndrewAPrice wrote: ↑Fri Jul 19, 2024 3:17 pm I'm looking for timer source that I can read relatively quickly from user-space in an event loop. For example, measure the delta time since the last frame update so I can update the UI animations.
You should probably use the TSC if possible. However, sometimes it is not possible. You will have to read the multi-processor configuration, but the TSC is initialized from the same value only across the CPU package. IIRC, if your system has more than one CPU package, you can't use the TSC since they will be out of sync. There is also a flag in CPUID somewhere telling you if the TSC will keep its frequency at low-power modes. Obviously, it isn't useful as a timepiece if it ticks at different rates over time.
HPET is next in line, but of course not always available. Reading it is done with one MMIO read. How you wish to expose that to userspace is your business, but I won't give all userspace processes access to all of address space, so a driver is still required to at least get at the address with the counter. If it exists, HPET can give a highly accurate and stable counter from which to derive the system clock.
The ACPI PM timer is basically unusable for having only a 24- or 32-bit register and no interrupt on terminal count so you cannot extend it.
PIT should be the fallback. It does not provide a counter, but you can set it up to interrupt you regularly, and the timer interrupt can increase a value in software. That value can be as large as you like. Of course, this is the worst possible solution for energy consumption. You get to choose between precision and battery life. But if life gives you lemons...
I think he was interrupted and now wants to know how much time passed between last and current iteration.Octocontrabass wrote: ↑Fri Jul 19, 2024 5:47 pm Why poll the timer when the timer could send interrupts to you?
Carpe diem!
- AndrewAPrice
- Member
- Posts: 2300
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Re: Delta time sources (x86-64)
The TSC seems like my best bet, specifically, rdtscp, which returns the IA32_TSC_AUX to identify the processor.nullplan wrote: ↑Fri Jul 19, 2024 9:56 pm An overview of time sources is available here: https://wiki.osdev.org/Timer_Interrupt_Sources
You should probably use the TSC if possible. However, sometimes it is not possible. You will have to read the multi-processor configuration, but the TSC is initialized from the same value only across the CPU package. IIRC, if your system has more than one CPU package, you can't use the TSC since they will be out of sync. There is also a flag in CPUID somewhere telling you if the TSC will keep its frequency at low-power modes. Obviously, it isn't useful as a timepiece if it ticks at different rates over time.
Then, I just need an API that can query some driver (or the kernel) for processor => {ticks per second, 0 epoch offset}, then I'd have everything I need to convert the TSC to seconds.
The next question is how I can accurately get the number of ticks per second.
My OS is Perception.
Re: Delta time sources (x86-64)
Linux does this by writing the required values into a data page that is shared with all processes (the VVAR page) and not writable for user programs. It also solves the problem of hardware abstraction by hiding all of this in the VDSO implementation of clock_gettime(), so users don't need to know anything about the TSC, the HPET, or anything, really.AndrewAPrice wrote: ↑ Then, I just need an API that can query some driver (or the kernel) for processor => {ticks per second, 0 epoch offset}, then I'd have everything I need to convert the TSC to seconds.
The common solution for this is to use a timer you do know the frequency of. Specifically, the PIT. Program the PIT to interrupt you in 100ms and calculate the TSC difference in that time.AndrewAPrice wrote: ↑Sat Jul 20, 2024 3:37 pm The next question is how I can accurately get the number of ticks per second.
Carpe diem!
-
- Member
- Posts: 5568
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Delta time sources (x86-64)
Wouldn't the interrupt itself provide that information?
Newer Intel CPUs report the TSC frequency via CPUID. Otherwise, you need to measure the TSC frequency using a timer with a known frequency (PIT, HPET, ACPI power management timer). SMM can add unexpected delays, so you need to measure more than once to make sure your measurement is accurate. The TSC frequency isn't constant on some CPUs, so you should check CPUID before you try to measure.AndrewAPrice wrote: ↑Sat Jul 20, 2024 3:37 pmThe next question is how I can accurately get the number of ticks per second.
Re: Delta time sources (x86-64)
How would it do that? Last time the program ran because of the mouse driver, this time it's because of a keyboard event, and next time it might be because of network activity. It doesn't have to be because of some timer.Octocontrabass wrote: ↑Sun Jul 21, 2024 7:49 pm Wouldn't the interrupt itself provide that information?
Carpe diem!
-
- Member
- Posts: 5568
- Joined: Mon Mar 25, 2013 7:01 pm