another test, to help with locking exercises

This commit is contained in:
Robert Morris 2019-07-11 05:41:59 -04:00
parent 4bc900e78b
commit 7797a38423
3 changed files with 47 additions and 5 deletions

View file

@ -55,8 +55,9 @@ kfree(void *pa)
// Fill with junk to catch dangling refs. // Fill with junk to catch dangling refs.
memset(pa, 1, PGSIZE); memset(pa, 1, PGSIZE);
acquire(&kmem.lock);
r = (struct run*)pa; r = (struct run*)pa;
acquire(&kmem.lock);
r->next = kmem.freelist; r->next = kmem.freelist;
kmem.freelist = r; kmem.freelist = r;
release(&kmem.lock); release(&kmem.lock);
@ -75,6 +76,7 @@ kalloc(void)
if(r) if(r)
kmem.freelist = r->next; kmem.freelist = r->next;
release(&kmem.lock); release(&kmem.lock);
if(r) if(r)
memset((char*)r, 5, PGSIZE); // fill with junk memset((char*)r, 5, PGSIZE); // fill with junk
return (void*)r; return (void*)r;

View file

@ -25,7 +25,7 @@ acquire(struct spinlock *lk)
if(holding(lk)) if(holding(lk))
panic("acquire"); panic("acquire");
// On RISC-V, this turns into an atomic swap: // On RISC-V, sync_lock_test_and_set turns into an atomic swap:
// a5 = 1 // a5 = 1
// s1 = &lk->locked // s1 = &lk->locked
// amoswap.w.aq a5, a5, (s1) // amoswap.w.aq a5, a5, (s1)
@ -57,9 +57,10 @@ release(struct spinlock *lk)
__sync_synchronize(); __sync_synchronize();
// Release the lock, equivalent to lk->locked = 0. // Release the lock, equivalent to lk->locked = 0.
// This code can't use a C assignment, since it might // This code doesn't use a C assignment, since the C standard
// not be atomic. // implies that an assignment might be implemented with
// On RISC-V, this turns into an atomic swap: // multiple store instructions.
// On RISC-V, sync_lock_release turns into an atomic swap:
// s1 = &lk->locked // s1 = &lk->locked
// amoswap.w zero, zero, (s1) // amoswap.w zero, zero, (s1)
__sync_lock_release(&lk->locked); __sync_lock_release(&lk->locked);

View file

@ -506,6 +506,44 @@ twochildren(void)
printf(1, "twochildren ok\n"); printf(1, "twochildren ok\n");
} }
// concurrent forks to try to expose locking bugs.
void
forkfork(void)
{
int ppid = getpid();
printf(1, "forkfork test\n");
for(int i = 0; i < 2; i++){
int pid = fork();
if(pid < 0){
printf(1, "fork failed");
exit();
}
if(pid == 0){
for(int j = 0; j < 200; j++){
int pid1 = fork();
if(pid1 < 0){
printf(1, "fork failed\n");
kill(ppid);
exit();
}
if(pid1 == 0){
exit();
}
wait();
}
exit();
}
}
for(int i = 0; i < 2; i++){
wait();
}
printf(1, "forkfork ok\n");
}
void void
forkforkfork(void) forkforkfork(void)
{ {
@ -1858,6 +1896,7 @@ main(int argc, char *argv[])
reparent(); reparent();
twochildren(); twochildren();
forkfork();
forkforkfork(); forkforkfork();
argptest(); argptest();