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.
memset(pa, 1, PGSIZE);
acquire(&kmem.lock);
r = (struct run*)pa;
acquire(&kmem.lock);
r->next = kmem.freelist;
kmem.freelist = r;
release(&kmem.lock);
@ -75,6 +76,7 @@ kalloc(void)
if(r)
kmem.freelist = r->next;
release(&kmem.lock);
if(r)
memset((char*)r, 5, PGSIZE); // fill with junk
return (void*)r;

View file

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

View file

@ -506,6 +506,44 @@ twochildren(void)
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
forkforkfork(void)
{
@ -1858,6 +1896,7 @@ main(int argc, char *argv[])
reparent();
twochildren();
forkfork();
forkforkfork();
argptest();