PatchworkOS  28a9544
A non-POSIX operating system.
Loading...
Searching...
No Matches
sys_time.c
Go to the documentation of this file.
2
3#include <kernel/cpu/cpu.h>
8#include <kernel/log/log.h>
9#include <kernel/log/panic.h>
11#include <kernel/sched/thread.h>
12#include <kernel/sched/timer.h>
13
14#include <kernel/sync/rwlock.h>
15#include <stdbool.h>
16#include <stdint.h>
17#include <sys/math.h>
18
19static time_t bootEpoch = 0;
20static bool bootEpochInitialized = false;
21
26
27static void timer_boot_epoch_init(void)
28{
29 struct tm time;
30 rtc_read(&time);
33}
34
36{
37 if (source == NULL || source->read == NULL || source->precision == 0)
38 {
39 errno = EINVAL;
40 return ERR;
41 }
42
45 {
47 errno = ENOSPC;
48 return ERR;
49 }
50
52
53 bool bestSourceUpdated = false;
55 {
57 bestSourceUpdated = true;
58 }
60
61 LOG_INFO("registered system timer source '%s' with precision %lu ns%s\n", source->name, source->precision,
62 bestSourceUpdated ? " (selected as best source)" : "");
63
64 return 0;
65}
66
68{
69 if (source == NULL)
70 {
71 return;
72 }
73
75 for (uint32_t i = 0; i < sourceCount; i++)
76 {
77 if (sources[i] != source)
78 {
79 continue;
80 }
81
82 memmove(&sources[i], &sources[i + 1], (sourceCount - i - 1) * sizeof(sys_time_source_t*));
84
85 if (bestSource == source)
86 {
88 for (uint32_t j = 0; j < sourceCount; j++)
89 {
90 if (bestSource == NULL || sources[j]->precision < bestSource->precision)
91 {
93 }
94 }
95 }
96
98 LOG_INFO("unregistered system timer source '%s'%s\n", source->name);
99 return;
100 }
101
103 panic(NULL, "Failed to unregister system timer source '%s', not found", source->name);
104}
105
107{
109 if (bestSource == NULL)
110 {
111 return 0;
112 }
113
114 return bestSource->read();
115}
116
118{
120 {
122 }
123
125}
126
127void sys_time_wait(clock_t nanoseconds)
128{
129 if (nanoseconds == 0)
130 {
131 return;
132 }
133
135 if (start == 0)
136 {
137 panic(NULL, "sys_time_wait called before timer system initialized");
138 }
139
140 while (sys_time_uptime() - start < nanoseconds)
141 {
142 asm volatile("pause");
143 }
144}
145
150
152{
153 time_t epoch = sys_time_unix_epoch();
154 if (timePtr != NULL)
155 {
156 if (thread_copy_to_user(sched_thread(), timePtr, &epoch, sizeof(epoch)) == ERR)
157 {
158 return ERR;
159 }
160 }
161
162 return epoch;
163}
#define CLOCKS_PER_SEC
Definition clock_t.h:15
#define SYS_UPTIME
Definition syscalls.h:29
#define SYS_UNIX_EPOCH
Definition syscalls.h:30
#define SYSCALL_DEFINE(num, returnType,...)
Macro to define a syscall.
Definition syscalls.h:101
void rtc_read(struct tm *time)
Reads the current time from the RTC.
Definition rtc.c:15
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
Definition panic.c:265
#define LOG_INFO(format,...)
Definition log.h:89
uint64_t thread_copy_to_user(thread_t *thread, void *dest, const void *userSrc, uint64_t length)
Safely copy data to user space.
Definition thread.c:262
thread_t * sched_thread(void)
Retrieves the currently running thread.
Definition sched.c:157
void rwlock_write_acquire(rwlock_t *lock)
Acquires a rwlock for writing, blocking until it is available.
Definition rwlock.c:62
#define RWLOCK_CREATE
Create a rwlock initializer.
Definition rwlock.h:47
#define RWLOCK_READ_SCOPE(lock)
Acquires a rwlock for reading for the reminder of the current scope.
Definition rwlock.h:29
void rwlock_write_release(rwlock_t *lock)
Releases a rwlock from writing.
Definition rwlock.c:109
uint64_t sys_time_register_source(const sys_time_source_t *source)
Register a system timer source.
Definition sys_time.c:35
time_t sys_time_unix_epoch(void)
The unix epoch.
Definition sys_time.c:117
clock_t sys_time_uptime(void)
Time since boot.
Definition sys_time.c:106
#define SYS_TIME_MAX_SOURCES
Maximum amount of system timer sources.
Definition sys_time.h:28
void sys_time_unregister_source(const sys_time_source_t *source)
Unregister a system timer source.
Definition sys_time.c:67
void sys_time_wait(clock_t nanoseconds)
Wait for a specified number of nanoseconds.
Definition sys_time.c:127
#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 NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
__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:185
static void start()
Definition main.c:542
__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)
Read-Write Ticket Lock structure.
Definition rwlock.h:61
Timer system source.
Definition sys_time.h:35
clock_t(* read)(void)
Definition sys_time.h:37
clock_t precision
Definition sys_time.h:38
const char * name
Definition sys_time.h:36
Definition time.h:21
static bool bootEpochInitialized
Definition sys_time.c:20
static rwlock_t sourcesLock
Definition sys_time.c:25
static void timer_boot_epoch_init(void)
Definition sys_time.c:27
static sys_time_source_t * sources[SYS_TIME_MAX_SOURCES]
Definition sys_time.c:22
static uint32_t sourceCount
Definition sys_time.c:23
static sys_time_source_t * bestSource
Definition sys_time.c:24
static time_t bootEpoch
Definition sys_time.c:19
_PUBLIC time_t time(time_t *timer)
Definition time.c:5
_PUBLIC time_t mktime(struct tm *timeptr)
Definition mktime.c:5
long long unsigned time_t
Definition time_t.h:4