another test, to help with locking exercises
This commit is contained in:
parent
4bc900e78b
commit
7797a38423
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue