Implement Jiffies

This commit is contained in:
Mathieu Maret 2020-04-27 23:08:36 +02:00
parent 3b97d0307d
commit 6c3a03a4bc
9 changed files with 82 additions and 7 deletions

View File

@ -15,7 +15,7 @@ CPPFLAGS += $(foreach dir, $(SUBDIRS), -I$(dir))
asmsrc=$(wildcard *.asm)
asmobj=$(asmsrc:%.asm=%.o)
csrc=$(shell find $(SUBDIRS) -type f -name "*.c")# $(wildcard *.c)
cobj=$(csrc:%.c=%.o) core/cpu_context_switch.o core/irq_pit.o
cobj=$(csrc:%.c=%.o) core/cpu_context_switch.o drivers/irq_pit.o
deps = $(csrc:%.c=%.d)
kernel:$(asmobj) $(cobj) linker.ld

View File

@ -4,6 +4,7 @@
#include "irq.h"
#include "klibc.h"
#include "list.h"
#include "time.h"
#include "vga.h"
static struct kthread *currentThread;
@ -80,7 +81,7 @@ struct kthread *kthreadSelectNext()
return nextThread;
}
struct cpu_state *switchKthread(struct cpu_state *prevCpu)
struct cpu_state *kthreadSwitch(struct cpu_state *prevCpu)
{
uint32_t flags;
disable_IRQs(flags);

View File

@ -22,6 +22,6 @@ struct kthread *kthreadCreate(const char *name, cpu_kstate_function_arg1_t func,
void kthreadDelete(struct kthread *thread);
struct kthread *kthreadSelectNext();
struct cpu_state *switchKthread(struct cpu_state *prevCpu);
struct cpu_state *kthreadSwitch(struct cpu_state *prevCpu);
int kthreadYield();

View File

@ -17,6 +17,7 @@
#ifdef RUN_TEST
#include "test.h"
#endif
#include "time.h"
#include "types.h"
#include "vga.h"
@ -29,9 +30,8 @@ void cpuid(int code, uint32_t *a, uint32_t *d)
void idleThread(void *arg)
{
(void)arg;
int count = 0;
while (1)
printIntDetails(count++, GREEN, BLACK, 0, VGA_HEIGHT - 1);
printIntDetails((jiffies/HZ), GREEN, BLACK, 0, VGA_HEIGHT - 1);
}
// Multiboot information available here :
@ -47,7 +47,7 @@ void kmain(unsigned long magic, unsigned long addr)
gdtSetup();
idtSetup();
irqSetup();
pitSetup(100);
pitSetup(HZ);
if (magic == MULTIBOOT_BOOTLOADER_MAGIC) { // Get loaded by Grub with mutliboot version 1
multiboot_info_t *mbi = (multiboot_info_t *)addr;

13
core/time.c Normal file
View File

@ -0,0 +1,13 @@
#include "time.h"
unsigned long volatile jiffies = INITIAL_JIFFIES;
unsigned int jiffies_to_msecs(const unsigned long j)
{
return (1000L / HZ) * j;
}
unsigned int jiffies_to_usecs(const unsigned long j)
{
return (1000000L / HZ) * j;
}

50
core/time.h Normal file
View File

@ -0,0 +1,50 @@
#pragma once
#define HZ 100
/*
* Have the 32 bit jiffies value wrap 5 minutes after boot
* so jiffies wrap bugs show up earlier.
*/
//#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
#define INITIAL_JIFFIES 0
extern unsigned long volatile jiffies;
#define time_after(unknown, known) ((long)(known) - (long)(unknown) < 0)
#define time_before(unknown, known) ((long)(unknown) - (long)(known) < 0)
#define time_after_eq(unknown, known) ((long)(unknown) - (long)(known) >= 0)
#define time_before_eq(unknown, known) ((long)(known) - (long)(unknown) >= 0)
/*
* Calculate whether a is in the range of [b, c].
*/
#define time_in_range(a,b,c) \
(time_after_eq(a,b) && \
time_before_eq(a,c))
/*
* Calculate whether a is in the range of [b, c).
*/
#define time_in_range_open(a,b,c) \
(time_after_eq(a,b) && \
time_before(a,c))
/*
* These four macros compare jiffies and 'a' for convenience.
*/
/* time_is_before_jiffies(a) return true if a is before jiffies */
#define time_is_before_jiffies(a) time_after(jiffies, a)
/* time_is_after_jiffies(a) return true if a is after jiffies */
#define time_is_after_jiffies(a) time_before(jiffies, a)
/* time_is_before_eq_jiffies(a) return true if a is before or equal to jiffies*/
#define time_is_before_eq_jiffies(a) time_after_eq(jiffies, a)
/* time_is_after_eq_jiffies(a) return true if a is after or equal to jiffies*/
#define time_is_after_eq_jiffies(a) time_before_eq(jiffies, a)
unsigned int jiffies_to_msecs(const unsigned long j);
unsigned int jiffies_to_usecs(const unsigned long j);

View File

@ -21,7 +21,7 @@ pit_handler: // already got eflags, cs and eip on stack thanks to CPU
outb %al, $0x20
pushl %esp
call switchKthread
call pitIrqHandler
movl %eax,%esp
/* Restore the CPU context */

View File

@ -1,6 +1,9 @@
#include "pit.h"
#include "io.h"
#include "irq.h"
#include "kthread.h"
#include "time.h"
#include "klibc.h"
int pitSetup(unsigned int freq)
{
@ -13,3 +16,9 @@ int pitSetup(unsigned int freq)
return 0;
}
struct cpu_state *pitIrqHandler(struct cpu_state *prevCpu)
{
__atomic_add_fetch(&jiffies, 1, __ATOMIC_RELAXED);
return kthreadSwitch(prevCpu);
}

View File

@ -1,4 +1,5 @@
#pragma once
#include "cpu_context.h"
// C.f https://wiki.osdev.org/PIT
@ -13,3 +14,4 @@
// 3 -> low then high 3-1: mode. See https://wiki.osdev.org/PIT
int pitSetup(unsigned int freq);
struct cpu_state *pitIrqHandler(struct cpu_state *prevCpu);