|
PatchworkOS
da8a090
A non-POSIX operating system.
|
Per-CPU timers. More...
Per-CPU timers.
The timer subsystem is responsible for managing per-CPU timers which are responsible for generating timer interrupts. These interrupts are whats called "one-shot" interrupts, meaning that the interrupt will only occur once and then a new interrupt must be programmed.
The way we handle timer interrupts is that each subsystem that relies on the timer calls the timer_set() function with their desired deadline and then, when the timer interrupt occurs, the timer interrupt is acknowledged and the usual interrupt handling process continues. For example, the scheduler and wait system will check if they need to do anything.
Both the scheduler and the wait system can now call timer_set() again if they need to schedule another timer interrupt or if the time they requested has not yet occurred.
This does technically result in some uneeded checks but its a very simply way of effectively eliminating timer related race conditions.
The actual timer interrupts are provided by "timer sources" (timer_source_t), which are registered by modules. Each source registers itself with a estimate of its precision, the timer subsystem then chooses the source with the highest precision as the active timer source.
Data Structures | |
| struct | timer_cpu_ctx_t |
| Per-CPU system time context. More... | |
| struct | timer_source_t |
| Timer source structure. More... | |
Macros | |
| #define | TIMER_MAX_SOURCES 4 |
| Maximum amount of timer sources. | |
Functions | |
| void | timer_cpu_ctx_init (timer_cpu_ctx_t *ctx) |
| Initialize per-CPU timer context. | |
| void | timer_ack_eoi (interrupt_frame_t *frame, cpu_t *self) |
| Acknowledge a timer interrupt and send EOI. | |
| uint64_t | timer_source_register (const timer_source_t *source) |
| Register a timer source. | |
| void | timer_source_unregister (const timer_source_t *source) |
| Unregister a timer source. | |
| uint64_t | timer_source_amount (void) |
| Get the amount of registered timer sources. | |
| void | timer_set (clock_t uptime, clock_t deadline) |
| Schedule a one-shot timer interrupt on the current CPU. | |
| void timer_cpu_ctx_init | ( | timer_cpu_ctx_t * | ctx | ) |
| void timer_ack_eoi | ( | interrupt_frame_t * | frame, |
| cpu_t * | self | ||
| ) |
| uint64_t timer_source_register | ( | const timer_source_t * | source | ) |
Register a timer source.
| source | The timer source to register. |
0. On failure, ERR and errno is set to:EINVAL: Invalid parameters.ENOSPC: No more timer sources can be registered.irq_handler_register(). Definition at line 49 of file timer.c.
| void timer_source_unregister | ( | const timer_source_t * | source | ) |
| uint64_t timer_source_amount | ( | void | ) |
Schedule a one-shot timer interrupt on the current CPU.
Sets the per-cpu timer to generate a interrupt after the specified timeout.
Multiple calls with different timeouts will result in the timer being set for the shortest requested timeout, this will be reset after a timer interrupt.
The reason we need to specify the current uptime, is not just as a slight optimization, but also to ensure the caller knows exactly what time they are scheduling the timer for, as the uptime could change between the caller reading the time and this function setting the timer, resulting in very subtle bugs or race conditions.
CONFIG_MIN_TIMER_TIMEOUT to avoid spamming the CPU with timer interrupts.| uptime | The time since boot, we need to specify this as an argument to avoid inconsistency in the timeout/deadline calculations. |
| deadline | The desired deadline. |
Definition at line 134 of file timer.c.