Exemplo n.º 1
0
/* Up or "V" operation on a semaphore.  Increments SEMA's value
   and wakes up one thread of those waiting for SEMA, if any.

   This function may be called from an interrupt handler.
   Within an interrupt context, sema_up () always returns. */
void
sema_up (struct semaphore *sema) 
{
  enum intr_level old_level;
  bool yield = false;

  ASSERT (sema != NULL);

  old_level = intr_disable ();
  if (!list_empty (&sema->waiters)) 
  {
    struct thread *t = list_entry (list_pop_front (&sema->waiters),
                        struct thread, elem);
    thread_unblock (t);

    /* Yield to the newly unblocked thread if it has higher priority. */
    if (t->priority > thread_current ()->priority)
      yield = true;
  }
  sema->value++;
  intr_set_level (old_level);

  if (yield)
  {
    if (!intr_context ())
      thread_yield ();
    else
      intr_yield_on_return ();
  }
}
Exemplo n.º 2
0
/* Called by the timer interrupt handler at each timer tick.
   Thus, this function runs in an external interrupt context. */
void
thread_tick (void) 
{
  struct thread *t = thread_current ();

  /* Update statistics. */
  if (t == idle_thread)
    idle_ticks++;
#ifdef USERPROG
  else if (t->pagedir != NULL)
    user_ticks++;
#endif
  else
    kernel_ticks++;

  /* Enforce preemption. */
  if (++thread_ticks >= TIME_SLICE)
    intr_yield_on_return ();
}
Exemplo n.º 3
0
/* Up or "V" operation on a semaphore.  Increments SEMA's value
   and wakes up one thread of those waiting for SEMA, if any.

   This function may be called from an interrupt handler. */
void
sema_up (struct semaphore *sema) 
{
  enum intr_level old_level;

  ASSERT (sema != NULL);
  struct thread *t=NULL;
  old_level = intr_disable ();
  if (!list_empty (&sema->waiters)) {
	  struct list_elem *e=list_max(&sema->waiters, thread_max_priority,NULL);
	  t= list_entry(e, struct thread, elem);
	  list_remove(e);
	  thread_unblock(t);
    //thread_unblock (list_entry (list_pop_front (&sema->waiters),struct thread, elem));
  }
  sema->value++;
  intr_set_level (old_level);
  if(t && t->priority>thread_current()->priority){
	  if(intr_context()) intr_yield_on_return();
	  else thread_yield();
  }
}