Advertisement
Guest User

Untitled

a guest
Mar 25th, 2017
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.07 KB | None | 0 0
  1. /* Programming Assignment 3: Exercise D
  2.  *
  3.  * Now that you have a working implementation of semaphores, you can
  4.  * implement a more sophisticated synchronization scheme for the car
  5.  * simulation.
  6.  *
  7.  * Study the program below.  Car 1 begins driving over the road, entering
  8.  * from the East at 40 mph.  After 900 seconds, both Car 3 and Car 4 try to
  9.  * enter the road.  Car 1 may or may not have exited by this time (it should
  10.  * exit after 900 seconds, but recall that the times in the simulation are
  11.  * approximate).  If Car 1 has not exited and Car 4 enters, they will crash
  12.  * (why?).  If Car 1 has exited, Car 3 and Car 4 will be able to enter the
  13.  * road, but since they enter from opposite directions, they will eventually
  14.  * crash.  Finally, after 1200 seconds, Car 2 enters the road from the West,
  15.  * and traveling twice as fast as Car 4.  If Car 3 was not coming from the
  16.  * opposite direction, Car 2 would eventually reach Car 4 from the back and
  17.  * crash.  (You may wish to experiment with reducing the initial delay of
  18.  * Car 2, or increase the initial delay of Car 3, to cause Car 2 to crash
  19.  * with Car 4 before Car 3 crashes with Car 4.)
  20.  *
  21.  *
  22.  * Exercises
  23.  *
  24.  * 1. Modify the procedure driveRoad such that the following rules are obeyed:
  25.  *
  26.  *  A. Avoid all collisions.
  27.  *
  28.  *  B. Multiple cars should be allowed on the road, as long as they are
  29.  *  traveling in the same direction.
  30.  *
  31.  *  C. If a car arrives and there are already other cars traveling in the
  32.  *  SAME DIRECTION, the arriving car should be allowed enter as soon as it
  33.  *  can. Two situations might prevent this car from entering immediately:
  34.  *  (1) there is a car immediately in front of it (going in the same
  35.  *  direction), and if it enters it will crash (which would break rule A);
  36.  *  (2) one or more cars have arrived at the other end to travel in the
  37.  *  opposite direction and are waiting for the current cars on the road
  38.  *  to exit, which is covered by the next rule.
  39.  *
  40.  *  D. If a car arrives and there are already other cars traveling in the
  41.  *  OPPOSITE DIRECTION, the arriving car must wait until all these other
  42.  *  cars complete their course over the road and exit.  It should only wait
  43.  *  for the cars already on the road to exit; no new cars traveling in the
  44.  *  same direction as the existing ones should be allowed to enter.
  45.  *
  46.  *  E. This last rule implies that if there are multiple cars at each end
  47.  *  waiting to enter the road, each side will take turns in allowing one
  48.  *  car to enter and exit.  (However, if there are no cars waiting at one
  49.  *  end, then as cars arrive at the other end, they should be allowed to
  50.  *  enter the road immediately.)
  51.  *
  52.  *  F. If the road is free (no cars), then any car attempting to enter
  53.  *  should not be prevented from doing so.
  54.  *
  55.  *  G. All starvation must be avoided.  For example, any car that is
  56.  *  waiting must eventually be allowed to proceed.
  57.  *
  58.  * This must be achieved ONLY by adding synchronization and making use of
  59.  * shared memory (as described in Exercise C).  You should NOT modify the
  60.  * delays or speeds to solve the problem.  In other words, the delays and
  61.  * speeds are givens, and your goal is to enforce the above rules by making
  62.  * use of only semaphores and shared memory.
  63.  *
  64.  * 2. Devise different tests (using different numbers of cars, speeds,
  65.  * directions) to see whether your improved implementation of driveRoad
  66.  * obeys the rules above.
  67.  *
  68.  * IMPLEMENTATION GUIDELINES
  69.  *
  70.  * 1. Avoid busy waiting. In class one of the reasons given for using
  71.  * semaphores was to avoid busy waiting in user code and limit it to
  72.  * minimal use in certain parts of the kernel. This is because busy
  73.  * waiting uses up CPU time, but a blocked process does not. You have
  74.  * semaphores available to implement the driveRoad function, so you
  75.  * should not use busy waiting anywhere.
  76.  *
  77.  * 2. Prevent race conditions. One reason for using semaphores is to
  78.  * enforce mutual exclusion on critical sections to avoid race conditions.
  79.  * You will be using shared memory in your driveRoad implementation.
  80.  * Identify the places in your code where there may be race conditions
  81.  * (the result of a computation on shared memory depends on the order
  82.  * that processes execute).  Prevent these race conditions from occurring
  83.  * by using semaphores.
  84.  *
  85.  * 3. Implement semaphores fully and robustly.  It is possible for your
  86.  * driveRoad function to work with an incorrect implementation of
  87.  * semaphores, because controlling cars does not exercise every use of
  88.  * semaphores.  You will be penalized if your semaphores are not correctly
  89.  * implemented, even if your driveRoad works.
  90.  *
  91.  * 4. Control cars with semaphores: Semaphores should be the basic
  92.  * mechanism for enforcing the rules on driving cars. You should not
  93.  * force cars to delay in other ways inside driveRoad such as by calling
  94.  * the Delay function or changing the speed of a car. (You can leave in
  95.  * the delay that is already there that represents the car's speed, just
  96.  * don't add any additional delaying).  Also, you should not be making
  97.  * decisions on what cars do using calculations based on car speed (since
  98.  * there are a number of unpredictable factors that can affect the
  99.  * actual cars' progress).
  100.  *
  101.  * GRADING INFORMATION
  102.  *
  103.  * 1. Semaphores: We will run a number of programs that test your
  104.  * semaphores directly (without using cars at all). For example:
  105.  * enforcing mututal exclusion, testing robustness of your list of
  106.  * waiting processes, calling signal and wait many times to make sure
  107.  * the semaphore state is consistent, etc.
  108.  *
  109.  * 2. Cars: We will run some tests of cars arriving in different ways,
  110.  * to make sure that you correctly enforce all the rules for cars given
  111.  * in the assignment.  We will use a correct semaphore implementation for
  112.  * these tests so that even if your semaphores are not correct you could
  113.  * still get full credit on the driving part of the grade.  Think about
  114.  * how your driveRoad might handle different situations and write your
  115.  * own tests with cars arriving in different ways to make sure you handle
  116.  * all cases correctly.
  117.  *
  118.  *
  119.  * WHAT TO TURN IN
  120.  *
  121.  * You must turn in two files: mykernel3.c and p3d.c.  mykernel3.c should
  122.  * contain you implementation of semaphores, and p3d.c should contain
  123.  * your modified version of InitRoad and driveRoad (Main will be ignored).
  124.  * Note that you may set up your static shared memory struct and other
  125.  * functions as you wish. They should be accessed via InitRoad and driveRoad,
  126.  * as those are the functions that we will call to test your code.
  127.  *
  128.  * Your programs will be tested with various Main programs that will exercise
  129.  * your semaphore implementation, AND different numbers of cars, directions,
  130.  * and speeds, to exercise your driveRoad function.  Our Main programs will
  131.  * first call InitRoad before calling driveRoad.  Make sure you do as much
  132.  * rigorous testing yourself to be sure your implementations are robust.
  133.  */
  134.  
  135. #include <stdio.h>
  136. #include "aux.h"
  137. #include "sys.h"
  138. #include "umix.h"
  139.  
  140. void InitRoad (void);
  141. void driveRoad (int from, int mph);
  142.  
  143. struct {        // structure of variables to be shared
  144.     int eastGateSem;
  145.     int westGateSem;
  146.     int roadSem[NUMPOS+1];
  147.     int waitingWest;
  148.     int waitingEast;
  149.     int mtxEnter;
  150.     int mtxRoad;
  151.     int carsOnRoadFromE;
  152.     int carsOnRoadFromW;
  153. } shm;
  154.  
  155. void Main ()
  156. {
  157.     InitRoad ();
  158.  
  159.     /* The following code is specific to this particular simulation,
  160.      * e.g., number of cars, directions, and speeds.  You should
  161.      * experiment with different numbers of cars, directions, and
  162.      * speeds to test your modification of driveRoad.  When your
  163.      * solution is tested, we will use different Main procedures,
  164.      * which will first call InitRoad before any calls to driveRoad.
  165.      * So, you should do any initializations in InitRoad.
  166.      */
  167. /*
  168.     if (Fork () == 0) {
  169.         Delay (200);            // car 2
  170.         driveRoad (WEST, 80);
  171.         Exit ();
  172.     }
  173.  
  174.     if (Fork() == 0) {
  175.         Delay(1500);
  176.         driveRoad(WEST, 60);
  177.         Exit();
  178.     }
  179.  
  180.     if (Fork() == 0){
  181.         Delay(1700);
  182.         driveRoad(WEST, 80);
  183.         Exit();
  184.     }
  185.  
  186.     if (Fork() == 0) {
  187.         Delay(1800);
  188.         driveRoad(EAST, 60);
  189.         Exit();
  190.     }
  191.  
  192.     if (Fork() == 0) {
  193.         Delay(3000);
  194.         driveRoad(WEST, 60);
  195.         Exit();
  196.     }
  197.  
  198.     if (Fork() == 0) {
  199.         Delay(3300);
  200.         driveRoad(EAST, 80);
  201.         Exit();
  202.     }
  203.  
  204.     if (Fork() == 0) {
  205.         Delay(3500);
  206.         driveRoad(WEST, 60);
  207.         Exit();
  208.     }
  209.  
  210.     driveRoad (WEST, 60);           // car 1
  211. */
  212. /*
  213.     //Step 4 tests
  214.  
  215.     if (Fork() == 0) {
  216.         Delay(300);
  217.         driveRoad(WEST, 50);
  218.         Exit();
  219.     }if (Fork() == 0) {
  220.         Delay(300);
  221.         driveRoad(WEST, 50);
  222.         Exit();
  223.     }if (Fork() == 0) {
  224.         Delay(300);
  225.         driveRoad(WEST, 50);
  226.         Exit();
  227.     }
  228.  
  229.     if (Fork() == 0) {
  230.         Delay(300);
  231.         driveRoad(EAST, 50);
  232.         Exit();
  233.     }if (Fork() == 0) {
  234.         Delay(300);
  235.         driveRoad(EAST, 50);
  236.         Exit();
  237.     }if (Fork() == 0) {
  238.         Delay(300);
  239.         driveRoad(EAST, 50);
  240.         Exit();
  241.     }
  242.  
  243.     driveRoad (WEST, 60);
  244.     Exit ();
  245.     */
  246.     if (Fork () == 0) {
  247.             Delay (50);          // car 2
  248.             driveRoad (WEST, 60);
  249.             Exit ();
  250.     }
  251.  
  252.     if (Fork () == 0) {
  253.             Delay (100);         // car 3
  254.             driveRoad (EAST, 50);
  255.             Exit ();
  256.     }
  257.  
  258.     driveRoad (WEST, 10);           // car 1
  259.  
  260.     Exit ();
  261. }
  262.  
  263. /* Our tests will call your versions of InitRoad and driveRoad, so your
  264.  * solution to the car simulation should be limited to modifying the code
  265.  * below.  This is in addition to your implementation of semaphores
  266.  * contained in mykernel3.c.
  267.  */
  268.  
  269. void InitRoad ()
  270. {
  271.     /* do any initializations here */
  272.     // init some shared memory (regshm here!)
  273.     // initialize semaphores (traffic lights)
  274.     Regshm ((char *) &shm, sizeof (shm));       // register as shared
  275.  
  276.     shm.eastGateSem = Seminit(0);
  277.     shm.westGateSem = Seminit(0);
  278.     shm.mtxEnter = Seminit(1);
  279.     shm.mtxRoad = Seminit(1);
  280.     for (int i = 1; i < NUMPOS+1; i++) {
  281.         shm.roadSem[i] = Seminit(1);
  282.     }
  283.     shm.waitingWest = 0;
  284.     shm.waitingEast = 0;
  285.     shm.carsOnRoadFromE = 0;
  286.     shm.carsOnRoadFromW = 0;
  287. }
  288.  
  289. #define IPOS(FROM)  (((FROM) == WEST) ? 1 : NUMPOS)
  290.  
  291. void driveRoad (from, mph)
  292.     int from;           // coming from which direction
  293.     int mph;            // speed of car
  294. {
  295.     int c;              // car ID c = process ID
  296.     int p, np, i;           // positions
  297.  
  298.     c = Getpid ();          // learn this car's ID
  299.  
  300.     Wait(shm.mtxEnter);
  301.     if (shm.carsOnRoadFromW >= 0 && shm.carsOnRoadFromE == 0 && shm.waitingEast == 0 && from == WEST) {
  302.         shm.carsOnRoadFromW++;
  303.         EnterRoad(from);
  304.         Signal(shm.mtxEnter);
  305.     }
  306.     else if (shm.carsOnRoadFromE >= 0 && shm.carsOnRoadFromW == 0 && shm.waitingWest == 0 && from == EAST){
  307.         shm.carsOnRoadFromE++;
  308.         EnterRoad(from);
  309.         Signal(shm.mtxEnter);
  310.     }
  311.     else if ((shm.carsOnRoadFromW > 0 && from == EAST) ||
  312.                    (shm.carsOnRoadFromE > 0 && shm.waitingWest > 0 && from == EAST)) {
  313.         shm.waitingEast++;
  314.         Signal(shm.mtxEnter);
  315.         Wait(shm.eastGateSem);
  316.         shm.waitingEast--;
  317.         shm.carsOnRoadFromE++;
  318.         EnterRoad(from);
  319.     }
  320.     else if ((shm.carsOnRoadFromE > 0 && from == WEST)  ||
  321.                      (shm.carsOnRoadFromW > 0 && shm.waitingEast > 0 && from == WEST)) {
  322.         shm.waitingWest++;
  323.         Signal(shm.mtxEnter);
  324.         Wait(shm.westGateSem);
  325.         shm.waitingWest--;
  326.         shm.carsOnRoadFromW++;
  327.         EnterRoad(from);
  328.     }
  329.     else {
  330.         Signal(shm.mtxEnter);
  331.     }
  332.  
  333.     PrintRoad ();
  334.     Printf ("Car %d enters at %d at %d mph\n", c, IPOS(from), mph);
  335.     for (i = 1; i < NUMPOS; i++) {
  336.         if (from == WEST) {
  337.             p = i;
  338.             np = i + 1;
  339.         } else {
  340.             p = NUMPOS + 1 - i;
  341.             np = p - 1;
  342.         }
  343.  
  344.         Delay (3600/mph);
  345.         Wait(shm.roadSem[np]);
  346.         ProceedRoad ();
  347.         Signal(shm.roadSem[p]);
  348.         Wait(shm.mtxRoad);
  349.         PrintRoad ();
  350.         Printf ("Car %d moves from %d to %d\n", c, p, np);
  351.         Signal(shm.mtxRoad);
  352.  
  353.         if (from == WEST) {
  354.             if (shm.waitingEast == 0 && shm.waitingWest > 0) {
  355.                 Signal(shm.westGateSem);
  356.             }
  357.         }
  358.         else {
  359.             if (shm.waitingWest == 0 && shm.waitingEast > 0) {
  360.                 Signal(shm.eastGateSem);
  361.             }
  362.         }
  363.     }
  364.  
  365.     Delay (3600/mph);
  366.     ProceedRoad ();
  367.     Signal(shm.roadSem[np]);
  368.     Wait(shm.mtxRoad);
  369.     PrintRoad ();
  370.     Printf ("Car %d exits road\n", c);
  371.     if (from == WEST) {
  372.         if (--shm.carsOnRoadFromW == 0 && shm.waitingEast > 0) {
  373.             Signal(shm.eastGateSem);
  374.         }
  375.     }
  376.     else {
  377.         if (--shm.carsOnRoadFromE == 0 && shm.waitingWest > 0) {
  378.             Signal(shm.westGateSem);
  379.         }
  380.     }
  381.     Signal(shm.mtxRoad);
  382. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement