cow.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. /* cow tests copy on write.
  2. *
  3. * It does so by doing a getpid(), then a fork. Child and parent set
  4. * an auto (i.e. on-stack) stack value to getpid() again. If COW
  5. * works, they will see the right value: pre and post-fork getpid
  6. * values will be the same. If COW does not work, they will see
  7. * different values in pre- and post-fork pid values, because the page
  8. * won't be copied since COW did not happen and one of them will see
  9. * the other's stack. Writing this test is *really* a bit tricky. You
  10. * have to write it with minimal branches because if COW is not
  11. * working, then the return from fork can go to the wrong place
  12. * because the parent and child might have the same stack. Which
  13. * means, sadly, that one can print PASS and one can print FAIL. I
  14. * don't know any good way to fix this. But this program has diagnosed
  15. * the problem with the riscv port failing to run pipering correctly.
  16. * So maybe all we can do is run it by hand.
  17. */
  18. #include <u.h>
  19. #include <libc.h>
  20. void
  21. main(int argc, char *argv[])
  22. {
  23. int i;
  24. int pid, fpid, cpid;
  25. pid = getpid();
  26. if ((cpid = fork()) < 0)
  27. sysfatal("fork failed: %r");
  28. fpid = getpid();
  29. // This test is racy but it's hard to do without a race.
  30. if (cpid && pid != fpid) {
  31. print("FAIL: pre-fork pid is %d, post-fork pid is %d\n", pid, fpid);
  32. exits("FAIL");
  33. }
  34. print("PASS\n");
  35. exits("PASS");
  36. }