updated alarmtest

This commit is contained in:
Robert Morris 2019-10-03 15:02:19 -04:00
parent 78f863f8ae
commit 56583b1402
6 changed files with 32 additions and 25 deletions

View file

@ -173,7 +173,6 @@ int copyinstr(pagetable_t, char *, uint64, uint64);
// plic.c // plic.c
void plicinit(void); void plicinit(void);
void plicinithart(void); void plicinithart(void);
uint64 plic_pending(void);
int plic_claim(void); int plic_claim(void);
void plic_complete(int); void plic_complete(int);

View file

@ -112,6 +112,7 @@ exec(char *path, char **argv)
p->tf->epc = elf.entry; // initial program counter = main p->tf->epc = elf.entry; // initial program counter = main
p->tf->sp = sp; // initial stack pointer p->tf->sp = sp; // initial stack pointer
proc_freepagetable(oldpagetable, oldsz); proc_freepagetable(oldpagetable, oldsz);
return argc; // this ends up in a0, the first argument to main(argc, argv) return argc; // this ends up in a0, the first argument to main(argc, argv)
bad: bad:

View file

@ -28,20 +28,6 @@ plicinithart(void)
*(uint32*)PLIC_SPRIORITY(hart) = 0; *(uint32*)PLIC_SPRIORITY(hart) = 0;
} }
// return a bitmap of which IRQs are waiting
// to be served.
uint64
plic_pending(void)
{
uint64 mask;
//mask = *(uint32*)(PLIC + 0x1000);
//mask |= (uint64)*(uint32*)(PLIC + 0x1004) << 32;
mask = *(uint64*)PLIC_PENDING;
return mask;
}
// ask the PLIC what interrupt we should serve. // ask the PLIC what interrupt we should serve.
int int
plic_claim(void) plic_claim(void)

View file

@ -95,7 +95,7 @@ struct proc {
int pid; // Process ID int pid; // Process ID
// these are private to the process, so p->lock need not be held. // these are private to the process, so p->lock need not be held.
uint64 kstack; // Bottom of kernel stack for this process uint64 kstack; // Virtual address of kernel stack
uint64 sz; // Size of process memory (bytes) uint64 sz; // Size of process memory (bytes)
pagetable_t pagetable; // Page table pagetable_t pagetable; // Page table
struct trapframe *tf; // data page for trampoline.S struct trapframe *tf; // data page for trampoline.S

View file

@ -34,7 +34,8 @@ acquire(struct spinlock *lk)
// Tell the C compiler and the processor to not move loads or stores // Tell the C compiler and the processor to not move loads or stores
// past this point, to ensure that the critical section's memory // past this point, to ensure that the critical section's memory
// references happen after the lock is acquired. // references happen strictly after the lock is acquired.
// On RISC-V, this emits a fence instruction.
__sync_synchronize(); __sync_synchronize();
// Record info about lock acquisition for holding() and debugging. // Record info about lock acquisition for holding() and debugging.
@ -52,8 +53,10 @@ release(struct spinlock *lk)
// Tell the C compiler and the CPU to not move loads or stores // Tell the C compiler and the CPU to not move loads or stores
// past this point, to ensure that all the stores in the critical // past this point, to ensure that all the stores in the critical
// section are visible to other CPUs before the lock is released. // section are visible to other CPUs before the lock is released,
// On RISC-V, this turns into a fence instruction. // and that loads in the critical section occur strictly before
// the lock is released.
// On RISC-V, this emits a fence instruction.
__sync_synchronize(); __sync_synchronize();
// Release the lock, equivalent to lk->locked = 0. // Release the lock, equivalent to lk->locked = 0.

View file

@ -21,7 +21,7 @@ main(int argc, char *argv[])
{ {
test0(); test0();
test1(); test1();
exit(); exit(0);
} }
volatile static int count; volatile static int count;
@ -44,7 +44,7 @@ test0()
count = 0; count = 0;
sigalarm(2, periodic); sigalarm(2, periodic);
for(i = 0; i < 1000*500000; i++){ for(i = 0; i < 1000*500000; i++){
if((i % 250000) == 0) if((i % 1000000) == 0)
write(2, ".", 1); write(2, ".", 1);
if(count > 0) if(count > 0)
break; break;
@ -53,7 +53,7 @@ test0()
if(count > 0){ if(count > 0){
printf("test0 passed\n"); printf("test0 passed\n");
} else { } else {
printf("test0 failed\n"); printf("\ntest0 failed: the kernel never called the alarm handler\n");
} }
} }
@ -64,6 +64,14 @@ void __attribute__ ((noinline)) foo(int i, int *j) {
*j += 1; *j += 1;
} }
//
// tests that the kernel calls the handler multiple times.
//
// tests that, when the handler returns, it returns to
// the point in the program where the timer interrupt
// occurred, with all registers holding the same values they
// held when the interrupt occurred.
//
void void
test1() test1()
{ {
@ -79,9 +87,19 @@ test1()
break; break;
foo(i, &j); foo(i, &j);
} }
if(i != j || count < 10){ if(count < 10){
// i should equal j printf("\ntest1 failed: too few calls to the handler\n");
printf("test1 failed\n"); exit(1);
} else if(i != j){
// the loop should have called foo() i times, and foo() should
// have incremented j once per call, so j should equal i.
// once possible source of errors is that the handler may
// return somewhere other than where the timer interrupt
// occurred; another is that that registers may not be
// restored correctly, causing i or j or the address ofj
// to get an incorrect value.
printf("\ntest1 failed: foo() executed fewer times than it was called\n");
exit(1);
} else { } else {
printf("test1 passed\n"); printf("test1 passed\n");
} }