diff options
| author | Robert Morris <rtm@csail.mit.edu> | 2019-10-03 15:02:19 -0400 | 
|---|---|---|
| committer | Robert Morris <rtm@csail.mit.edu> | 2019-10-03 15:02:19 -0400 | 
| commit | 56583b1402a7f8fad0f8c3c296e26f12b1114c95 (patch) | |
| tree | 68ea77f02de3b3dabea5c976f6bac571be0478d6 | |
| parent | 78f863f8aead6346dfdfc62e91af25c9383e25a7 (diff) | |
| download | xv6-labs-56583b1402a7f8fad0f8c3c296e26f12b1114c95.tar.gz xv6-labs-56583b1402a7f8fad0f8c3c296e26f12b1114c95.tar.bz2 xv6-labs-56583b1402a7f8fad0f8c3c296e26f12b1114c95.zip | |
updated alarmtest
| -rw-r--r-- | kernel/defs.h | 1 | ||||
| -rw-r--r-- | kernel/exec.c | 1 | ||||
| -rw-r--r-- | kernel/plic.c | 14 | ||||
| -rw-r--r-- | kernel/proc.h | 2 | ||||
| -rw-r--r-- | kernel/spinlock.c | 9 | ||||
| -rw-r--r-- | user/alarmtest.c | 30 | 
6 files changed, 32 insertions, 25 deletions
| diff --git a/kernel/defs.h b/kernel/defs.h index f893d28..9c5f643 100644 --- a/kernel/defs.h +++ b/kernel/defs.h @@ -173,7 +173,6 @@ int             copyinstr(pagetable_t, char *, uint64, uint64);  // plic.c  void            plicinit(void);  void            plicinithart(void); -uint64          plic_pending(void);  int             plic_claim(void);  void            plic_complete(int); diff --git a/kernel/exec.c b/kernel/exec.c index 74ef654..6a51499 100644 --- a/kernel/exec.c +++ b/kernel/exec.c @@ -112,6 +112,7 @@ exec(char *path, char **argv)    p->tf->epc = elf.entry;  // initial program counter = main    p->tf->sp = sp; // initial stack pointer    proc_freepagetable(oldpagetable, oldsz); +    return argc; // this ends up in a0, the first argument to main(argc, argv)   bad: diff --git a/kernel/plic.c b/kernel/plic.c index b569492..eed8316 100644 --- a/kernel/plic.c +++ b/kernel/plic.c @@ -28,20 +28,6 @@ plicinithart(void)    *(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.  int  plic_claim(void) diff --git a/kernel/proc.h b/kernel/proc.h index 538b48a..812c769 100644 --- a/kernel/proc.h +++ b/kernel/proc.h @@ -95,7 +95,7 @@ struct proc {    int pid;                     // Process ID    // 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)    pagetable_t pagetable;       // Page table    struct trapframe *tf;        // data page for trampoline.S diff --git a/kernel/spinlock.c b/kernel/spinlock.c index 563532e..f192832 100644 --- a/kernel/spinlock.c +++ b/kernel/spinlock.c @@ -34,7 +34,8 @@ acquire(struct spinlock *lk)    // Tell the C compiler and the processor to not move loads or stores    // 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();    // 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    // past this point, to ensure that all the stores in the critical -  // section are visible to other CPUs before the lock is released. -  // On RISC-V, this turns into a fence instruction. +  // section are visible to other CPUs before the lock is released, +  // and that loads in the critical section occur strictly before +  // the lock is released. +  // On RISC-V, this emits a fence instruction.    __sync_synchronize();    // Release the lock, equivalent to lk->locked = 0. diff --git a/user/alarmtest.c b/user/alarmtest.c index ca3db23..d3746c4 100644 --- a/user/alarmtest.c +++ b/user/alarmtest.c @@ -21,7 +21,7 @@ main(int argc, char *argv[])  {    test0();    test1(); -  exit(); +  exit(0);  }  volatile static int count; @@ -44,7 +44,7 @@ test0()    count = 0;    sigalarm(2, periodic);    for(i = 0; i < 1000*500000; i++){ -    if((i % 250000) == 0) +    if((i % 1000000) == 0)        write(2, ".", 1);      if(count > 0)        break; @@ -53,7 +53,7 @@ test0()    if(count > 0){      printf("test0 passed\n");    } 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;  } +// +// 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  test1()  { @@ -79,9 +87,19 @@ test1()        break;      foo(i, &j);    } -  if(i != j || count < 10){ -    // i should equal j -    printf("test1 failed\n"); +  if(count < 10){ +    printf("\ntest1 failed: too few calls to the handler\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 {      printf("test1 passed\n");    } | 
