since they're protected by the semaphore.
Thanks to Godmar Back for reporting this.
* Add FS persistence test(s).
-* lock_acquire(), lock_release() don't need additional intr_dis/enable
- calls, because the semaphore protects lock->holder.
- [ Think this over: is this really true when priority donation is
- implemented? intr_dis/enable prevents the race with thread_set_priority.
- Leaving it there could help the students getting the correct synchronization
- right.
- ]
-
-
-
* process_death test needs improvement
* Internal tests.
interrupt handling latency, which can make a machine feel sluggish if
taken too far.
-You may need to add or modify code where interrupts are already
-disabled, such as in @func{sema_up} or @func{sema_down}. You should
-still try to keep this code as short as you can.
+The synchronization primitives themselves in @file{synch.c} are
+implemented by disabling interrupts. You may need to increase the
+amount of code that runs with interrupts disabled here, but you should
+still try to keep it to a minimum.
Disabling interrupts can be useful for debugging, if you want to make
sure that a section of code is not interrupted. You should remove
intr_set_level (old_level);
}
-@@ -200,6 +218,23 @@ lock_acquire (struct lock *lock)
+@@ -200,8 +218,29 @@ lock_acquire (struct lock *lock)
+ lock_acquire (struct lock *lock)
+ {
++ enum intr_level old_level;
++
+ ASSERT (lock != NULL);
+ ASSERT (!intr_context ());
ASSERT (!lock_held_by_current_thread (lock));
- old_level = intr_disable ();
++ old_level = intr_disable ();
+
+ if (lock->holder != NULL)
+ {
+
sema_down (&lock->semaphore);
lock->holder = thread_current ();
- intr_set_level (old_level);
-@@ -238,13 +273,37 @@ void
++ intr_set_level (old_level);
+@@ -238,9 +273,37 @@ void
lock_release (struct lock *lock)
{
- enum intr_level old_level;
++ enum intr_level old_level;
+ struct thread *t = thread_current ();
+ struct list_elem *e;
-
++
ASSERT (lock != NULL);
ASSERT (lock_held_by_current_thread (lock));
- old_level = intr_disable ();
++ old_level = intr_disable ();
+
+ /* Return donations to threads that want this lock. */
+ for (e = list_begin (&t->donors); e != list_end (&t->donors); )
+ thread_recompute_priority (t);
+ thread_yield_to_higher_priority ();
+
- intr_set_level (old_level);
++ intr_set_level (old_level);
}
@@ -264,6 +323,7 @@ struct semaphore_elem
void
lock_acquire (struct lock *lock)
{
- enum intr_level old_level;
-
ASSERT (lock != NULL);
ASSERT (!intr_context ());
ASSERT (!lock_held_by_current_thread (lock));
- old_level = intr_disable ();
sema_down (&lock->semaphore);
lock->holder = thread_current ();
- intr_set_level (old_level);
}
/* Tries to acquires LOCK and returns true if successful or false
bool
lock_try_acquire (struct lock *lock)
{
- enum intr_level old_level;
bool success;
ASSERT (lock != NULL);
ASSERT (!lock_held_by_current_thread (lock));
- old_level = intr_disable ();
success = sema_try_down (&lock->semaphore);
if (success)
lock->holder = thread_current ();
- intr_set_level (old_level);
-
return success;
}
void
lock_release (struct lock *lock)
{
- enum intr_level old_level;
-
ASSERT (lock != NULL);
ASSERT (lock_held_by_current_thread (lock));
- old_level = intr_disable ();
lock->holder = NULL;
sema_up (&lock->semaphore);
- intr_set_level (old_level);
}
/* Returns true if the current thread holds LOCK, false