PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
timer.c
Go to the documentation of this file.
1#include <kernel/cpu/cpu.h>
3#include <kernel/cpu/irq.h>
5#include <kernel/log/log.h>
6#include <kernel/log/panic.h>
10#include <kernel/sched/timer.h>
11
12#include <kernel/sync/rwlock.h>
13#include <stdbool.h>
14#include <stdint.h>
15#include <sys/math.h>
16#include <time.h>
17
22
23typedef struct
24{
25 clock_t volatile deadline;
27
29{
30 pcpu_timer->deadline = CLOCKS_NEVER;
31}
32
34{
35 UNUSED(frame);
36
38
39 pcpu_timer->deadline = CLOCKS_NEVER;
40
41 if (bestSource != NULL)
42 {
43 if (bestSource->ack != NULL)
44 {
45 bestSource->ack();
46 }
47 if (bestSource->eoi != NULL)
48 {
49 bestSource->eoi();
50 }
51 }
52}
53
55{
56 if (source == NULL || source->set == NULL || source->precision == 0 || source->name == NULL)
57 {
58 errno = EINVAL;
59 return ERR;
60 }
61
64 {
66 errno = ENOSPC;
67 return ERR;
68 }
69
70 for (uint32_t i = 0; i < sourceCount; i++)
71 {
72 if (sources[i] == source)
73 {
75 return 0;
76 }
77 }
78
80
81 bool bestSourceUpdated = false;
83 {
85 bestSourceUpdated = true;
86 }
88
89 LOG_INFO("registered timer source '%s'%s\n", source->name, bestSourceUpdated ? " (best source)" : "");
90 return 0;
91}
92
94{
95 if (source == NULL)
96 {
97 return;
98 }
99
101 for (uint32_t i = 0; i < sourceCount; i++)
102 {
103 if (sources[i] != source)
104 {
105 continue;
106 }
107
108 memmove(&sources[i], &sources[i + 1], (sourceCount - i - 1) * sizeof(timer_source_t*));
109 sourceCount--;
110
111 if (bestSource == source)
112 {
114 for (uint32_t j = 0; j < sourceCount; j++)
115 {
116 if (bestSource == NULL || sources[j]->precision < bestSource->precision)
117 {
118 bestSource = sources[j];
119 }
120 }
121 }
122
124 LOG_INFO("unregistered timer source '%s'\n", source->name);
125 return;
126 }
127
129}
130
138
139void timer_set(clock_t now, clock_t deadline)
140{
141 if (deadline == CLOCKS_NEVER)
142 {
143 return;
144 }
145
147
148 deadline = MAX(deadline, now + CONFIG_MIN_TIMER_TIMEOUT);
149
150 if (pcpu_timer->deadline <= deadline)
151 {
152 return;
153 }
154 pcpu_timer->deadline = deadline;
155
156 if (bestSource != NULL)
157 {
158 bestSource->set(VECTOR_TIMER, now, deadline - now);
159 }
160}
#define CLOCKS_NEVER
Definition clock_t.h:18
#define CONFIG_MIN_TIMER_TIMEOUT
Minimum timer timeout configuration.
Definition config.h:88
@ VECTOR_TIMER
See Timer subsystem for more information.
Definition interrupt.h:180
#define PERCPU_DEFINE_CTOR(type, name)
Macro to define a percpu variable with a constructor.
Definition percpu.h:130
static clock_source_t source
Structure to describe the HPET to the sys time subsystem.
Definition hpet.c:193
#define LOG_INFO(format,...)
Definition log.h:91
static void rwlock_write_release(rwlock_t *lock)
Releases a rwlock from writing.
Definition rwlock.h:196
static void rwlock_read_release(rwlock_t *lock)
Releases a rwlock from reading.
Definition rwlock.h:146
#define RWLOCK_READ_SCOPE(lock)
Acquires a rwlock for reading for the reminder of the current scope.
Definition rwlock.h:34
static void rwlock_write_acquire(rwlock_t *lock)
Acquires a rwlock for writing, blocking until it is available.
Definition rwlock.h:158
#define RWLOCK_CREATE()
Create a rwlock initializer.
Definition rwlock.h:52
static void rwlock_read_acquire(rwlock_t *lock)
Acquires a rwlock for reading, blocking until it is available.
Definition rwlock.h:93
uint64_t timer_source_amount(void)
Get the amount of registered timer sources.
Definition timer.c:131
void timer_source_unregister(const timer_source_t *source)
Unregister a timer source.
Definition timer.c:93
#define TIMER_MAX_SOURCES
Maximum amount of timer sources.
Definition timer.h:45
void timer_ack_eoi(interrupt_frame_t *frame)
Acknowledge a timer interrupt and send EOI.
Definition timer.c:33
uint64_t timer_source_register(const timer_source_t *source)
Register a timer source.
Definition timer.c:54
void timer_set(clock_t now, clock_t deadline)
Schedule a one-shot timer interrupt on the current CPU.
Definition timer.c:139
#define ENOSPC
No space left on device.
Definition errno.h:172
#define EINVAL
Invalid argument.
Definition errno.h:142
#define errno
Error number variable.
Definition errno.h:27
#define UNUSED(x)
Mark a variable as unused.
Definition defs.h:96
#define MAX(x, y)
Definition math.h:17
#define NULL
Pointer error value.
Definition NULL.h:25
#define ERR
Integer error value.
Definition ERR.h:17
__UINT64_TYPE__ clock_t
A nanosecond time.
Definition clock_t.h:13
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
_PUBLIC void * memmove(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
const char * name
Definition clock.h:36
clock_t precision
Definition clock.h:37
Trap Frame Structure.
Definition interrupt.h:195
Read-Write Ticket Lock structure.
Definition rwlock.h:66
clock_t volatile deadline
Definition timer.c:25
Timer source structure.
Definition timer.h:52
void(* eoi)(void)
Definition timer.h:66
clock_t precision
Definition timer.h:54
void(* set)(irq_virt_t virt, clock_t uptime, clock_t timeout)
Should set the one-shot timer to fire after the specified timeout.
Definition timer.h:64
void(* ack)(void)
Definition timer.h:65
static rwlock_t sourcesLock
Definition timer.c:21
static const timer_source_t * sources[TIMER_MAX_SOURCES]
Definition timer.c:18
static const timer_source_t * bestSource
Definition timer.c:20
static uint32_t sourceCount
Definition timer.c:19