home *** CD-ROM | disk | FTP | other *** search
/ ftp.ee.pdx.edu / 2014.02.ftp.ee.pdx.edu.tar / ftp.ee.pdx.edu / pub / users / Harry / Blitz / OSProject / p6 / TestProgram3.c < prev    next >
Text File  |  2009-06-03  |  25KB  |  818 lines

  1. code TestProgram3
  2.  
  3.  
  4.            ------------------------------------------
  5.            ------                              ------
  6.            ------  Harry's Test Program #3     ------
  7.            ------                              ------
  8.            ------------------------------------------
  9.  
  10.  
  11. -----------------------------  main  ---------------------------------
  12.  
  13.   function main ()
  14.     --
  15.     -- For each of the following tests, you should uncomment the call,
  16.     -- compile and run this program, and hand in the output it produces.
  17.     --
  18.     -- This program should be run with the following constants in the kernel:
  19.     --     NUMBER_OF_PHYSICAL_PAGE_FRAMES = 512
  20.     --     MAX_NUMBER_OF_PROCESSES = 10
  21.     --     MAX_PAGES_PER_VIRT_SPACE = 20
  22.     --     MAX_FILES_PER_PROCESS = 10
  23.     --     USER_STACK_SIZE_IN_PAGES = 1
  24.     --     NUMBER_OF_ENVIRONMENT_PAGES = 0
  25.  
  26.  
  27.       -- SysExitTest ()
  28.       -- BasicForkTest ()
  29.       -- YieldTest ()
  30.       -- ForkTest ()
  31.       -- JoinTest1 ()
  32.       -- JoinTest2 ()
  33.       -- JoinTest3 ()
  34.       -- JoinTest4 ()
  35.       -- ManyProcessesTest1 ()
  36.       -- ManyProcessesTest2 ()
  37.       -- ManyProcessesTest3 ()
  38.       -- ErrorTest ()
  39.  
  40.       Sys_Exit (0)
  41.     endFunction
  42.  
  43. -----------------------------  SysExitTest  ---------------------------------
  44.  
  45.   function SysExitTest ()
  46.     --
  47.     -- This function executes the Sys_Exit syscall.
  48.     --
  49.       print ("\nSysExitTest running.\n\n")
  50.       print ("About to terminate the only process; should cause the OS to stop on a 'wait' instruction.\n")
  51.       Sys_Exit (0)
  52.       print ("*****  Error: Should not return from Sys_Exit  *****")
  53.     endFunction
  54.  
  55. -----------------------------  BasicForkTest  ---------------------------------
  56.  
  57.   function BasicForkTest ()
  58.     --
  59.     -- This function creates two processes.  Each one prints a message and
  60.     -- calls Sys_Exit.
  61.     --
  62.       var pid: int
  63.       print ("\nBasicForkTest running.\n\n")
  64.       pid = Sys_Fork ()
  65.       if pid == 0
  66.         print ("I am the child\n")
  67.         Sys_Exit (0)
  68.       elseIf pid == 1
  69.         -- The first process should have pid == 1.
  70.         -- Check to see if nextPID is incremented before or after first use.
  71.         print ("*****  Error: Fork returns 1, implying the parent had pid == 0  *****\n")
  72.         Sys_Exit (0)
  73.       else
  74.         print ("I am the parent\n")
  75.         Sys_Exit (0)
  76.       endIf
  77.     endFunction
  78.  
  79. -----------------------------  YieldTest  ---------------------------------
  80.  
  81.   function YieldTest ()
  82.     --
  83.     -- This function creates two processes and each one prints several
  84.     -- messages.  It does this twice.  In the first run, the processes
  85.     -- contain no yields.  In the second run, the processes contain
  86.     -- calls to yield.  If yield acutally does anything, the two runs should
  87.     -- be different.
  88.     --
  89.       var pid, i, j: int
  90.       print ("\nYieldTest running.\n\n")
  91.       print ("This test involves calls to Fork, Yield, and Exit.\n\n")
  92.       print ("RUN ONE: You should see 10 'compiler' messages and 10 'OS' messages.\n\n")
  93.       pid = Sys_Fork ()
  94.       if pid == 0
  95.         -- Child Code
  96.         for i = 1 to 10
  97.           print ("Designing compilers is fun!\n")
  98.         endFor
  99.       else
  100.         -- Parent Code
  101.         for i = 1 to 10
  102.           print ("Writing OS kernel code is a blast!\n")
  103.         endFor
  104.         Sys_Exit (0)
  105.       endIf
  106.       Sys_Yield ()
  107.       Sys_Yield ()
  108.       Sys_Yield ()
  109.       Sys_Yield ()
  110.       Sys_Yield ()
  111.       print ("\nRUN TWO: You should see the same 20 messages, but the order should be different, due to the presence of 'Yield's.\n\n")
  112.       pid = Sys_Fork ()
  113.       if pid == 0
  114.         -- Child Code
  115.         for i = 1 to 10
  116.           for j = 1 to i
  117.             Sys_Yield ()
  118.           endFor
  119.           print ("Designing compilers is fun!\n")
  120.           Sys_Yield ()
  121.         endFor
  122.       else
  123.         -- Parent Code
  124.         for i = 1 to 10
  125.           for j = i to 10
  126.             Sys_Yield ()
  127.           endFor
  128.           print ("Writing OS kernel code is a blast!\n")
  129.         endFor
  130.         Sys_Exit (0)
  131.       endIf
  132.  
  133.     endFunction
  134.  
  135. -----------------------------  ForkTest  ---------------------------------
  136.  
  137.   function ForkTest ()
  138.     --
  139.     -- This function creates a whole bunch of processes.
  140.     --
  141.       print ("\nForkTest running.\n\n")
  142.       print ("This test involves calls to Fork, Yield, and Exit.\n")
  143.       print ("There should be 26 columns (A-Z) printed.  Each letter should be printed 5 times.\n")
  144.       ExecuteAFork ("A\n")
  145.       ExecuteAFork (" B\n")
  146.       ExecuteAFork ("  C\n")
  147.       ExecuteAFork ("   D\n")
  148.       ExecuteAFork ("    E\n")
  149.       ExecuteAFork ("     F\n")
  150.       ExecuteAFork ("      G\n")
  151.       ExecuteAFork ("       H\n")
  152.       ExecuteAFork ("        I\n")
  153.       ExecuteAFork ("         J\n")
  154.       ExecuteAFork ("          K\n")
  155.       ExecuteAFork ("           L\n")
  156.       ExecuteAFork ("            M\n")
  157.       ExecuteAFork ("             N\n")
  158.       ExecuteAFork ("              O\n")
  159.       ExecuteAFork ("               P\n")
  160.       ExecuteAFork ("                Q\n")
  161.       ExecuteAFork ("                 R\n")
  162.       ExecuteAFork ("                  S\n")
  163.       ExecuteAFork ("                   T\n")
  164.       ExecuteAFork ("                    U\n")
  165.       ExecuteAFork ("                     V\n")
  166.       ExecuteAFork ("                      W\n")
  167.       ExecuteAFork ("                       X\n")
  168.       ExecuteAFork ("                        Y\n")
  169.       ExecuteAFork ("                         Z\n")
  170.       Sys_Exit (0)
  171.     endFunction
  172.  
  173. -----------------------------  ExecuteAFork  ---------------------------------
  174.  
  175.   function ExecuteAFork (str: String)
  176.     --
  177.     -- Create a process to print out the string 5 times.  Also create a child
  178.     -- process to continue and return and terminate the parent.  This done
  179.     -- because otherwise we would create 1 parent processes, with 26 children.
  180.     -- Each child terminates but will turn into a zombie until its parent either
  181.     -- does a join or itself terminates.  With a small MAX number of processes,
  182.     -- we could run out of PCBs if we don't kill the parent and fully reclaim
  183.     -- its resources.
  184.     --
  185.       var pid: int
  186.           i, j: int
  187.       pid = Sys_Fork ()
  188.       if pid == 0
  189.         -- Child Code
  190.         for i = 1 to 5
  191.           print (str)
  192.           for j = 1 to i*50   -- Increase this constant for greater parallelism
  193.             Sys_Yield ()
  194.           endFor
  195.         endFor
  196.         Sys_Exit (0)
  197.       else
  198.         -- Parent Code
  199.         -- Create another child to continue our work and terminate this process
  200.         pid = Sys_Fork ()
  201.         if pid != 0
  202.           Sys_Exit (0)
  203.         endIf
  204.       endIf
  205.     endFunction
  206.  
  207. -----------------------------  JoinTest1  ---------------------------------
  208.  
  209.   function JoinTest1 ()
  210.     --
  211.     -- This function creates two processes.  The child immediately calls
  212.     -- Exit to return a value to the parent.  The parent waits a long time,
  213.     -- (until after the child has done its exit) and then calls Join.  It makes
  214.     -- sure the value passed from the child is returned to the parent.  Then
  215.     -- this test does the same thing again, except this time the parent calls
  216.     -- join immediately while the child waits a long time before calling Exit.
  217.     --
  218.       var pid, i: int
  219.       print ("\nJoinTest 1 running.\n\n")
  220.       print ("This test involves calls to Fork, Yield, and Exit.\n")
  221.       print ("Running first test...\n")
  222.       pid = Sys_Fork ()
  223.       if pid == 0
  224.         -- Child Code
  225.         print ("This line should print first.\n")
  226.         Sys_Exit (0x12345678)
  227.       else
  228.         -- Parent Code
  229.         -- Wait for child to finish first
  230.         for i = 1 to 100
  231.           Sys_Yield ()
  232.         endFor
  233.         print ("This line should print second.\n")
  234.         i = Sys_Join (pid)
  235.         if i != 0x12345678
  236.           print ("*****  ERROR: Exit passes 0x12345678, but join returns ")
  237.           printHex (i)
  238.           print ("  *****\n")
  239.         else
  240.           print ("Done.\n")
  241.         endIf
  242.       endIf
  243.       print ("Running second test...\n")
  244.       pid = Sys_Fork ()
  245.       if pid == 0
  246.         -- Child Code
  247.         -- Wait for parent to call join first
  248.         for i = 1 to 100
  249.           Sys_Yield ()
  250.         endFor
  251.         print ("This line should print second.\n")
  252.         Sys_Exit (0x87654321)
  253.       else
  254.         -- Parent Code
  255.         print ("This line should print first.\n")
  256.         i = Sys_Join (pid)
  257.         if i != 0x87654321
  258.           print ("*****  ERROR: Exit passes 0x87654321, but join returns ")
  259.           printHex (i)
  260.           print ("  *****\n")
  261.         else
  262.           print ("Done.\n")
  263.         endIf
  264.       endIf
  265.     endFunction
  266.  
  267. -----------------------------  JoinTest2  ---------------------------------
  268.  
  269.   function JoinTest2 ()
  270.     --
  271.     -- This function creates 5 children.  It then waits for each child to
  272.     -- finish. It makes sure that the expected value is passed back from
  273.     -- each child.
  274.     --
  275.       var pid1, pid2, pid3, pid4, pid5: int
  276.       print ("\nJoinTest 2 running.\n\n")
  277.       print ("This test involves calls to Fork, Yield, and Exit.\n")
  278.       print ("Creating 5 children...\n")
  279.  
  280.       pid1 = Sys_Fork ()
  281.       if pid1 == 0
  282.         -- Code for child 1
  283.         print ("Child 1 running...\n")
  284.         Sys_Yield ()
  285.         Sys_Exit (100)
  286.       endIf
  287.  
  288.       pid2 = Sys_Fork ()
  289.       if pid2 == 0
  290.         -- Code for child 2
  291.         print ("Child 2 running...\n")
  292.         Sys_Yield ()
  293.         Sys_Exit (200)
  294.       endIf
  295.  
  296.       pid3 = Sys_Fork ()
  297.       if pid3 == 0
  298.         -- Code for child 3
  299.         print ("Child 3 running...\n")
  300.         Sys_Yield ()
  301.         Sys_Exit (300)
  302.       endIf
  303.  
  304.       pid4 = Sys_Fork ()
  305.       if pid4 == 0
  306.         -- Code for child 4
  307.         print ("Child 4 running...\n")
  308.         Sys_Yield ()
  309.         Sys_Exit (400)
  310.       endIf
  311.  
  312.       pid5 = Sys_Fork ()
  313.       if pid5 == 0
  314.         -- Code for child 5
  315.         print ("Child 5 running...\n")
  316.         Sys_Exit (500)
  317.       endIf
  318.  
  319.       print ("Waiting for children in order 1, 2, 3, 4, 5...\n")
  320.  
  321.       if 100 != Sys_Join (pid1)
  322.         print ("*****  ERROR: 100 != Sys_Join (pid1)  *****\n")
  323.       endIf
  324.  
  325.       if 200 != Sys_Join (pid2)
  326.         print ("*****  ERROR: 200 != Sys_Join (pid2)  *****\n")
  327.       endIf
  328.  
  329.       if 300 != Sys_Join (pid3)
  330.         print ("*****  ERROR: 300 != Sys_Join (pid3)  *****\n")
  331.       endIf
  332.  
  333.       if 400 != Sys_Join (pid4)
  334.         print ("*****  ERROR: 400 != Sys_Join (pid4)  *****\n")
  335.       endIf
  336.  
  337.       if 500 != Sys_Join (pid5)
  338.         print ("*****  ERROR: 500 != Sys_Join (pid5)  *****\n")
  339.       endIf
  340.  
  341.       print ("Creating 5 more children...\n")
  342.  
  343.       pid1 = Sys_Fork ()
  344.       if pid1 == 0
  345.         -- Code for child 1
  346.         print ("Child 1 running...\n")
  347.         Sys_Yield ()
  348.         Sys_Exit (100)
  349.       endIf
  350.  
  351.       pid2 = Sys_Fork ()
  352.       if pid2 == 0
  353.         -- Code for child 2
  354.         print ("Child 2 running...\n")
  355.         Sys_Yield ()
  356.         Sys_Exit (200)
  357.       endIf
  358.  
  359.       pid3 = Sys_Fork ()
  360.       if pid3 == 0
  361.         -- Code for child 3
  362.         print ("Child 3 running...\n")
  363.         Sys_Yield ()
  364.         Sys_Exit (300)
  365.       endIf
  366.  
  367.       pid4 = Sys_Fork ()
  368.       if pid4 == 0
  369.         -- Code for child 4
  370.         print ("Child 4 running...\n")
  371.         Sys_Yield ()
  372.         Sys_Exit (400)
  373.       endIf
  374.  
  375.       pid5 = Sys_Fork ()
  376.       if pid5 == 0
  377.         -- Code for child 5
  378.         print ("Child 5 running...\n")
  379.         Sys_Exit (500)
  380.       endIf
  381.  
  382.       print ("Waiting for children in order 5, 4, 1, 3, 2...\n")
  383.  
  384.       if 500 != Sys_Join (pid5)
  385.         print ("*****  ERROR: 500 != Sys_Join (pid5)  *****\n")
  386.       endIf
  387.  
  388.       if 400 != Sys_Join (pid4)
  389.         print ("*****  ERROR: 400 != Sys_Join (pid4)  *****\n")
  390.       endIf
  391.  
  392.       if 100 != Sys_Join (pid1)
  393.         print ("*****  ERROR: 100 != Sys_Join (pid1)  *****\n")
  394.       endIf
  395.  
  396.       if 300 != Sys_Join (pid3)
  397.         print ("*****  ERROR: 300 != Sys_Join (pid3)  *****\n")
  398.       endIf
  399.  
  400.       if 200 != Sys_Join (pid2)
  401.         print ("*****  ERROR: 200 != Sys_Join (pid2)  *****\n")
  402.       endIf
  403.  
  404.       print ("Done.\n")
  405.  
  406.     endFunction
  407.  
  408. -----------------------------  JoinTest3  ---------------------------------
  409.  
  410.   function JoinTest3 ()
  411.     --
  412.     -- This function waits for a non-existent child, which is an error
  413.     --
  414.       print ("\nJoinTest3 running.\n\n")
  415.       print ("This test involves 5 illegal calls to Sys_Join, waiting on non-existent children.\n")
  416.       print ("In each case, it prints the return code, which should be -1.\n")
  417.  
  418.       printIntVar ("Return code from 1st call", Sys_Join (-1))
  419.       printIntVar ("Return code from 2nd call", Sys_Join (0))
  420.       printIntVar ("Return code from 3rd call", Sys_Join (1))
  421.       printIntVar ("Return code from 4th call", Sys_Join (2))
  422.       printIntVar ("Return code from 5th call", Sys_Join (40123))
  423.  
  424.       print ("Done.\n")
  425.  
  426.     endFunction
  427.  
  428. -----------------------------  JoinTest4  ---------------------------------
  429.  
  430.   function JoinTest4 ()
  431.     --
  432.     -- This function waits for a child that we've already waited for.  A
  433.     -- call to Sys_Join in this case should return -1.  It also creates a tree
  434.     -- of processes, and calls Sys_Join for processes that are not children as
  435.     -- well as for processes that are children.
  436.     --
  437.       var pid, i, j, pid1, pid2: int
  438.           myName, nameOfChild1, nameOfChild2: String
  439.       print ("\nJoinTest4 running.\n\n")
  440.       print ("   This test forks a child process and then waits on it twice.\n")
  441.       print ("   The first call to Sys_Join should return its error code; the\n")
  442.       print ("   second call to Sys_Join should return -1.\n\n")
  443.  
  444.       -- First test: make sure the Sys_Join is called before Sys_Exit.
  445.       pid = Sys_Fork ()
  446.       if pid == 0
  447.         -- Child Code
  448.         for i = 1 to 100
  449.           Sys_Yield ()
  450.         endFor
  451.         print ("This should print second.\n")
  452.         Sys_Exit (12345)
  453.       endIf
  454.       printIntVar ("The PID of the child", pid)
  455.       print ("This should print first.\n")
  456.       i = Sys_Join (pid)
  457.       if i == 12345
  458.         print ("Okay (1).\n")
  459.       else
  460.         printIntVar ("*****  ERROR: Return code from first call to Sys_Join", i)
  461.       endIf
  462.       i = Sys_Join (pid)
  463.       if i == -1
  464.         print ("Okay (2).\n")
  465.       else
  466.         printIntVar ("*****  ERROR: Return code from second call to Sys_Join", i)
  467.       endIf
  468.  
  469.       -- Second test: make sure the Sys_Exit is called before Sys_Join.
  470.       pid = Sys_Fork ()
  471.       if pid == 0
  472.         -- Child Code
  473.         print ("This should print first.\n")
  474.         Sys_Exit (12345)
  475.       endIf
  476.       for i = 1 to 100
  477.         Sys_Yield ()
  478.       endFor
  479.       printIntVar ("The PID of the child", pid)
  480.       print ("This should print second.\n")
  481.       i = Sys_Join (pid)
  482.       if i == 12345
  483.         print ("Okay (3).\n")
  484.       else
  485.         printIntVar ("*****  ERROR: Return code from first call to Sys_Join", i)
  486.       endIf
  487.       i = Sys_Join (pid)
  488.       if i == -1
  489.         print ("Okay (4).\n")
  490.       else
  491.         printIntVar ("*****  ERROR: Return code from second call to Sys_Join", i)
  492.       endIf
  493.  
  494.       print ("\n   In the next test, we create 2 children, and each creates 2 children,\n")
  495.       print ("   giving 7 processes in all.  Then each process attempts a Sys_Join on\n")
  496.       print ("   every process except its own children, to make sure the result is -1.\n")
  497.       print ("   Finally, each process with children waits on them.\n\n")
  498.       -- Create this process tree:
  499.       --    A
  500.       --      A.B
  501.       --         A.B.D
  502.       --         A.B.E
  503.       --      A.C
  504.       --         A.C.F
  505.       --         A.C.G
  506.       -- Set every process's "myName".  For processes with children, set
  507.       -- "pid1" and "pid2" and set "nameOfChild1" and "nameOfChild2".
  508.       pid1 = Sys_Fork ()
  509.       if pid1 == 0
  510.         -- Now in child (process A.B)
  511.         pid1 = Sys_Fork ()
  512.         if pid1 == 0
  513.           -- Now in child (process A.B.D)
  514.           myName = "A.B.D"
  515.         else
  516.           -- Now in parent (process A.B)
  517.           myName = "A.B"
  518.           pid2 = Sys_Fork ()
  519.           if pid2 == 0
  520.             -- Now in child (process A.B.E)
  521.             myName = "A.B.E"
  522.             pid1 = 0
  523.           else
  524.             -- Now in parent (process A.B)
  525.             myName = "A.B"
  526.             nameOfChild1 = "A.B.D"
  527.             nameOfChild2 = "A.B.E"
  528.           endIf
  529.         endIf
  530.       else
  531.         -- Now in parent (process A)
  532.         pid2 = Sys_Fork ()
  533.         if pid2 == 0
  534.           -- Now in child (process A.C)
  535.           pid1 = Sys_Fork ()
  536.           if pid1 == 0
  537.             -- Now in child (process A.C.F)
  538.             myName = "A.C.F"
  539.           else
  540.             -- Now in parent (process A.C)
  541.             pid2 = Sys_Fork ()
  542.             if pid2 == 0
  543.               -- Now in child (process A.C.G)
  544.               myName = "A.C.G"
  545.               pid1 = 0
  546.             else
  547.               -- Now in parent (process A.C)
  548.               myName = "A.C"
  549.               nameOfChild1 = "A.C.F"
  550.               nameOfChild2 = "A.C.G"
  551.             endIf
  552.           endIf
  553.         else
  554.           -- Now in parent (process A)
  555.           myName = "A"
  556.           nameOfChild1 = "A.B"
  557.           nameOfChild2 = "A.C"
  558.         endIf
  559.       endIf
  560.  
  561.       -- Every process will execute the following code.  First
  562.       -- print out this process's name and, if it has children,
  563.       -- print their names and pids.
  564.       print (myName)
  565.       print (" is running...\n")
  566.       if nameOfChild1
  567.         print ("  My first  child is ")
  568.         print (nameOfChild1)
  569.         printIntVar ("   pid1", pid1)
  570.         print ("  My second child is ")
  571.         print (nameOfChild2)
  572.         printIntVar ("   pid2", pid2)
  573.       endIf
  574.       print ("---------------\n")
  575.  
  576.       -- Next call Sys_Join for lots of different pids, except do
  577.       -- not call Sys_Join for our own children.  Make sure everything
  578.       -- returns -1.
  579.       for i = -5 to 20
  580.         if i != pid1 && i != pid2
  581.           j = Sys_Join (i)
  582.           if j != -1
  583.             print ("***** ERROR in process ")
  584.             print (myName)
  585.             print (" *****\n")
  586.             printIntVar ("*****  Arg to Sys_Join, i", i)
  587.             printIntVar ("*****  Result from Sys_Join was not -1; j", j)
  588.           endIf
  589.         endIf
  590.       endFor
  591.  
  592.       -- Wait for every body to finish the above testing before printing.
  593.       for i = 1 to 400
  594.         Sys_Yield ()
  595.       endFor
  596.  
  597.       print (myName)
  598.       print (" done with error tests...\n")
  599.  
  600.       -- Wait for every body to finish the above printing.
  601.       for i = 1 to 400
  602.         Sys_Yield ()
  603.       endFor
  604.  
  605.       -- If we've got children...
  606.       if pid1 != 0
  607.  
  608.         -- Wait for the first child to terminate.
  609.         print ("-----------------------------------")
  610.         print (myName)
  611.         print (" is waiting on ")
  612.         print (nameOfChild1)
  613.         printIntVar ("     pid1", pid1)
  614.         j = Sys_Join (pid1)
  615.         if j != 123
  616.           print ("***** ERROR in process ")
  617.           print (myName)
  618.           print (" *****\n")
  619.           printIntVar ("*****  Arg to Sys_Join, pid1", pid1)
  620.           printIntVar ("*****  Result from Sys_Join was not 123; j", j)
  621.         endIf
  622.  
  623.         -- Wait for the second child to terminate.
  624.         print ("-----------------------------------")
  625.         print (myName)
  626.         print (" is waiting on ")
  627.         print (nameOfChild2)
  628.         printIntVar ("     pid2", pid2)
  629.         j = Sys_Join (pid2)
  630.         if j != 123
  631.           print ("***** ERROR in process ")
  632.           print (myName)
  633.           print (" *****\n")
  634.           printIntVar ("*****  Arg to Sys_Join, pid2", pid2)
  635.           printIntVar ("*****  Result from Sys_Join was not 123; j", j)
  636.         endIf
  637.  
  638.       else
  639.         -- Else if this process has no children, then wait a long time
  640.         -- so the parents will call Sys_Join first.
  641.  
  642.         for i = 1 to 400
  643.           Sys_Yield ()
  644.         endFor
  645.  
  646.       endIf
  647.  
  648.       print (myName)
  649.       print (" is done.\n")
  650.       Sys_Exit (123)
  651.     endFunction
  652.  
  653. -----------------------------  ManyProcessesTest1  ---------------------------------
  654.  
  655.   function ManyProcessesTest1 ()
  656.     --
  657.     -- This function creates lots of processes.  Each should terminate, so
  658.     -- the test should not cause problems unless resources are not freed.
  659.     --
  660.       var i, pid: int
  661.       print ("\nManyProcessesTest1 running.\n\n")
  662.       print ("This test should create 100 child processes.\n")
  663.       print ("It should print 100 lines of output.\n")
  664.  
  665.       for i = 1 to 100
  666.         pid = Sys_Fork ()
  667.         if pid != 0
  668.           -- Parent code
  669.           Sys_Exit (0)
  670.         endIf
  671.         print ("Child ")
  672.         printInt (i)
  673.         nl ()
  674.       endFor
  675.  
  676.       print ("Done.\n")
  677.  
  678.     endFunction
  679.  
  680. -----------------------------  ManyProcessesTest2  ---------------------------------
  681.  
  682.   function ManyProcessesTest2 ()
  683.       print ("\nManyProcessesTest2 running.\n\n")
  684.       CreateManyProcesses (9)
  685.     endFunction
  686.  
  687. -----------------------------  ManyProcessesTest3  ---------------------------------
  688.  
  689.   function ManyProcessesTest3 ()
  690.       print ("\nManyProcessesTest3 running.\n\n")
  691.       CreateManyProcesses (10)
  692.     endFunction
  693.  
  694. -----------------------------  CreateManyProcesses  ---------------------------------
  695.  
  696.   function CreateManyProcesses (numProcs: int)
  697.     --
  698.     -- This function creates numProcs additional processes.  If numProcs is
  699.     -- 9 or less, this should be possible.  If numProcs is greater then the
  700.     -- OS should run out of PCBs and hang.
  701.     --
  702.       var i, pid: int
  703.       print ("This test attempts to create ")
  704.       printInt (numProcs)
  705.       print (" new processes.\n")
  706.  
  707.       if numProcs <= 9
  708.         print ("It should print a line for each process and then it should print 123.\n")
  709.       else
  710.         print ("It should run out of resources and hang.\n")
  711.       endIf
  712.  
  713.       print ("Process 0\n")  -- Print a line for the initial process
  714.       pid = Sys_Fork ()
  715.       if pid == 0
  716.         -- Code for 1st child
  717.         print ("Process 1\n")
  718.         for i = 2 to numProcs
  719.           pid = Sys_Fork ()
  720.           if pid == 0
  721.             -- Code for a new child
  722.             print ("Process ")
  723.             printInt (i)
  724.             nl ()
  725.           else
  726.             -- Code for the parent: wait on the child
  727.             Sys_Exit (Sys_Join (pid))
  728.           endIf
  729.         endFor
  730.         -- Last child will exit loop and return
  731.         Sys_Exit (123)
  732.       else
  733.         -- Code for original parent: wait on its child
  734.         printIntVar ("Final return value", Sys_Join (pid))
  735.         print ("Done.\n")
  736.       endIf
  737.  
  738.     endFunction
  739.  
  740. -----------------------------  ErrorTest  ---------------------------------
  741.  
  742.   function ErrorTest ()
  743.     --
  744.     -- This tests what happens when a user-level program has an error.
  745.     --
  746.       var pid, i: int
  747.           p: ptr to int
  748.  
  749.       print ("\nErrorTest running.\n\n")
  750.  
  751.       print ("Should print \"User Program Error: Attempt to use a null pointer!\"...\n")
  752.       pid = Sys_Fork ()
  753.       if pid == 0
  754.         -- Child process: cause runtime error
  755.         *p = 123
  756.         print ("*****  ERROR: Execution will not continue  *****\n")
  757.         Sys_Exit (0)
  758.       endIf
  759.  
  760.       -- Parent process: wait for child to complete
  761.       i = Sys_Join (pid)
  762.       nl ()
  763.       Check (i, -2)
  764.  
  765.       print ("\nShould print \"An AddressException exception has occured while in user mode\"...\n")
  766.       pid = Sys_Fork ()
  767.       if pid == 0
  768.         -- Child process: cause address exception
  769.         p = 0xeeeeeee0 asPtrTo int
  770.         *p = 123
  771.         print ("*****  ERROR: Execution will not continue  *****\n")
  772.         Sys_Exit (0)
  773.       endIf
  774.  
  775.       -- Parent process: wait for child to complete
  776.       i = Sys_Join (pid)
  777.       nl ()
  778.       Check (i, -1)
  779.  
  780.       print ("\nShould print \"A PageReadonlyException exception has occured while in user mode\"...\n")
  781.       pid = Sys_Fork ()
  782.       if pid == 0
  783.         -- Child process: cause page fault
  784.         p = main asPtrTo int
  785.         *p = 123
  786.         print ("*****  ERROR: Execution will not continue  *****\n")
  787.         Sys_Exit (0)
  788.       endIf
  789.  
  790.       -- Parent process: wait for child to complete
  791.       i = Sys_Join (pid)
  792.       nl ()
  793.       Check (i, -1)
  794.  
  795.       print ("\nDone.\n")
  796.  
  797.     endFunction
  798.  
  799. -----------------------------  Check  ---------------------------------
  800.  
  801.   function Check (i, expectedVal: int)
  802.     --
  803.     -- This function is passed the return code from a syscall and
  804.     -- the expected value.  It prints an error message if it is incorrect.
  805.     --
  806.       if i == expectedVal
  807.         print ("Okay.\n")
  808.       else
  809.         print ("*****  ERROR: Return value from syscall (")
  810.         printInt (i)
  811.         print (") is incorrect  *****\n")
  812.       endIf
  813.       
  814.     endFunction
  815.  
  816.  
  817. endCode
  818.