root/kern/thread/synch.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sem_create
  2. sem_destroy
  3. P
  4. V
  5. lock_create
  6. lock_destroy
  7. lock_acquire
  8. lock_release
  9. lock_do_i_hold
  10. cv_create
  11. cv_destroy
  12. cv_wait
  13. cv_signal
  14. cv_broadcast

   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 /*
  31  * Synchronization primitives.
  32  * The specifications of the functions are in synch.h.
  33  */
  34 
  35 #include <types.h>
  36 #include <lib.h>
  37 #include <spinlock.h>
  38 #include <wchan.h>
  39 #include <thread.h>
  40 #include <current.h>
  41 #include <synch.h>
  42 
  43 ////////////////////////////////////////////////////////////
  44 //
  45 // Semaphore.
  46 
  47 struct semaphore *
  48 sem_create(const char *name, int initial_count)
  49 {
  50         struct semaphore *sem;
  51 
  52         KASSERT(initial_count >= 0);
  53 
  54         sem = kmalloc(sizeof(struct semaphore));
  55         if (sem == NULL) {
  56                 return NULL;
  57         }
  58 
  59         sem->sem_name = kstrdup(name);
  60         if (sem->sem_name == NULL) {
  61                 kfree(sem);
  62                 return NULL;
  63         }
  64 
  65         sem->sem_wchan = wchan_create(sem->sem_name);
  66         if (sem->sem_wchan == NULL) {
  67                 kfree(sem->sem_name);
  68                 kfree(sem);
  69                 return NULL;
  70         }
  71 
  72         spinlock_init(&sem->sem_lock);
  73         sem->sem_count = initial_count;
  74 
  75         return sem;
  76 }
  77 
  78 void
  79 sem_destroy(struct semaphore *sem)
  80 {
  81         KASSERT(sem != NULL);
  82 
  83         /* wchan_cleanup will assert if anyone's waiting on it */
  84         spinlock_cleanup(&sem->sem_lock);
  85         wchan_destroy(sem->sem_wchan);
  86         kfree(sem->sem_name);
  87         kfree(sem);
  88 }
  89 
  90 void 
  91 P(struct semaphore *sem)
  92 {
  93         KASSERT(sem != NULL);
  94 
  95         /*
  96          * May not block in an interrupt handler.
  97          *
  98          * For robustness, always check, even if we can actually
  99          * complete the P without blocking.
 100          */
 101         KASSERT(curthread->t_in_interrupt == false);
 102 
 103         spinlock_acquire(&sem->sem_lock);
 104         while (sem->sem_count == 0) {
 105                 /*
 106                  * Bridge to the wchan lock, so if someone else comes
 107                  * along in V right this instant the wakeup can't go
 108                  * through on the wchan until we've finished going to
 109                  * sleep. Note that wchan_sleep unlocks the wchan.
 110                  *
 111                  * Note that we don't maintain strict FIFO ordering of
 112                  * threads going through the semaphore; that is, we
 113                  * might "get" it on the first try even if other
 114                  * threads are waiting. Apparently according to some
 115                  * textbooks semaphores must for some reason have
 116                  * strict ordering. Too bad. :-)
 117                  *
 118                  * Exercise: how would you implement strict FIFO
 119                  * ordering?
 120                  */
 121                 wchan_lock(sem->sem_wchan);
 122                 spinlock_release(&sem->sem_lock);
 123                 wchan_sleep(sem->sem_wchan);
 124 
 125                 spinlock_acquire(&sem->sem_lock);
 126         }
 127         KASSERT(sem->sem_count > 0);
 128         sem->sem_count--;
 129         spinlock_release(&sem->sem_lock);
 130 }
 131 
 132 void
 133 V(struct semaphore *sem)
 134 {
 135         KASSERT(sem != NULL);
 136 
 137         spinlock_acquire(&sem->sem_lock);
 138 
 139         sem->sem_count++;
 140         KASSERT(sem->sem_count > 0);
 141         wchan_wakeone(sem->sem_wchan);
 142 
 143         spinlock_release(&sem->sem_lock);
 144 }
 145 
 146 ////////////////////////////////////////////////////////////
 147 //
 148 // Lock.
 149 
 150 struct lock *
 151 lock_create(const char *name)
 152 {
 153         struct lock *lock;
 154 
 155         lock = kmalloc(sizeof(struct lock));
 156         if (lock == NULL) {
 157                 return NULL;
 158         }
 159 
 160         lock->lk_name = kstrdup(name);
 161         if (lock->lk_name == NULL) {
 162                 kfree(lock);
 163                 return NULL;
 164         }
 165         
 166         // add stuff here as needed
 167         
 168         return lock;
 169 }
 170 
 171 void
 172 lock_destroy(struct lock *lock)
 173 {
 174         KASSERT(lock != NULL);
 175 
 176         // add stuff here as needed
 177         
 178         kfree(lock->lk_name);
 179         kfree(lock);
 180 }
 181 
 182 void
 183 lock_acquire(struct lock *lock)
 184 {
 185         // Write this
 186 
 187         (void)lock;  // suppress warning until code gets written
 188 }
 189 
 190 void
 191 lock_release(struct lock *lock)
 192 {
 193         // Write this
 194 
 195         (void)lock;  // suppress warning until code gets written
 196 }
 197 
 198 bool
 199 lock_do_i_hold(struct lock *lock)
 200 {
 201         // Write this
 202 
 203         (void)lock;  // suppress warning until code gets written
 204 
 205         return true; // dummy until code gets written
 206 }
 207 
 208 ////////////////////////////////////////////////////////////
 209 //
 210 // CV
 211 
 212 
 213 struct cv *
 214 cv_create(const char *name)
 215 {
 216         struct cv *cv;
 217 
 218         cv = kmalloc(sizeof(struct cv));
 219         if (cv == NULL) {
 220                 return NULL;
 221         }
 222 
 223         cv->cv_name = kstrdup(name);
 224         if (cv->cv_name==NULL) {
 225                 kfree(cv);
 226                 return NULL;
 227         }
 228         
 229         // add stuff here as needed
 230         
 231         return cv;
 232 }
 233 
 234 void
 235 cv_destroy(struct cv *cv)
 236 {
 237         KASSERT(cv != NULL);
 238 
 239         // add stuff here as needed
 240         
 241         kfree(cv->cv_name);
 242         kfree(cv);
 243 }
 244 
 245 void
 246 cv_wait(struct cv *cv, struct lock *lock)
 247 {
 248         // Write this
 249         (void)cv;    // suppress warning until code gets written
 250         (void)lock;  // suppress warning until code gets written
 251 }
 252 
 253 void
 254 cv_signal(struct cv *cv, struct lock *lock)
 255 {
 256         // Write this
 257         (void)cv;    // suppress warning until code gets written
 258         (void)lock;  // suppress warning until code gets written
 259 }
 260 
 261 void
 262 cv_broadcast(struct cv *cv, struct lock *lock)
 263 {
 264         // Write this
 265         (void)cv;    // suppress warning until code gets written
 266         (void)lock;  // suppress warning until code gets written
 267 }

/* [<][>][^][v][top][bottom][index][help] */