traffic_synch.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. #include <types.h>
  2. #include <lib.h>
  3. #include <synchprobs.h>
  4. #include <synch.h>
  5. #include <opt-A1.h>
  6. /*
  7. * This simple default synchronization mechanism allows only vehicle at a time
  8. * into the intersection. The intersectionSem is used as a a lock.
  9. * We use a semaphore rather than a lock so that this code will work even
  10. * before locks are implemented.
  11. */
  12. /*
  13. * Replace this default synchronization mechanism with your own (better) mechanism
  14. * needed for your solution. Your mechanism may use any of the available synchronzation
  15. * primitives, e.g., semaphores, locks, condition variables. You are also free to
  16. * declare other global variables if your solution requires them.
  17. */
  18. /*
  19. * replace this with declarations of any synchronization and other variables you need here
  20. */
  21. static struct semaphore * intersectionSem;
  22. static struct lock * globlock;
  23. static struct semaphore * nsem;
  24. static struct semaphore * esem;
  25. static struct semaphore * ssem;
  26. static struct semaphore * ssem;
  27. // This section contains global vars and useful functions to work with them. As well as the structs used for them
  28. typedef struct car
  29. {
  30. Direction origin;
  31. Direction dest;
  32. bool old;
  33. car * next;
  34. } car;
  35. typedef struct list
  36. {
  37. car * front;
  38. car * back;
  39. } list;
  40. list * queue = NULL;
  41. list * active = NULL;
  42. // car initializer/allocator
  43. car * newcar(Direction origin, Direction dest)
  44. {
  45. car * temp = kmalloc(sizeof(car));
  46. if(!(temp))
  47. {
  48. kprintf("Failed to create a car.");
  49. panic();
  50. }
  51. temp->origin = origin;
  52. temp->dest = dest;
  53. temp->old = 0;
  54. temp->next = NULL;
  55. }
  56. // list initializer/allocator
  57. list * newlist()
  58. {
  59. list * temp = kmalloc(sizeof(list));
  60. if(!(temp))
  61. {
  62. kprintf("Could not allocate list.");
  63. panic();
  64. }
  65. temp->front = NULL;
  66. temp->back = NULL;
  67. }
  68. // puts a car into the queue, at the front if front is true, the back otherwise
  69. void enqueue(car * newcar, bool front)
  70. {
  71. if (!(queue->back))
  72. {
  73. queue->front = newcar;
  74. queue->back = newcar;
  75. }
  76. if (front)
  77. {
  78. car * temp = queue->front;
  79. queue->front = newcar;
  80. newcar->next = temp;
  81. return;
  82. }
  83. queue->back->next = newcar;
  84. queue->back = newcar;
  85. }
  86. // push a car to the end of the active list
  87. void push(car * newcar)
  88. {
  89. if (!(active->front))
  90. {
  91. active->front = newcar;
  92. active->back = newcar;
  93. }
  94. active->back->next = newcar;
  95. active->back = newcar;
  96. }
  97. // remove an element from the front of the queue
  98. car * pop()
  99. {
  100. if (!(queue->front))
  101. {
  102. return NULL;
  103. }
  104. if (queue->front == queue->back)
  105. {
  106. queue->back == NULL;
  107. }
  108. car * temp = queue->front;
  109. queue->front = queue->front->next;
  110. return temp;
  111. }
  112. // called when a car clears the intersection
  113. void clearint(car * done)
  114. {
  115. car * temp = active->front();
  116. car * temp2 = NULL;
  117. while(temp != done)
  118. {
  119. temp = active->next;
  120. temp2 = temp;
  121. }
  122. // first element of the list is being removed
  123. if (!(temp2))
  124. {
  125. active->front = active->front->next;
  126. goto SKIP1;
  127. }
  128. temp2->next = temp->next;
  129. SKIP1:
  130. kfree(temp);
  131. }
  132. // cleans up a list
  133. void dellist(list * dead)
  134. {
  135. car * temp = dead->front;
  136. while (temp)
  137. {
  138. car * temp2 = temp->next;
  139. kfree(temp);
  140. temp = temp2;
  141. }
  142. kree(dead);
  143. }
  144. // returns true if a car is turning right
  145. bool rightturn(car * car)
  146. {
  147. int temp = car->origin - car->dest;
  148. return (temp == 1 || temp == -3)
  149. }
  150. /*
  151. * The simulation driver will call this function once before starting
  152. * the simulation
  153. *
  154. * You can use it to initialize synchronization and other variables.
  155. *
  156. */
  157. void
  158. intersection_sync_init(void)
  159. {
  160. /* replace this default implementation with your own implementation */
  161. intersectionSem = sem_create("intersectionSem",1);
  162. if (intersectionSem == NULL)
  163. {
  164. panic("could not create intersection semaphore");
  165. }
  166. return;
  167. nsem = sem_create("nsem",1);
  168. if (intersectionSem == NULL)
  169. {
  170. panic("could not create intersection semaphore");
  171. }
  172. return;
  173. intersectionSem = sem_create("intersectionSem",1);
  174. if (intersectionSem == NULL)
  175. {
  176. panic("could not create intersection semaphore");
  177. }
  178. return;
  179. intersectionSem = sem_create("intersectionSem",1);
  180. if (intersectionSem == NULL)
  181. {
  182. panic("could not create intersection semaphore");
  183. }
  184. return;
  185. intersectionSem = sem_create("intersectionSem",1);
  186. if (intersectionSem == NULL)
  187. {
  188. panic("could not create intersection semaphore");
  189. }
  190. return;
  191. }
  192. /*
  193. * The simulation driver will call this function once after
  194. * the simulation has finished
  195. *
  196. * You can use it to clean up any synchronization and other variables.
  197. *
  198. */
  199. void
  200. intersection_sync_cleanup(void)
  201. {
  202. /* replace this default implementation with your own implementation */
  203. KASSERT(intersectionSem);
  204. sem_destroy(intersectionSem);
  205. }
  206. /*
  207. * The simulation driver will call this function each time a vehicle
  208. * tries to enter the intersection, before it enters.
  209. * This function should cause the calling simulation thread
  210. * to block until it is OK for the vehicle to enter the intersection.
  211. *
  212. * parameters:
  213. * * origin: the Direction from which the vehicle is arriving
  214. * * destination: the Direction in which the vehicle is trying to go
  215. *
  216. * return value: none
  217. */
  218. void
  219. intersection_before_entry(Direction origin, Direction destination)
  220. {
  221. /* replace this default implementation with your own implementation */
  222. (void)origin; /* avoid compiler complaint about unused parameter */
  223. (void)destination; /* avoid compiler complaint about unused parameter */
  224. KASSERT(intersectionSem);
  225. P(intersectionSem);
  226. }
  227. /*
  228. * The simulation driver will call this function each time a vehicle
  229. * leaves the intersection.
  230. *
  231. * parameters:
  232. * * origin: the Direction from which the vehicle arrived
  233. * * destination: the Direction in which the vehicle is going
  234. *
  235. * return value: none
  236. */
  237. void
  238. intersection_after_exit(Direction origin, Direction destination)
  239. {
  240. /* replace this default implementation with your own implementation */
  241. (void)origin; /* avoid compiler complaint about unused parameter */
  242. (void)destination; /* avoid compiler complaint about unused parameter */
  243. KASSERT(intersectionSem);
  244. V(intersectionSem);
  245. }