mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 20:58:22 +00:00
timekeeper: redo timekeeping
This commit is contained in:
@@ -2,9 +2,40 @@
|
||||
#define _TIMEKEEPER_H
|
||||
|
||||
#include <time.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void timekeeper_init(time_t (*tick)(), time_t ticksperus);
|
||||
timespec_t timekeeper_timefromboot();
|
||||
timespec_t timekeeper_time();
|
||||
#define TIMEKEEPER_SOURCE_FLAGS_EARLY 1 // can be used as an early timer
|
||||
|
||||
typedef struct {
|
||||
time_t ticks_per_us;
|
||||
void *private;
|
||||
} timekeeper_source_info_t;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int priority;
|
||||
bool (*probe)(void); // returns true if the timer can currently be used
|
||||
timekeeper_source_info_t *(*init)(void); // initializes the timer, returning the info structure
|
||||
time_t (*ticks)(timekeeper_source_info_t *private); // returns a monotonic number of ticks
|
||||
int flags;
|
||||
} timekeeper_source_t;
|
||||
|
||||
// initializes the highest priority source that can be used as an early timer and switches the cpu to use it
|
||||
void timekeeper_early_init(time_t us_offset);
|
||||
|
||||
// initializes the highest priority source and switches the cpu to use it. uses the early timer for calibration if nescessary
|
||||
void timekeeper_init(void);
|
||||
|
||||
// spins waiting for us to pass
|
||||
void timekeeper_wait_us(time_t us);
|
||||
|
||||
timespec_t timekeeper_timefromboot(void);
|
||||
timespec_t timekeeper_time(void);
|
||||
|
||||
#define TIMEKEEPER_SOURCE(x, ...) \
|
||||
static timekeeper_source_t x = { \
|
||||
__VA_ARGS__ \
|
||||
}; \
|
||||
__attribute__((section(".timekeeper_sources"), used)) static timekeeper_source_t *timekeeper_source_##x = &x;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,4 +20,6 @@ typedef semaphore_t mutex_t;
|
||||
#define MUTEX_TRY(m) \
|
||||
semaphore_test(m)
|
||||
|
||||
#define MUTEX_DEFINE(x) SEMAPHORE_DEFINE(x, 1)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,6 +23,11 @@ typedef struct semaphore_t{
|
||||
(x)->head = NULL; \
|
||||
}
|
||||
|
||||
#define SEMAPHORE_DEFINE(x, v) semaphore_t x = { \
|
||||
.i = v, \
|
||||
.lock = SPINLOCK_INIT_VALUE \
|
||||
}
|
||||
|
||||
|
||||
int semaphore_wait(semaphore_t *sem, bool interruptible);
|
||||
int semaphore_timedwait(semaphore_t *sem, time_t timeoutusec, bool interruptible);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
typedef int spinlock_t;
|
||||
|
||||
#define SPINLOCK_INIT(x) x = 0;
|
||||
#define SPINLOCK_INIT_VALUE 0
|
||||
|
||||
static inline void spinlock_acquire(spinlock_t *lock){
|
||||
while(!__sync_bool_compare_and_swap(lock, 0, 1)) asm("pause");
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define _TIME_H
|
||||
|
||||
#include <util.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef long time_t;
|
||||
typedef long suseconds_t;
|
||||
@@ -39,4 +40,21 @@ static inline time_t timespec_ns(timespec_t a) {
|
||||
return a.ns + a.s * 1000000000;
|
||||
}
|
||||
|
||||
static inline time_t timespec_us(timespec_t a) {
|
||||
return a.ns / 1000 + a.s * 1000000;
|
||||
}
|
||||
|
||||
static inline timespec_t timespec_from_us(time_t us) {
|
||||
timespec_t ts = {
|
||||
.s = us / 1000000,
|
||||
.ns = (us % 1000000) * 100
|
||||
};
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
static inline bool timespec_bigger(timespec_t t1, timespec_t t2) {
|
||||
return t1.s > t2.s || (t1.s == t2.s && t1.ns > t2.ns);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <kernel/scheduler.h>
|
||||
#include <kernel/dpc.h>
|
||||
#include <arch/apic.h>
|
||||
#include <kernel/timekeeper.h>
|
||||
|
||||
#define ARCH_EOI arch_apic_eoi
|
||||
|
||||
@@ -23,7 +24,12 @@ typedef struct cpu_t {
|
||||
|
||||
vmmcontext_t *vmmctx; // expected to be here by other code
|
||||
|
||||
long id;
|
||||
long id; // expected to be here by other code
|
||||
|
||||
timekeeper_source_t *timekeeper_source;
|
||||
timekeeper_source_info_t *timekeeper_source_info;
|
||||
time_t timekeeper_source_base_ticks;
|
||||
time_t timekeeper_source_tick_offset;
|
||||
|
||||
isr_t isr[MAX_ISR_COUNT];
|
||||
bool intstatus;
|
||||
|
||||
Reference in New Issue
Block a user