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 / version-1-0 / OSProject / p4 / Main.c < prev    next >
Text File  |  2006-04-19  |  16KB  |  473 lines

  1. code Main
  2.  
  3.   -- This is code for testing the ThreadManage, ProcessManager and FrameManager
  4.  
  5. -----------------------------  Main  ---------------------------------
  6.  
  7.   function main ()
  8.  
  9. /*
  10.  
  11.       var th0, th1, th2: ptr to Thread
  12.           proc0, proc1, proc2, proc3: ptr to ProcessControlBlock
  13.  
  14. */
  15.  
  16.       -- Initialization for testing code
  17.       uniqueNumberLock.Init ()
  18.  
  19.       -- Initialize the Thread Scheduler
  20.       InitializeScheduler ()
  21.  
  22.       -- Initialize the ProcessManager
  23.       processManager = new ProcessManager
  24.       processManager.Init ()
  25.  
  26.       -- Initialize the ThreadManager
  27.       threadManager = new ThreadManager
  28.       threadManager.Init ()
  29.  
  30.       -- Initialize the FrameManager
  31.       frameManager = new FrameManager
  32.       frameManager.Init ()
  33.  
  34. -- THE FOLLOWING CODE MAY BE USEFUL DURING TESTING, SO YOU MAY WISH TO
  35. -- UNCOMMENT AND USE ALL OR PART OF IT.  HOWEVER, FOR YOUR FINAL RUN,
  36. -- PLEASE USE THIS FILE EXACTLY AS DISTRIBUTED.
  37.  
  38. /*
  39.  
  40.       -- Print the initial state
  41.       print ("\n====================  INITIAL STATE  ====================\n\n")
  42.       threadManager.Print ()
  43.       print ("\n=========================================================\n\n")
  44.  
  45.       -- Allocate some threads
  46.       print ("\n*****  Allocating some threads  *****\n\n")
  47.       th0 = threadManager.GetANewThread()
  48.       th1 = threadManager.GetANewThread()
  49.       th2 = threadManager.GetANewThread()
  50.  
  51.       -- Rreturn one of the threads
  52.       print ("*****  Returning one thread  *****\n\n")
  53.       threadManager.FreeThread (th1)
  54.  
  55.       -- Print the new state
  56.       print ("\n====================  NEW STATE  ====================\n\n")
  57.       threadManager.Print ()
  58.       print ("\n=========================================================\n\n")
  59.  
  60.       -- Return the other threads
  61.       threadManager.FreeThread (th0)
  62.       threadManager.FreeThread (th2)
  63.  
  64.       -- Print the initial state
  65.       print ("\n====================  INITIAL STATE  ====================\n\n")
  66.       processManager.Print ()
  67.       print ("\n\n")
  68.       frameManager.Print ()
  69.       print ("\n=========================================================\n\n")
  70.  
  71.       -- Allocate some processes
  72.       print ("*****  Allocating some processes  *****\n\n")
  73.       proc0 = processManager.GetANewProcess()
  74.       proc1 = processManager.GetANewProcess()
  75.       proc2 = processManager.GetANewProcess()
  76.       proc3 = processManager.GetANewProcess()
  77.  
  78.       -- Allocate some frames
  79.       print ("*****  Allocating some frames  *****\n\n")
  80.       frameManager.GetNewFrames(&proc2.addrSpace, 3)
  81.       frameManager.GetNewFrames(&proc1.addrSpace, 2)
  82.       frameManager.GetNewFrames(&proc0.addrSpace, 5)
  83.       frameManager.GetNewFrames(&proc3.addrSpace, 1)
  84.  
  85.       -- Return one of the processes and return its frames
  86.       print ("*****  Returning one process and its frames  *****\n\n")
  87.       frameManager.ReturnAllFrames(&proc1.addrSpace)
  88.       processManager.FreeProcess (proc1)
  89.  
  90.       -- Rreturn one of the threads
  91.       print ("*****  Returning one thread  *****\n\n")
  92.       threadManager.FreeThread (th1)
  93.  
  94.       -- Print the new state
  95.       print ("\n====================  NEW STATE  ====================\n\n")
  96.       processManager.Print ()
  97.       print ("\n\n")
  98.       frameManager.Print ()
  99.       print ("\n=========================================================\n\n")
  100.  
  101.       -- Return the other processes and their frames
  102.       frameManager.ReturnAllFrames(&proc0.addrSpace)
  103.       processManager.FreeProcess (proc0)
  104.       frameManager.ReturnAllFrames(&proc2.addrSpace)
  105.       processManager.FreeProcess (proc2)
  106.       frameManager.ReturnAllFrames(&proc3.addrSpace)
  107.       processManager.FreeProcess (proc3)
  108.  
  109. */
  110.  
  111.       -- Run more thorough tests.
  112.       RunThreadManagerTests ()
  113.       RunProcessManagerTests ()
  114.       RunFrameManagerTests ()
  115.  
  116.       RuntimeExit ()
  117.  
  118.     endFunction
  119.  
  120. -----------------------------  GetUniqueNumber  ---------------------------------
  121. --
  122. -- This function returns a different number each time it is called.  It is passed
  123. -- the number of unique numbers required, in "count".  Normally, count is 1.
  124. -- If several unique numbers are needed, it can be called with a larger "count";
  125. -- In this case, the numbers
  126. --     ret, ret+1, ret+2, ... ret+count-1
  127. -- will all be unique numbers that can be used.
  128. --
  129.   var uniqueNumberLock: Mutex = new Mutex
  130.       nextUnique: int = 1
  131.  
  132.   function GetUniqueNumber (count: int) returns int
  133.       var i: int
  134.       uniqueNumberLock.Lock ()
  135.       i = nextUnique
  136.       nextUnique = nextUnique + count
  137.       uniqueNumberLock.Unlock ()
  138.       return i
  139.     endFunction
  140.  
  141. -----------------------------  Misc  ---------------------------------
  142. --
  143. -- These are used by various testing functions.
  144. --
  145.   const NUM_THREADS = 20
  146.         WAIT_TIME = 10
  147.         NUMBER_ITERATIONS = 20
  148.  
  149.   var allDone: Semaphore = new Semaphore
  150.       freeze: Semaphore = new Semaphore
  151.  
  152. -----------------------------  RunThreadManagerTests  ---------------------------------
  153. --
  154. -- This function tests the ThreadManager.  It creates a bunch of threads
  155. -- (NUM_THREADS) and starts each thread running.  Each thread will execute
  156. -- the "TestThreadManager" function.  The main thread will then wait until all
  157. -- the threads complete.  To control this, there is a single Semaphore "allDone".
  158. -- Each TestThreadManager thread signals it and the main thread will wait
  159. -- for NUM-THREAD times, i.e., until all threads have finished.
  160. --
  161. -- Each TestThreadManager does basically this:
  162. --        loop NUMBER_ITERATIONS times
  163. --           call GetANewThread
  164. --           wait
  165. --           call FreeThread
  166. --           wait
  167. --        endLoop
  168. --
  169.   function RunThreadManagerTests ()
  170.       var i: int
  171.           th: ptr to Thread
  172.  
  173.       allDone.Init (0)
  174.       freeze.Init (0)
  175.       uniqueNumberLock.Init ()
  176.       nextUnique = 1
  177.  
  178.       print ("\n\n*****  THREAD-MANAGER TEST  *****\n\n")
  179.  
  180.       for i = 1 to NUM_THREADS
  181.         th = alloc Thread
  182.         th.Init ("TestThreadManager")
  183.         th.Fork (TestThreadManager, i)
  184.       endFor
  185.  
  186.       -- Wait for all the testing threads to complete.
  187.       -- (Make sure you see the completion message!)
  188.       for i = 1 to NUM_THREADS
  189.         allDone.Wait ()
  190.       endFor
  191.  
  192.       if GetUniqueNumber (1) != NUM_THREADS * NUMBER_ITERATIONS + 1
  193.         FatalError ("Concurrency control failure (1)")
  194.       endIf
  195.       print ("\n\n***** THREAD-MANAGER TEST COMPLETED SUCCESSFULLY *****\n\n")
  196.  
  197.     endFunction
  198.  
  199. -----------------------------  TestThreadManager  ---------------------------------
  200. --
  201. -- This function is the main function for a thread which will test the
  202. -- ThreadManager.  It will request and return Thread objects.  First, it
  203. -- grabs a unique number and stuffs it in the Thread.  Later, it makes sure that
  204. -- the number is unchanged.  It could only have changed if some other tester
  205. -- was allowed to access this Thread object before this tester returned it.
  206. --
  207.   function TestThreadManager (myID: int)
  208.       var i, j, e: int
  209.           th: ptr to Thread
  210.       -- printIntVar ("Thread started", myID)
  211.       for i = 1 to NUMBER_ITERATIONS
  212.         printInt (myID)
  213.         e = GetUniqueNumber (1)
  214.         th = threadManager.GetANewThread ()
  215.         th.regs[0] = e
  216.         for j = 1 to WAIT_TIME+i
  217.           currentThread.Yield ()
  218.         endFor
  219.         if e != th.regs[0]
  220.           FatalError ("Concurrency control failure (2)")
  221.         endIf
  222.         printChar ('.')
  223.         threadManager.FreeThread (th)
  224.         for j = 1 to WAIT_TIME-i
  225.           currentThread.Yield ()
  226.         endFor
  227.       endFor
  228.       allDone.Signal ()
  229.       freeze.Wait ()
  230.     endFunction
  231.  
  232. -----------------------------  RunProcessManagerTests  ---------------------------------
  233. --
  234. -- This function tests the ProcessManager.  It creates a bunch of tester threads
  235. -- (NUM_THREADS) and starts each thread running.  Each tester thread will execute
  236. -- the "TestProcessManager" function.  The main thread will then wait until all
  237. -- the testers complete.  To control this, there is a single Semaphore "allDone".
  238. -- Each TestProcessManager thread signals it and the main thread will wait
  239. -- for NUM-THREAD times, i.e., until all tester threads have finished.
  240. --
  241. -- Each TestProcessManager does basically this:
  242. --        loop NUMBER_ITERATIONS times
  243. --           call GetANewProcess
  244. --           wait
  245. --           call FreeProcess
  246. --           wait
  247. --        endLoop
  248. --
  249.   function RunProcessManagerTests ()
  250.       var i: int
  251.           th: ptr to Thread
  252.  
  253.       allDone.Init (0)
  254.       freeze.Init (0)
  255.       uniqueNumberLock.Init ()
  256.       nextUnique = 1
  257.  
  258.       print ("\n\n*****  PROCESS-MANAGER TEST  *****\n\n")
  259.  
  260.       for i = 1 to NUM_THREADS
  261.         th = alloc Thread
  262.         th.Init ("TestProcessManager")
  263.         th.Fork (TestProcessManager, i)
  264.       endFor
  265.  
  266.       -- Wait for all the testing threads to complete.
  267.       -- (Make sure you see the completion message!)
  268.       for i = 1 to NUM_THREADS
  269.         allDone.Wait ()
  270.       endFor
  271.  
  272.       if GetUniqueNumber (1) != NUM_THREADS * NUMBER_ITERATIONS + 1
  273.         FatalError ("Concurrency control failure (1)")
  274.       endIf
  275.       print ("\n\n***** PROCESS-MANAGER TEST COMPLETED SUCCESSFULLY *****\n\n")
  276.  
  277.     endFunction
  278.  
  279. -----------------------------  TestProcessManager  ---------------------------------
  280. --
  281. -- This function is the main function for a thread which will test the
  282. -- ProcessManager.  It will request and return ProcessControlBlocks.  First, it
  283. -- grabs a unique number and stuffs it in the PCB.  Later, it makes sure that
  284. -- the number is unchanged.  It could only have changed if some other tester
  285. -- was also allowed to access this ProcessContolBlock  before this tester
  286. -- returned it.
  287. --
  288.   function TestProcessManager (myID: int)
  289.       var i, j, e: int
  290.           pcb: ptr to ProcessControlBlock
  291.       -- printIntVar ("Thread started", myID)
  292.       for i = 1 to NUMBER_ITERATIONS
  293.         printInt (myID)
  294.         e = GetUniqueNumber (1)
  295.         pcb = processManager.GetANewProcess ()
  296.         pcb.exitStatus = e
  297.         for j = 1 to WAIT_TIME+i
  298.           currentThread.Yield ()
  299.         endFor
  300.         if e != pcb.exitStatus
  301.           FatalError ("Concurrency control failure (2)")
  302.         endIf
  303.         printChar ('.')
  304.         processManager.FreeProcess (pcb)
  305.         for j = 1 to WAIT_TIME-i
  306.           currentThread.Yield ()
  307.         endFor
  308.       endFor
  309.       allDone.Signal ()
  310.       freeze.Wait ()
  311.     endFunction
  312.  
  313. -----------------------------  RunFrameManagerTests  ---------------------------------
  314. --
  315. -- This function tests the FrameManager.  It creates one thread
  316. -- for each ProcessControlBlock.  Each thread will execute
  317. -- the "TestFrameManager" function.  The main thread will then wait until all
  318. -- the threads complete.  To control this, there is a single Semaphore "allDone2".
  319. -- Each TestFrameManager thread signals it and the main thread will wait
  320. -- for NUM-THREAD times, i.e., until all threads have finished.
  321. -- We also keep track of how many times each frame is used and print this
  322. -- data (as a histogram) after all the threads have finished.
  323. --
  324.   const WAIT_TIME2 = 5
  325.         NUMBER_ITERATIONS_2 = 5
  326.  
  327.   var allDone2: Semaphore = new Semaphore
  328.       histogram: array [NUMBER_OF_PHYSICAL_PAGE_FRAMES] of int =
  329.                     new array of int {NUMBER_OF_PHYSICAL_PAGE_FRAMES of 0 }
  330.  
  331.   function RunFrameManagerTests ()
  332.       var i,j : int
  333.           th: ptr to Thread
  334.  
  335.       allDone2.Init (0)
  336.       freeze.Init (0)
  337.  
  338.       print ("\n\n*****  FRAME-MANAGER TEST  *****\n\n")
  339.       
  340.       for i = 1 to MAX_NUMBER_OF_PROCESSES
  341.         th = alloc Thread
  342.         th.Init ("TestFrameManager")
  343.         th.Fork (TestFrameManager, i)
  344.       endFor
  345.  
  346.       -- Wait for all the testing threads to complete.
  347.       -- (Make sure you see the completion message!)
  348.       for i = 1 to MAX_NUMBER_OF_PROCESSES
  349.         allDone2.Wait ()
  350.       endFor
  351.  
  352.       print ("\n\nHere is a histogram showing how many times each frame was used:\n")
  353.       for i = 0 to NUMBER_OF_PHYSICAL_PAGE_FRAMES-1
  354.         print ("  ")
  355.         printInt (i)
  356.         print (":  ")
  357.         for j = 0 to histogram[i]
  358.           printChar ('*')
  359.         endFor
  360.         nl ()
  361.       endFor
  362.  
  363.       print ("\n\n***** FRAME-MANAGER TEST COMPLETED SUCCESSFULLY *****\n\n")
  364.  
  365.     endFunction
  366.  
  367. -----------------------------  TestFrameManager  ---------------------------------
  368. --
  369. -- This function is the main function for a thread which will test the
  370. -- FrameManager.
  371. --
  372. -- Each TestFrameManager does basically this:
  373. --        get a PCB
  374. --        loop NUMBER_ITERATIONS_2 times
  375. --           for sz = 1, 2, 3, ... MAX
  376. --             call GetNewFrames to get "sz" frames
  377. --             check to make sure the pageTable looks good
  378. --                    and store some data in the frames
  379. --             wait
  380. --             check to make sure the data we stored is still
  381. --                    in the frames
  382. --             call ReturnAllFrames
  383. --             wait
  384. --           endFor
  385. --        endLoop
  386. --
  387.   function TestFrameManager (myID: int)
  388.      var i, j, newData, sz: int
  389.          pcb: ptr to ProcessControlBlock
  390.       -- printIntVar ("Thread started", myID)
  391.       pcb = processManager.GetANewProcess ()
  392.       for i = 1 to NUMBER_ITERATIONS_2
  393.         for sz = 1 to MAX_PAGES_PER_VIRT_SPACE-1
  394.           printInt (myID)
  395.           newData = GetUniqueNumber (sz)
  396.           frameManager.GetNewFrames (&pcb.addrSpace, sz)
  397.           CheckAddrSpace (&pcb.addrSpace, sz, newData)
  398.           for j = 1 to WAIT_TIME+i
  399.             currentThread.Yield ()
  400.           endFor
  401.           printChar ('.')
  402.           CheckAddrSpace2 (&pcb.addrSpace, sz, newData)
  403.           frameManager. ReturnAllFrames (&pcb.addrSpace)
  404.           for j = 1 to WAIT_TIME-i
  405.             currentThread.Yield ()
  406.           endFor
  407.         endFor
  408.       endFor
  409.       allDone2.Signal ()
  410.       processManager.FreeProcess (pcb)
  411.       freeze.Wait ()
  412.     endFunction
  413.  
  414. -----------------------------  CheckAddrSpace  ---------------------------------
  415. --
  416. -- This function is passed a pointer to an address space.  It checks to make
  417. -- sure that it looks good.  It also stores some data in each of the frames.
  418. --
  419.   function CheckAddrSpace (addrSpace: ptr to AddrSpace, n: int, uniq: int)
  420.       var i, frameAddr, frameNumber: int
  421.       if addrSpace.numberOfPages != n
  422.         FatalError ("addrSpace.numberOfPages is wrong")
  423.       endIf
  424.       for i = 0 to n-1
  425.         frameAddr = addrSpace.ExtractFrameAddr (i)
  426.         frameNumber = (frameAddr - PHYSICAL_ADDRESS_OF_FIRST_PAGE_FRAME) / PAGE_SIZE
  427.         -- printIntVar ("frameNumber", frameNumber)
  428.         if frameNumber < 0 ||
  429.            frameNumber >= NUMBER_OF_PHYSICAL_PAGE_FRAMES ||
  430.            frameAddr % PAGE_SIZE != 0
  431.           FatalError ("Bad frame number in some addr space")
  432.         endIf
  433.         histogram[frameNumber] = histogram[frameNumber] + 1
  434.         if addrSpace.ExtractUndefinedBits (i) != 0 ||
  435.            addrSpace.IsDirty (i) ||
  436.            addrSpace.IsReferenced (i) ||
  437.            ! addrSpace.IsWritable (i) ||
  438.            ! addrSpace. IsValid (i)
  439.           FatalError ("Problems with bits in some page table entry")
  440.         endIf
  441.         * (frameAddr asPtrTo int) = uniq + i
  442.       endFor
  443.     endFunction
  444.  
  445. -----------------------------  CheckAddrSpace2  ---------------------------------
  446. --
  447. -- This function is passed a pointer to an address space.  It checks to make
  448. -- sure that the data we stored in the frame earlier is still there.  The only
  449. -- way it might have gotten corrupted is if some other thread also used this
  450. -- frame.
  451. --
  452.   function CheckAddrSpace2 (addrSpace: ptr to AddrSpace, n: int, uniq: int)
  453.       var i, frameAddr, frameNumber: int
  454.       if addrSpace.numberOfPages != n
  455.         FatalError ("addrSpace.numberOfPages is wrong")
  456.       endIf
  457.       for i = 0 to n-1
  458.         frameAddr = addrSpace.ExtractFrameAddr (i)
  459.         frameNumber = (frameAddr - PHYSICAL_ADDRESS_OF_FIRST_PAGE_FRAME) / PAGE_SIZE
  460.         -- printIntVar ("frameNumber", frameNumber)
  461.         if frameNumber < 0 ||
  462.            frameNumber >= NUMBER_OF_PHYSICAL_PAGE_FRAMES ||
  463.            frameAddr % PAGE_SIZE != 0
  464.           FatalError ("Bad frame number in some addr space")
  465.         endIf
  466.         if * (frameAddr asPtrTo int) != uniq + i
  467.           FatalError ("Data corruption, indicating that frame was shared")
  468.         endIf
  469.       endFor
  470.     endFunction
  471.  
  472. endCode
  473.