Advertisement
Guest User

lolers

a guest
Mar 25th, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.41 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.  
  144.  
  145.  
  146. struct{
  147. int positions[NUMPOS + 1];
  148. int east;
  149. int west;
  150. int mutex;
  151. int mutexPrint;
  152. int waitingWest;
  153. int waitingEast;
  154. int numCarsWest;
  155. int numCarsEast;
  156. }shm;
  157. void Main ()
  158. {
  159. InitRoad ();
  160.  
  161. /* The following code is specific to this particular simulation,
  162. * e.g., number of cars, directions, and speeds. You should
  163. * experiment with different numbers of cars, directions, and
  164. * speeds to test your modification of driveRoad. When your
  165. * solution is tested, we will use different Main procedures,
  166. * which will first call InitRoad before any calls to driveRoad.
  167. * So, you should do any initializations in InitRoad.
  168. */
  169. if(Fork() == 0){
  170. Delay(50);
  171. driveRoad(WEST,50);
  172. Exit();
  173. }
  174. if(Fork() == 0){
  175. Delay(100);
  176. driveRoad(EAST,50);
  177. Exit();
  178. }
  179. /*
  180. if(Fork() == 0){
  181. Delay(300);
  182. driveRoad(WEST,50);
  183. Exit();
  184. }
  185. if(Fork() == 0){
  186. Delay(300);
  187. driveRoad(EAST,50);
  188. Exit();
  189. }
  190. if(Fork() == 0){
  191. Delay(300);
  192. driveRoad(EAST,50);
  193. Exit();
  194. }
  195. if(Fork() == 0){
  196. Delay(300);
  197. driveRoad(EAST,50);
  198. Exit();
  199. }
  200. */
  201. driveRoad(WEST,10);
  202.  
  203.  
  204. }
  205.  
  206. /* Our tests will call your versions of InitRoad and driveRoad, so your
  207. * solution to the car simulation should be limited to modifying the code
  208. * below. This is in addition to your implementation of semaphores
  209. * contained in mykernel3.c.
  210. */
  211.  
  212. void InitRoad ()
  213. {
  214. /* do any initializations here */
  215. Regshm((char *) &shm, sizeof(shm));
  216. int i;
  217. for(i = 1; i < NUMPOS + 1;i++){
  218. shm.positions[i] = Seminit(1);
  219. }
  220. shm.east = Seminit(0);
  221. shm.west = Seminit(0);
  222. shm.mutex = Seminit(1);
  223. shm.mutexPrint = Seminit(1);
  224. shm.waitingWest = 0;
  225. shm.waitingEast = 0;
  226. shm.numCarsWest = 0;
  227. shm.numCarsEast = 0;
  228. }
  229.  
  230. #define IPOS(FROM) (((FROM) == WEST) ? 1 : NUMPOS)
  231.  
  232. void driveRoad (from, mph)
  233. int from; // coming from which direction
  234. int mph; // speed of car
  235. {
  236. int c; // car ID c = process ID
  237. int p, np, i; // positions
  238.  
  239. c = Getpid (); // learn this car's ID
  240.  
  241. /*Add car to the road if there are no cars in the road.*/
  242. /*Increment num of cars on the road.*/
  243. Wait(shm.mutex);
  244. if(shm.numCarsWest >= 0 && shm.numCarsEast == 0 && shm.waitingEast == 0 && from == WEST){
  245. shm.numCarsWest++;
  246. EnterRoad(from);
  247. Signal(shm.mutex);
  248. }
  249. else if(shm.numCarsEast >= 0 && shm.numCarsWest== 0 && shm.waitingWest == 0 && from == EAST)
  250. {
  251. shm.numCarsEast++;
  252. EnterRoad(from);
  253. Signal(shm.mutex);
  254. }
  255. else if((shm.numCarsWest > 0 && from == EAST) ||
  256. (shm.numCarsEast > 0 && shm.waitingWest > 0 && from == EAST)){
  257. shm.waitingEast++;
  258. Signal(shm.mutex);
  259. Wait(shm.east);
  260. EnterRoad(from);
  261. }
  262. else if((shm.numCarsEast > 0 && from == WEST) ||
  263. (shm.numCarsWest > 0 && shm.waitingEast > 0 && from == WEST)){
  264. shm.waitingWest++;
  265. Signal(shm.mutex);
  266. Wait(shm.west);
  267. EnterRoad(from);
  268. }
  269. else{
  270. Signal(shm.mutex);
  271. }
  272.  
  273. PrintRoad ();
  274. Printf ("Car %d enters at %d at %d mph\n", c, IPOS(from), mph);
  275.  
  276.  
  277. for (i = 1; i < NUMPOS; i++) {
  278. if (from == WEST) {
  279. p = i;
  280. np = i + 1;
  281.  
  282. } else {
  283. p = NUMPOS + 1 - i;
  284. np = p - 1;
  285. }
  286.  
  287. Delay (3600/mph);
  288. Wait(shm.positions[np]);
  289. ProceedRoad ();
  290. Signal(shm.positions[p]);
  291.  
  292. Wait(shm.mutexPrint);
  293. PrintRoad ();
  294. Printf ("Car %d moves from %d to %d\n", c, p, np);
  295. Signal(shm.mutexPrint);
  296.  
  297. if(from == WEST){
  298. if(shm.waitingEast == 0){
  299. if(shm.waitingWest > 0){
  300. shm.waitingWest--;
  301. shm.numCarsWest++;
  302. Signal(shm.west);
  303.  
  304. }
  305. }
  306. }
  307. else{
  308. if(shm.waitingWest == 0){
  309. if(shm.waitingEast > 0){
  310. shm.waitingEast--;
  311. shm.numCarsEast++;
  312. Signal(shm.east);
  313. }
  314. }
  315. }
  316. }
  317. Delay (3600/mph);
  318. ProceedRoad ();
  319. Signal(shm.positions[np]);
  320. Wait(shm.mutexPrint);
  321.  
  322. PrintRoad ();
  323. Printf ("Car %d exits road\n", c);
  324. if(from == WEST){
  325. shm.numCarsWest--;
  326.  
  327. }
  328. else if(from == EAST){
  329. shm.numCarsEast--;
  330. }
  331. if(shm.numCarsWest == 0 && shm.waitingEast > 0 && from == WEST){
  332. shm.waitingEast--;
  333. shm.numCarsEast++;
  334. Signal(shm.east);
  335. }
  336. else if(shm.numCarsEast == 0 && shm.waitingWest > 0 && from == EAST){
  337. shm.waitingWest--;
  338. shm.numCarsWest++;
  339. Signal(shm.west);
  340. }
  341. Signal(shm.mutexPrint);
  342. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement