Skip to content

Commit

Permalink
Merge pull request #1961 from ghaerr/prectimer2
Browse files Browse the repository at this point in the history
[kernel] Finalize precision timing routines
  • Loading branch information
ghaerr authored Aug 10, 2024
2 parents 6ac56e1 + 29bd275 commit a97f710
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 24 deletions.
30 changes: 22 additions & 8 deletions elks/arch/i86/lib/prectimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ static unsigned long lastjiffies;
* unsigned long jiffies jiffies 497 days(< 2^32 jiffies)
*/

#if 0 /* don't use - too unreliable with no overflow check */
/* read PIT diff count, returns < 11932 pticks (10ms), no overflow checking */
unsigned int get_time_10ms(void)
{
Expand All @@ -58,20 +59,32 @@ unsigned int get_time_10ms(void)
lastcount = count;
return pdiff;
}
#endif

/* count up to 5 jiffies in pticks, returns < 59660 pticks (50ms), w/overflow check */
unsigned int get_time_50ms(void)
{
int jdiff;
unsigned int pticks;
int pticks, jdiff;
unsigned int lo, hi, count;
flag_t flags;
static unsigned int lastcount;

clr_irq();
save_flags(flags);
clr_irq(); /* synchronize countdown and jiffies */
outb(0, TIMER_CMDS_PORT); /* latch timer value */
/* ia16-elf-gcc won't generate 32-bit subtract so use 16-bit and check wrap */
jdiff = (unsigned)jiffies - (unsigned)lastjiffies;
lastjiffies = jiffies; /* 32 bit save required after ~10.9 mins */
outb(0, TIMER_CMDS_PORT); /* latch timer value */
set_irq();
restore_flags(flags);

lo = inb(TIMER_DATA_PORT);
hi = inb(TIMER_DATA_PORT) << 8;
count = lo | hi;
pticks = lastcount - count;
if (pticks < 0) /* wrapped */
pticks += MAX_PTICK; /* = MAX_PTICK - count + lastcount */
lastcount = count;

pticks = get_time_10ms();
if (jdiff < 0) /* lower half wrapped */
jdiff = -jdiff; /* = 0x10000000 - lastjiffies + jiffies */
if (jdiff >= 2) {
Expand All @@ -88,8 +101,7 @@ unsigned long get_time(void)
unsigned int pticks;
static unsigned long lasttime;

clr_irq(); /* for saving lasttime below */
lasttime = lastjiffies;
lasttime = lastjiffies; /* race condition here before clr_irq in get_time_50ms */
pticks = get_time_50ms();
if (pticks != 0)
return pticks; /* < 50ms */
Expand All @@ -99,13 +111,15 @@ unsigned long get_time(void)

#if TIMER_TEST
/* sample timer routines */
#if 0
void timer_10ms(void)
{
unsigned int pticks;

pticks = get_time_10ms();
printk("%u %u = %k\n", pticks, (unsigned)jiffies, pticks);
}
#endif

void timer_50ms(void)
{
Expand Down
38 changes: 23 additions & 15 deletions elks/init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,21 @@ static void INITPROC early_kernel_init(void);
#if TIMER_TEST
void testloop(unsigned timer)
{
unsigned pticks, x = timer;

get_time_10ms();
while (x--) outb(x, 0x80);
pticks = get_time_10ms();
unsigned int pticks, x = timer;
int i;
static unsigned int a[10];

#if 1
get_time_50ms();
for (i=0; i<10; i++)
a[i] = get_time_50ms();
for (i=0; i<10; i++)
printk("%d,", a[i]);
printk("\n");
#endif
get_time_50ms();
while (x--) asm("nop");
pticks = get_time_50ms();
printk("hptimer %u: %k (%u)\n", timer, pticks, pticks);
}
#endif
Expand All @@ -107,30 +117,28 @@ void start_kernel(void)
setsp(&task->t_regs.ax); /* change to idle task stack */
kernel_init(); /* continue init running on idle task stack */

#if TIMER_TEST
/* run tests before 2nd process created for stability */
testloop(30000);
testloop(3000);
testloop(300);
printk("\n");
#endif

/* fork and run procedure init_task() as task #1*/
kfork_proc(init_task);
wake_up_process(&task[1]);

/*
* We are now the idle task. We won't run unless no other process can run.
*/
#if TIMER_TEST
timer_test();
testloop(10000);
testloop(3000);
testloop(500);
#endif
while (1) {
#if TIMER_TEST
timer_50ms();
#else
schedule();
#ifdef CONFIG_TIMER_INT0F
int0F(); /* simulate timer interrupt hooked on IRQ 7 */
#else
idle_halt(); /* halt until interrupt to save power */
#endif
#endif /* TIMER_TEST */
}
}

Expand Down
5 changes: 4 additions & 1 deletion qemu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ AUDIO="-audiodev pa,id=speaker -machine pcspk-audiodev=speaker"

# Configure QEMU as pure ISA system

exec $QEMU $AUDIO $CONSOLE -nodefaults -name ELKS -machine isapc -cpu 486,tsc -m 4M \
# uncomment to run native speed if x86 macOS
#MACOS="-accel hvf"

exec $QEMU $MACOS $AUDIO $CONSOLE -nodefaults -name ELKS -machine isapc -cpu 486,tsc -m 4M \
$KEYBOARD $QDISPLAY -vga std -rtc base=utc $SERIAL \
$NET $NETDUMP $IMAGE $DISK2 $@

0 comments on commit a97f710

Please sign in to comment.