Exemple #1
0
/* Acquires LOCK, sleeping until it becomes available if
   necessary.  The lock must not already be held by the current
   thread.

   This function may sleep, so it must not be called within an
   interrupt handler.  This function may be called with
   interrupts disabled, but interrupts will be turned back on if
   we need to sleep. */
void
lock_acquire (struct lock *lock)
{
  ASSERT (lock != NULL);
  ASSERT (!intr_context ());
  ASSERT (!lock_held_by_current_thread (lock));
  
  struct thread *cur_thread = thread_current ();

  /* If we are not in the multi-level feedback queue scheduler
     then use priority donation */
  if(!thread_mlfqs)
  {
    /* donate priority if someone holds the lock we want */
    enum intr_level old_level = intr_disable ();
     
    if (lock->holder != NULL) {
      cur_thread->lock_waiting_for = lock;
      cur_thread->t_donating_to = lock->holder;
      thread_donate_priority(cur_thread);
    }
    intr_set_level (old_level);
  }  

  sema_down (&lock->semaphore);
  lock->holder = cur_thread;
}
Exemple #2
0
/* Down or "P" operation on a semaphore.  Waits for SEMA's value
   to become positive and then atomically decrements it.

   This function may sleep, so it must not be called within an
   interrupt handler.  This function may be called with
   interrupts disabled, but if it sleeps then the next scheduled
   thread will probably turn interrupts back on. */
void
sema_down (struct semaphore *sema) 
{
  enum intr_level old_level;

  ASSERT (sema != NULL);
  ASSERT (!intr_context ());

  old_level = intr_disable ();

  struct thread *currentThread = thread_current();
  
  while (sema->value == 0) 
  {
  	if(!thread_mlfqs)
  	{
  	  thread_donate_priority();
  	}
  	//list_insert_priority_ordered (&sema->waiters, &currentThread->elem, currentThread->priority);
  	list_insert_ordered (&sema->waiters, &currentThread->elem, (list_less_func *) &thread_cmp_priority, NULL);

    thread_block ();
  }
  
  sema->value--;
  intr_set_level (old_level);
}
/* Acquires LOCK, sleeping until it becomes available if
   necessary.  The lock must not already be held by the current
   thread.

   This function may sleep, so it must not be called within an
   interrupt handler.  This function may be called with
   interrupts disabled, but interrupts will be turned back on if
   we need to sleep. */
void
lock_acquire (struct lock *lock)
{
  ASSERT (lock != NULL);
  ASSERT (!intr_context ());
  ASSERT (!lock_held_by_current_thread (lock));
  ASSERT (thread_current ()->waiting_on == NULL);

  enum intr_level old_level;
  old_level = intr_disable ();
  
  /* If the lock is currently held by someone, then we need to invoke
     thread_donate_priority to donate our priority to that special
     someone. */  
  if (!thread_mlfqs && lock->holder != NULL)
    {
      thread_current ()->waiting_on = lock;
      thread_donate_priority (thread_current ());
    }

  sema_down (&lock->semaphore);

  lock->holder = thread_current ();
  thread_current ()->waiting_on = NULL;

  intr_set_level (old_level);
}
Exemple #4
0
/* Acquires LOCK, sleeping until it becomes available if
   necessary.  The lock must not already be held by the current
   thread.

   This function may sleep, so it must not be called within an
   interrupt handler.  This function may be called with
   interrupts disabled, but interrupts will be turned back on if
   we need to sleep. */
void
lock_acquire (struct lock *lock)
{
  ASSERT (lock != NULL);
  ASSERT (!intr_context ());
  ASSERT (!lock_held_by_current_thread (lock));

  enum intr_level old_level = intr_disable ();

  if (!thread_mlfqs && lock->holder != NULL && lock->holder->priority < thread_current ()->priority)
    thread_donate_priority (lock->holder, lock);

  sema_down (&lock->semaphore);

  lock->holder = thread_current ();

  intr_set_level (old_level);
}
/* Acquires LOCK, sleeping until it becomes available if
   necessary.  The lock must not already be held by the current
   thread.

   This function may sleep, so it must not be called within an
   interrupt handler.  This function may be called with
   interrupts disabled, but interrupts will be turned back on if
   we need to sleep. */
void
lock_acquire (struct lock *lock)
{
  ASSERT (lock != NULL);
  ASSERT (!intr_context ());
  ASSERT (!lock_held_by_current_thread (lock));

  /* Added for priority donation. */
  if (lock->holder != NULL)
  {
    if (lock->highest_waiter == NULL)
    { 
      lock->highest_waiter = thread_current ();
      lock->highest_waiter->waiting_for = lock->holder;
    }
    else if (lock->highest_waiter->priority < thread_current ()->priority)
    {
      list_remove (&lock->highest_waiter->waiting_elem);
      lock->highest_waiter->waiting_for = thread_current ();
      lock->highest_waiter = thread_current ();
      lock->highest_waiter->waiting_for = lock->holder;
    }

    if (lock->highest_waiter == thread_current ())
    {
      list_insert_ordered (&lock->holder->waiting_threads, &lock->highest_waiter->waiting_elem, waiting_value_great, NULL);
      if (lock->holder->priority < &lock->highest_waiter->priority)
      {
        if (lock->holder->priority_orig < 0)
          lock->holder->priority_orig = lock->holder->priority;
	thread_donate_priority (lock->holder, lock->highest_waiter->priority);
      }
    }
  }

  sema_down (&lock->semaphore);
  lock->holder = thread_current ();

  /* Added for priority donation. */
  lock->highest_waiter = !list_empty (&lock->semaphore.waiters) ? 
	  list_entry (list_begin (&lock->semaphore.waiters), struct thread, elem) : NULL;
}