PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
clock.c
Go to the documentation of this file.
2
3#include <kernel/cpu/cpu.h>
6#include <kernel/log/log.h>
7#include <kernel/log/panic.h>
10#include <kernel/sched/timer.h>
11
12#include <kernel/sync/rwlock.h>
13#include <stdatomic.h>
14#include <stdbool.h>
15#include <stdint.h>
16#include <sys/math.h>
17
23
24#ifdef DEBUG
25static _Atomic(clock_t) lastNsTime = ATOMIC_VAR_INIT(0);
26#endif
27
29{
32
33 for (uint32_t i = 0; i < sourceCount; i++)
34 {
35 const clock_source_t* source = sources[i];
37 {
39 }
41 {
43 }
44 }
45}
46
48{
49 if (source == NULL || (source->read_ns == NULL && source->read_epoch == NULL) || source->precision == 0)
50 {
51 errno = EINVAL;
52 return ERR;
53 }
54
57 {
59 errno = ENOSPC;
60 return ERR;
61 }
62
65
67
68 LOG_INFO("registered system timer source '%s' with precision %lu ns\n", source->name, source->precision);
69 return 0;
70}
71
73{
74 if (source == NULL)
75 {
76 return;
77 }
78
80 for (uint32_t i = 0; i < sourceCount; i++)
81 {
82 if (sources[i] != source)
83 {
84 continue;
85 }
86
87 memmove(&sources[i], &sources[i + 1], (sourceCount - i - 1) * sizeof(clock_source_t*));
89
92 return;
93 }
94
96 panic(NULL, "Failed to unregister system timer source '%s', not found", source->name);
97}
98
100{
102 if (bestNsSource == NULL)
103 {
104 return 0;
105 }
106
107 return bestNsSource->read_ns();
108}
109
111{
113 if (bestEpochSource == NULL)
114 {
115 return 0;
116 }
117
118 return bestEpochSource->read_epoch();
119}
120
121void clock_wait(clock_t nanoseconds)
122{
123 if (nanoseconds == 0)
124 {
125 return;
126 }
127
129 if (start == 0)
130 {
131 panic(NULL, "clock_wait called before timer system initialized");
132 }
133
134 while (clock_uptime() - start < nanoseconds)
135 {
136 ASM("pause");
137 }
138}
139
144
146{
147 time_t epoch = clock_epoch();
148 if (timePtr != NULL)
149 {
150 if (thread_copy_to_user(thread_current(), timePtr, &epoch, sizeof(epoch)) == ERR)
151 {
152 return ERR;
153 }
154 }
155
156 return epoch;
157}
static void start()
Definition main.c:542
#define SYSCALL_DEFINE(num, returnType,...)
Macro to define a syscall.
Definition syscall.h:172
@ SYS_EPOCH
Definition syscall.h:73
@ SYS_UPTIME
Definition syscall.h:72
static clock_source_t source
Structure to describe the HPET to the sys time subsystem.
Definition hpet.c:193
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
Definition panic.c:292
#define LOG_INFO(format,...)
Definition log.h:91
#define CLOCK_MAX_SOURCES
Maximum amount of system timer sources.
Definition clock.h:28
time_t clock_epoch(void)
Retrieve the seconds since the unix epoch.
Definition clock.c:110
void clock_wait(clock_t nanoseconds)
Wait for a specified number of nanoseconds.
Definition clock.c:121
clock_t clock_uptime(void)
Retrieve the time in nanoseconds since boot.
Definition clock.c:99
uint64_t clock_source_register(const clock_source_t *source)
Register a system timer source.
Definition clock.c:47
void clock_source_unregister(const clock_source_t *source)
Unregister a system timer source.
Definition clock.c:72
static thread_t * thread_current(void)
Retrieves the currently running thread.
Definition thread.h:126
uint64_t thread_copy_to_user(thread_t *thread, void *userDest, const void *src, uint64_t length)
Safely copy data to user space.
Definition thread.c:220
static void rwlock_write_release(rwlock_t *lock)
Releases a rwlock from writing.
Definition rwlock.h:196
#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
#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 ASM(...)
Inline assembly macro.
Definition defs.h:160
#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
static rwlock_t sourcesLock
Definition clock.c:22
static const clock_source_t * bestEpochSource
Definition clock.c:21
static const clock_source_t * sources[CLOCK_MAX_SOURCES]
Definition clock.c:18
static const clock_source_t * bestNsSource
Definition clock.c:20
static uint32_t sourceCount
Definition clock.c:19
static void clock_update_best_sources(void)
Definition clock.c:28
#define _Atomic(T)
Definition stdatomic.h:59
#define ATOMIC_VAR_INIT(value)
Definition stdatomic.h:74
__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)
Clock source structure.
Definition clock.h:35
const char * name
Definition clock.h:36
clock_t precision
Definition clock.h:37
clock_t(* read_ns)(void)
Definition clock.h:38
time_t(* read_epoch)(void)
Definition clock.h:39
Read-Write Ticket Lock structure.
Definition rwlock.h:66
long long unsigned time_t
Definition time_t.h:4