PatchworkOS  da8a090
A non-POSIX operating system.
Loading...
Searching...
No Matches
timer.h
Go to the documentation of this file.
1#pragma once
2
4#include <kernel/cpu/irq.h>
5#include <kernel/sync/lock.h>
6
7#include <sys/proc.h>
8#include <time.h>
9
10typedef struct cpu cpu_t;
11
12/**
13 * @brief Per-CPU timers.
14 * @defgroup kernel_timer Timer subsystem
15 * @ingroup kernel_sched
16 *
17 * The timer subsystem is responsible for managing per-CPU timers which are responsible for generating timer interrupts.
18These interrupts are whats called "one-shot" interrupts, meaning that the interrupt will only occur once and then a new
19interrupt must be programmed.
20 *
21 * ## Timer Interrupts
22 *
23 * The way we handle timer interrupts is that each subsystem that relies on the timer calls the `timer_set()` function
24with their desired deadline and then, when the timer interrupt occurs, the timer interrupt is acknowledged and the usual
25interrupt handling process continues. For example, the scheduler and wait system will check if they need to do anything.
26 *
27 * Both the scheduler and the wait system can now call `timer_set()` again if they need to schedule another timer
28interrupt or if the time they requested has not yet occurred.
29 *
30 * This does technically result in some uneeded checks but its a very simply way of effectively eliminating timer
31related race conditions.
32 *
33 * ## Timer Sources
34 *
35 * The actual timer interrupts are provided by "timer sources" (`timer_source_t`), which are registered by modules. Each
36source registers itself with a estimate of its precision, the timer subsystem then chooses the source with the highest
37precision as the active timer source.
38 *
39 * @{
40 */
41
42/**
43 * @brief Per-CPU system time context.
44 */
45typedef struct
46{
47 /**
48 * The next time the owner cpus apic timer will fire, specified in nanoseconds since boot, used in
49 * `timer_set()`.
50 *
51 * Will be accessed in interrupt and non-interrupt context, so must be declared `volatile` to avoid compiler
52 * optimizations that could lead to stale reads.
53 */
54 clock_t volatile deadline;
56
57/**
58 * @brief Maximum amount of timer sources.
59 */
60#define TIMER_MAX_SOURCES 4
61
62/**
63 * @brief Timer source structure.
64 * @struct timer_source_t
65 */
66typedef struct
67{
68 const char* name;
70 /**
71 * @brief Should set the one-shot timer to fire after the specified timeout.
72 *
73 * Should panic on failure, as failing to set a timer will almost certainly result in the system hanging.
74 *
75 * @param virt The virtual IRQ to use for the timer interrupt, usually `VECTOR_TIMER`.
76 * @param uptime The current uptime in nanoseconds.
77 * @param timeout The desired timeout in nanoseconds, if `CLOCKS_NEVER`, the timer should be disabled.
78 */
79 void (*set)(irq_virt_t virt, clock_t uptime, clock_t timeout);
80 void (*ack)(cpu_t* cpu);
81 void (*eoi)(cpu_t* cpu);
83
84/**
85 * @brief Initialize per-CPU timer context.
86 *
87 * Must be called on the CPU who owns the context.
88 *
89 * @param ctx The timer context to initialize.
90 */
92
93/**
94 * @brief Acknowledge a timer interrupt and send EOI.
95 *
96 * @param frame The interrupt frame of the timer interrupt.
97 * @param self The CPU on which the timer interrupt was received.
98 */
99void timer_ack_eoi(interrupt_frame_t* frame, cpu_t* self);
100
101/**
102 * @brief Register a timer source.
103 *
104 * @param source The timer source to register.
105 * @return On success, `0`. On failure, `ERR` and `errno` is set to:
106 * - `EINVAL`: Invalid parameters.
107 * - `ENOSPC`: No more timer sources can be registered.
108 * - Other errors as returned by `irq_handler_register()`.
109 */
111
112/**
113 * @brief Unregister a timer source.
114 *
115 * @param source The timer source to unregister, or `NULL` for no-op.
116 */
118
119/**
120 * @brief Get the amount of registered timer sources.
121 *
122 * @return The amount of registered timer sources.
123 */
125
126/**
127 * @brief Schedule a one-shot timer interrupt on the current CPU.
128 *
129 * Sets the per-cpu timer to generate a interrupt after the specified timeout.
130 *
131 * Multiple calls with different timeouts will result in the timer being set for the shortest requested timeout, this
132 * will be reset after a timer interrupt.
133 *
134 * The reason we need to specify the current uptime, is not just as a slight optimization, but also to ensure the caller
135 * knows exactly what time they are scheduling the timer for, as the uptime could change between the caller reading the
136 * time and this function setting the timer, resulting in very subtle bugs or race conditions.
137 *
138 * @note Will never set the timeout to be less than `CONFIG_MIN_TIMER_TIMEOUT` to avoid spamming the CPU with timer
139 * interrupts.
140 *
141 * @param uptime The time since boot, we need to specify this as an argument to avoid inconsistency in the
142 * timeout/deadline calculations.
143 * @param deadline The desired deadline.
144 */
145void timer_set(clock_t uptime, clock_t deadline);
146
147/** @} */
uint8_t irq_virt_t
Virtual IRQ numbers.
Definition irq.h:57
uint64_t timer_source_amount(void)
Get the amount of registered timer sources.
Definition timer.c:126
void timer_cpu_ctx_init(timer_cpu_ctx_t *ctx)
Initialize per-CPU timer context.
Definition timer.c:23
void timer_set(clock_t uptime, clock_t deadline)
Schedule a one-shot timer interrupt on the current CPU.
Definition timer.c:134
void timer_source_unregister(const timer_source_t *source)
Unregister a timer source.
Definition timer.c:88
void timer_ack_eoi(interrupt_frame_t *frame, cpu_t *self)
Acknowledge a timer interrupt and send EOI.
Definition timer.c:28
uint64_t timer_source_register(const timer_source_t *source)
Register a timer source.
Definition timer.c:49
clock_t uptime(void)
System call for retreving the time since boot.
Definition uptime.c:6
__UINT64_TYPE__ clock_t
A nanosecond time.
Definition clock_t.h:13
static sys_time_source_t source
Structure to describe the HPET to the sys time subsystem.
Definition hpet.c:192
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
CPU structure.
Definition cpu.h:122
Trap Frame Structure.
Definition interrupt.h:143
Per-CPU system time context.
Definition timer.h:46
clock_t volatile deadline
Definition timer.h:54
Timer source structure.
Definition timer.h:67
const char * name
Definition timer.h:68
clock_t precision
Definition timer.h:69