Jelajahi Sumber

did locks (blocking)

tarfeef101 6 tahun lalu
induk
melakukan
d4a360e431
2 mengubah file dengan 47 tambahan dan 31 penghapusan
  1. 4 3
      kern/include/synch.h
  2. 43 28
      kern/thread/synch.c

+ 4 - 3
kern/include/synch.h

@@ -1,4 +1,4 @@
-/*
+	/*
  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
  *	The President and Fellows of Harvard College.
  *
@@ -76,6 +76,7 @@ struct lock
 {
   char * lk_name;
   struct wchan * wc;
+  struct spinlock spin;
   struct thread * volatile owner;
 };
 
@@ -88,7 +89,7 @@ void lock_acquire(struct lock *);
  *                   same time.
  *    lock_release - Free the lock. Only the thread holding the lock may do
  *                   this.
- *    lock_do_i_hold - Return true if the current thread holds the lock; 
+ *    lock_do_i_hold - Return true if the current thread holds the lock;
  *                   false otherwise.
  *
  * These operations must be atomic. You get to write them.
@@ -128,7 +129,7 @@ void cv_destroy(struct cv *);
  *    cv_signal    - Wake up one thread that's sleeping on this CV.
  *    cv_broadcast - Wake up all threads sleeping on this CV.
  *
- * For all three operations, the current thread must hold the lock passed 
+ * For all three operations, the current thread must hold the lock passed
  * in. Note that under normal circumstances the same lock should be used
  * on all operations with any particular CV.
  *

+ 43 - 28
kern/thread/synch.c

@@ -87,7 +87,7 @@ sem_destroy(struct semaphore *sem)
         kfree(sem);
 }
 
-void 
+void
 P(struct semaphore *sem)
 {
         KASSERT(sem != NULL);
@@ -147,8 +147,7 @@ V(struct semaphore *sem)
 //
 // Lock.
 
-struct lock *
-lock_create(const char * name)
+struct lock * lock_create(const char * name)
 {
   struct lock * lock = kmalloc(sizeof(struct lock));
   
@@ -165,45 +164,61 @@ lock_create(const char * name)
   {
     kfree(lock);
     kfree(wc);
+  }
+  
+  lock->owner = NULL;
+  spinlock_init(&lock->spin);
     
   return lock;
 }
 
-void
-lock_destroy(struct lock *lock)
+void lock_destroy(struct lock * lock)
 {
-        KASSERT(lock != NULL);
-
-        // add stuff here as needed
-        
-        kfree(lock->lk_name);
-        kfree(lock);
+  KASSERT(lock);
+  
+  spinlock_cleanup(lock->spin);
+  wchan_destroy(lock->wc);
+  kfree(lock->lk_name);
+  kfree(lock->owner);
+  kfree(lock);
 }
 
-void
-lock_acquire(struct lock *lock)
+void lock_acquire(struct lock * lock)
 {
-        // Write this
-
-        (void)lock;  // suppress warning until code gets written
+  KASSERT(lock);
+  
+  spinlock_acquire(&(lock->spin));
+  
+  if (lock->owner)
+  {
+    wchan_lock(lock->wc);
+    spinlock_release(&(lock->spin));
+    wchan_sleep(lock->wc);
+    spinlock_acquire(lock->wc);
+  }
+  
+  lock->owner = curthread;
+  spinlock_release(lock->wc);
 }
 
-void
-lock_release(struct lock *lock)
+void lock_release(struct lock * lock)
 {
-        // Write this
-
-        (void)lock;  // suppress warning until code gets written
+  KASSERT(lock);
+  
+  spinlock_acquire(&(lock->spin));
+  KASSERT(curthread == lock->owner);
+  lock->owner = NULL;
+  wchan_wakeone(lock->wc);
+  spinlock_release(lock->spin);
 }
 
-bool
-lock_do_i_hold(struct lock *lock)
+bool lock_do_i_hold(struct lock * lock)
 {
-        // Write this
-
-        (void)lock;  // suppress warning until code gets written
-
-        return true; // dummy until code gets written
+  KASSERT(lock);
+  
+  if (lock->owner == curthread) return 1;
+  
+  return 0;
 }
 
 ////////////////////////////////////////////////////////////