Advertisement
Guest User

call me daddy

a guest
Feb 24th, 2020
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.31 KB | None | 0 0
  1. /*
  2. * stoplight.c
  3. *
  4. * You can use any synchronization primitives available to solve
  5. * the stoplight problem in this file.
  6. */
  7.  
  8.  
  9. /*
  10. *
  11. * Includes
  12. *
  13. */
  14.  
  15. #include <types.h>
  16. #include <lib.h>
  17. #include <test.h>
  18. #include <thread.h>
  19. #include <synch.h>
  20.  
  21. /*
  22. * Number of cars created.
  23. */
  24.  
  25. #define NCARS 20
  26. #define STRAIGHT 2
  27. #define RIGHT 1
  28. #define LEFT 3
  29.  
  30. #define goS 1
  31. #define goR 2
  32. #define goL 3
  33.  
  34. static struct lock *SWlock;
  35. static struct lock *SElock;
  36. static struct lock *NWlock;
  37. static struct lock *NElock;
  38.  
  39. static void
  40. printRealMessage(int numOfRegionsPassed, int carnumber, int cardirection, int destdirection);
  41. static void
  42. checkLocksIntersections(struct lock *lock1, struct lock *lock2, struct lock *lock3, int numOfRegionsPassed, int carnumber, int cardirection, int destdirection);
  43. int
  44. calculateDesDirection(int cardirection, int turn);
  45. /*
  46. *
  47. * Function Definitions
  48. *
  49. */
  50.  
  51. static const char *directions[] = { "N", "E", "S", "W" };
  52.  
  53. static const char *msgs[] = {
  54. "approaching:",
  55. "region1: ",
  56. "region2: ",
  57. "region3: ",
  58. "leaving: "
  59. };
  60.  
  61. /* use these constants for the first parameter of message */
  62. enum { APPROACHING, REGION1, REGION2, REGION3, LEAVING };
  63.  
  64. static void
  65. message(int msg_nr, int carnumber, int cardirection, int destdirection)
  66. {
  67. kprintf("%s car = %2d, direction = %s, destination = %s\n",
  68. msgs[msg_nr], carnumber,
  69. directions[cardirection], directions[destdirection]);
  70. }
  71.  
  72. /*
  73. * gostraight()
  74. *
  75. * Arguments:
  76. * unsigned long cardirection: the direction from which the car
  77. * approaches the intersection.
  78. * unsigned long carnumber: the car id number for printing purposes.
  79. *
  80. * Returns:
  81. * nothing.
  82. *
  83. * Notes:
  84. * This function should implement passing straight through the
  85. * intersection from any direction.
  86. * Write and comment this function.
  87. */
  88.  
  89. static
  90. void
  91. gostraight(unsigned long cardirection,
  92. unsigned long carnumber)
  93. {
  94. int destdirection;
  95.  
  96. destdirection = calculateDesDirection(cardirection, goS);
  97.  
  98. if (cardirection == 0)
  99. checkLocksIntersections(NWlock, SWlock, NULL, STRAIGHT, carnumber, cardirection, destdirection);
  100. else if (cardirection == 1)
  101. checkLocksIntersections(NWlock, NElock, NULL, STRAIGHT, carnumber, cardirection, destdirection);
  102. else if (cardirection == 2)
  103. checkLocksIntersections(NElock, SElock, NULL, STRAIGHT, carnumber, cardirection, destdirection);
  104. else if (cardirection == 3)
  105. checkLocksIntersections(SWlock, SElock, NULL, STRAIGHT, carnumber, cardirection, destdirection);
  106.  
  107.  
  108.  
  109. /*
  110. * Avoid unused variable warnings.
  111. */
  112.  
  113. // (void) cardirection;
  114. // (void) carnumber;
  115. }
  116.  
  117.  
  118. /*
  119. * turnleft()
  120. *
  121. * Arguments:
  122. * unsigned long cardirection: the direction from which the car
  123. * approaches the intersection.
  124. * unsigned long carnumber: the car id number for printing purposes.
  125. *
  126. * Returns:
  127. * nothing.
  128. *
  129. * Notes:
  130. * This function should implement making a left turn through the
  131. * intersection from any direction.
  132. * Write and comment this function.
  133. */
  134.  
  135. static
  136. void
  137. turnleft(unsigned long cardirection,
  138. unsigned long carnumber)
  139. {
  140. int destdirection;
  141.  
  142. destdirection = calculateDesDirection(cardirection, goL);
  143.  
  144. if (cardirection == 0)
  145. checkLocksIntersections(NWlock, SWlock, SElock, LEFT, carnumber, cardirection, destdirection);
  146. else if (cardirection == 1)
  147. checkLocksIntersections(NWlock, NElock, SWlock, LEFT, carnumber, cardirection, destdirection);
  148. else if (cardirection == 2)
  149. checkLocksIntersections(NWlock, NElock, SElock, LEFT, carnumber, cardirection, destdirection);
  150. else if (cardirection == 3)
  151. checkLocksIntersections(NElock, SWlock, SElock, LEFT, carnumber, cardirection, destdirection);
  152.  
  153.  
  154.  
  155.  
  156. /*
  157. * Avoid unused variable warnings.
  158. */
  159.  
  160. // (void) cardirection;
  161. // (void) carnumber;
  162. }
  163.  
  164.  
  165. /*
  166. * turnright()
  167. *
  168. * Arguments:
  169. * unsigned long cardirection: the direction from which the car
  170. * approaches the intersection.
  171. * unsigned long carnumber: the car id number for printing purposes.
  172. *
  173. * Returns:
  174. * nothing.
  175. *
  176. * Notes:
  177. * This function should implement making a right turn through the
  178. * intersection from any direction.
  179. * Write and comment this function.
  180. */
  181.  
  182. static
  183. void
  184. turnright(unsigned long cardirection,
  185. unsigned long carnumber)
  186. {
  187.  
  188. int destdirection;
  189.  
  190. destdirection = calculateDesDirection(cardirection, goR);
  191.  
  192. if (cardirection == 0)
  193. checkLocksIntersections(NWlock, NULL, NULL, RIGHT, carnumber, cardirection, destdirection);
  194. else if (cardirection == 1)
  195. checkLocksIntersections(NElock, NULL, NULL, RIGHT, carnumber, cardirection, destdirection);
  196. else if (cardirection == 2)
  197. checkLocksIntersections(SElock, NULL, NULL, RIGHT, carnumber, cardirection, destdirection);
  198. else if (cardirection == 3)
  199. checkLocksIntersections(SWlock, NULL, NULL, RIGHT, carnumber, cardirection, destdirection);
  200.  
  201.  
  202. /*
  203. * Avoid unused variable warnings.
  204. */
  205.  
  206. // (void) cardirection;
  207. // (void) carnumber;
  208. }
  209.  
  210.  
  211. /*
  212. * approachintersection()
  213. *
  214. * Arguments:
  215. * void * unusedpointer: currently unused.
  216. * unsigned long carnumber: holds car id number.
  217. *
  218. * Returns:
  219. * nothing.
  220. *
  221. * Notes:
  222. * Change this function as necessary to implement your solution. These
  223. * threads are created by createcars(). Each one must choose a direction
  224. * randomly, approach the intersection, choose a turn randomly, and then
  225. * complete that turn. The code to choose a direction randomly is
  226. * provided, the rest is left to you to implement. Making a turn
  227. * or going straight should be done by calling one of the functions
  228. * above.
  229. */
  230.  
  231. static
  232. void
  233. approachintersection(void * unusedpointer,
  234. unsigned long carnumber)
  235. {
  236. int cardirection;
  237. int turn;
  238. /*
  239. * Avoid unused variable and function warnings.
  240. */
  241.  
  242. (void) unusedpointer;
  243. //(void) carnumber;
  244. // (void) gostraight;
  245. // (void) turnleft;
  246. // (void) turnright;
  247.  
  248. /*
  249. * cardirection is set randomly.
  250. */
  251.  
  252. cardirection = random() % 4;
  253. turn = random() % 3;
  254.  
  255. if (turn == 0)
  256. turnright(cardirection , carnumber);
  257.  
  258. else if (turn == 1)
  259. turnleft(cardirection , carnumber);
  260.  
  261. else
  262. gostraight(cardirection , carnumber);
  263. }
  264.  
  265. static void
  266. printRealMessage(int numOfRegionsPassed, int carnumber, int cardirection, int destdirection){
  267. int i;
  268.  
  269. if (numOfRegionsPassed == 1) {// right turn
  270. for(i = 0; i <= numOfRegionsPassed; i++)
  271. message(i, carnumber, cardirection, destdirection);
  272. message(4,carnumber, cardirection, destdirection);
  273. }
  274.  
  275. else if (numOfRegionsPassed == 2){// straight way{
  276. for(i = 0; i <= numOfRegionsPassed; i++)
  277. message(i, carnumber, cardirection, destdirection);
  278. message(4,carnumber, cardirection, destdirection);
  279. }
  280.  
  281. else{
  282. for(i = 0; i <= (numOfRegionsPassed + 1) ; i++)
  283. message(i, carnumber, cardirection, destdirection);
  284. //message(4,carnumber, cardirection, destdirection);
  285. }
  286. }
  287.  
  288. static void
  289. checkLocksIntersections(struct lock *lock1, struct lock *lock2, struct lock *lock3, int numOfRegionsPassed, int carnumber, int cardirection, int destdirection){
  290.  
  291. assert(lock1);
  292.  
  293. lock_acquire(lock1);
  294. // assert(lock2);
  295. if(lock2)//lock_do_i_hold(lock2))
  296. lock_acquire(lock2);
  297. // assert(lock3);
  298. if(lock3)//lock_do_i_hold(lock3))
  299. lock_acquire(lock3);
  300. printRealMessage(numOfRegionsPassed, carnumber, cardirection, destdirection);
  301. if (lock3)
  302. lock_release(lock3);
  303. if (lock2)
  304. lock_release(lock2);
  305. lock_release(lock1);
  306. }
  307.  
  308. int
  309. calculateDesDirection(int cardirection, int turn){
  310.  
  311. int desdirection;
  312. if (turn == 1)
  313. desdirection = (cardirection + 2) % 4;
  314. else if(turn == 2)
  315. desdirection = (cardirection + 3) % 4;
  316. else if(turn == 3)
  317. desdirection = (cardirection + 1) % 4;
  318.  
  319. return desdirection;
  320. }
  321.  
  322.  
  323. /*
  324. * createcars()
  325. *
  326. * Arguments:
  327. * int nargs: unused.
  328. * char ** args: unused.
  329. *
  330. * Returns:
  331. * 0 on success.
  332. *
  333. * Notes:
  334. * Driver code to start up the approachintersection() threads. You are
  335. * free to modiy this code as necessary for your solution.
  336. */
  337.  
  338. int
  339. createcars(int nargs,
  340. char ** args)
  341. {
  342. int index, error;
  343.  
  344.  
  345. NWlock = lock_create("NWlock");
  346. NElock = lock_create("NElock");
  347. SWlock = lock_create("SWlock");
  348. SElock = lock_create("SElock");
  349. /*
  350. * Start NCARS approachintersection() threads.
  351. */
  352.  
  353. for (index = 0; index < NCARS; index++) {
  354. error = thread_fork("approachintersection thread",
  355. NULL, index, approachintersection, NULL);
  356.  
  357. /*
  358. * panic() on error.
  359. */
  360.  
  361. if (error) {
  362. panic("approachintersection: thread_fork failed: %s\n",
  363. strerror(error));
  364. }
  365. }
  366.  
  367. /*
  368. * wait until all other threads finish
  369. */
  370.  
  371. while (thread_count() > 1)
  372. thread_yield();
  373.  
  374. (void)message;
  375. (void)nargs;
  376. (void)args;
  377. kprintf("stoplight test done\n");
  378. return 0;
  379. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement