synch.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
  3. * The President and Fellows of Harvard College.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the University nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. */
  29. /*
  30. * Synchronization primitives.
  31. * The specifications of the functions are in synch.h.
  32. */
  33. #include <types.h>
  34. #include <lib.h>
  35. #include <spinlock.h>
  36. #include <wchan.h>
  37. #include <thread.h>
  38. #include <current.h>
  39. #include <synch.h>
  40. ////////////////////////////////////////////////////////////
  41. //
  42. // Semaphore.
  43. struct semaphore *
  44. sem_create(const char *name, int initial_count)
  45. {
  46. struct semaphore *sem;
  47. KASSERT(initial_count >= 0);
  48. sem = kmalloc(sizeof(struct semaphore));
  49. if (sem == NULL) {
  50. return NULL;
  51. }
  52. sem->sem_name = kstrdup(name);
  53. if (sem->sem_name == NULL) {
  54. kfree(sem);
  55. return NULL;
  56. }
  57. sem->sem_wchan = wchan_create(sem->sem_name);
  58. if (sem->sem_wchan == NULL) {
  59. kfree(sem->sem_name);
  60. kfree(sem);
  61. return NULL;
  62. }
  63. spinlock_init(&sem->sem_lock);
  64. sem->sem_count = initial_count;
  65. return sem;
  66. }
  67. void
  68. sem_destroy(struct semaphore *sem)
  69. {
  70. KASSERT(sem != NULL);
  71. /* wchan_cleanup will assert if anyone's waiting on it */
  72. spinlock_cleanup(&sem->sem_lock);
  73. wchan_destroy(sem->sem_wchan);
  74. kfree(sem->sem_name);
  75. kfree(sem);
  76. }
  77. void
  78. P(struct semaphore *sem)
  79. {
  80. KASSERT(sem != NULL);
  81. /*
  82. * May not block in an interrupt handler.
  83. *
  84. * For robustness, always check, even if we can actually
  85. * complete the P without blocking.
  86. */
  87. KASSERT(curthread->t_in_interrupt == false);
  88. spinlock_acquire(&sem->sem_lock);
  89. while (sem->sem_count == 0) {
  90. /*
  91. * Bridge to the wchan lock, so if someone else comes
  92. * along in V right this instant the wakeup can't go
  93. * through on the wchan until we've finished going to
  94. * sleep. Note that wchan_sleep unlocks the wchan.
  95. *
  96. * Note that we don't maintain strict FIFO ordering of
  97. * threads going through the semaphore; that is, we
  98. * might "get" it on the first try even if other
  99. * threads are waiting. Apparently according to some
  100. * textbooks semaphores must for some reason have
  101. * strict ordering. Too bad. :-)
  102. *
  103. * Exercise: how would you implement strict FIFO
  104. * ordering?
  105. */
  106. wchan_lock(sem->sem_wchan);
  107. spinlock_release(&sem->sem_lock);
  108. wchan_sleep(sem->sem_wchan);
  109. spinlock_acquire(&sem->sem_lock);
  110. }
  111. KASSERT(sem->sem_count > 0);
  112. sem->sem_count--;
  113. spinlock_release(&sem->sem_lock);
  114. }
  115. void
  116. V(struct semaphore *sem)
  117. {
  118. KASSERT(sem != NULL);
  119. spinlock_acquire(&sem->sem_lock);
  120. sem->sem_count++;
  121. KASSERT(sem->sem_count > 0);
  122. wchan_wakeone(sem->sem_wchan);
  123. spinlock_release(&sem->sem_lock);
  124. }
  125. ////////////////////////////////////////////////////////////
  126. //
  127. // Lock.
  128. struct lock *
  129. lock_create(const char *name)
  130. {
  131. struct lock *lock;
  132. lock = kmalloc(sizeof(struct lock));
  133. if (lock == NULL) {
  134. return NULL;
  135. }
  136. lock->lk_name = kstrdup(name);
  137. if (lock->lk_name == NULL) {
  138. kfree(lock);
  139. return NULL;
  140. }
  141. // add stuff here as needed
  142. return lock;
  143. }
  144. void
  145. lock_destroy(struct lock *lock)
  146. {
  147. KASSERT(lock != NULL);
  148. // add stuff here as needed
  149. kfree(lock->lk_name);
  150. kfree(lock);
  151. }
  152. void
  153. lock_acquire(struct lock *lock)
  154. {
  155. // Write this
  156. (void)lock; // suppress warning until code gets written
  157. }
  158. void
  159. lock_release(struct lock *lock)
  160. {
  161. // Write this
  162. (void)lock; // suppress warning until code gets written
  163. }
  164. bool
  165. lock_do_i_hold(struct lock *lock)
  166. {
  167. // Write this
  168. (void)lock; // suppress warning until code gets written
  169. return true; // dummy until code gets written
  170. }
  171. ////////////////////////////////////////////////////////////
  172. //
  173. // CV
  174. struct cv *
  175. cv_create(const char *name)
  176. {
  177. struct cv *cv;
  178. cv = kmalloc(sizeof(struct cv));
  179. if (cv == NULL) {
  180. return NULL;
  181. }
  182. cv->cv_name = kstrdup(name);
  183. if (cv->cv_name==NULL) {
  184. kfree(cv);
  185. return NULL;
  186. }
  187. // add stuff here as needed
  188. return cv;
  189. }
  190. void
  191. cv_destroy(struct cv *cv)
  192. {
  193. KASSERT(cv != NULL);
  194. // add stuff here as needed
  195. kfree(cv->cv_name);
  196. kfree(cv);
  197. }
  198. void
  199. cv_wait(struct cv *cv, struct lock *lock)
  200. {
  201. // Write this
  202. (void)cv; // suppress warning until code gets written
  203. (void)lock; // suppress warning until code gets written
  204. }
  205. void
  206. cv_signal(struct cv *cv, struct lock *lock)
  207. {
  208. // Write this
  209. (void)cv; // suppress warning until code gets written
  210. (void)lock; // suppress warning until code gets written
  211. }
  212. void
  213. cv_broadcast(struct cv *cv, struct lock *lock)
  214. {
  215. // Write this
  216. (void)cv; // suppress warning until code gets written
  217. (void)lock; // suppress warning until code gets written
  218. }