windr0id / pintos

homepage
http://windroid.cc
0 stars 0 forks source link

这里有用while的必要吗? #1

Open windr0id opened 6 years ago

windr0id commented 6 years ago

https://github.com/windr0id/pintos/blob/a2f2c8e9fb9c5df58d5f69390e7582aa6f17e12a/src/threads/synch.c#L69

/* 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 ();
    while (sema->value == 0)
    {
        list_push_back (&sema->waiters, &thread_current ()->elem);
        thread_block ();
    }
    sema->value--;
    intr_set_level (old_level);
}
windr0id commented 6 years ago
/* 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);

  old_level = intr_disable ();
  if (!list_empty (&sema->waiters)) 
    thread_unblock (list_entry (list_pop_front (&sema->waiters),
                                struct thread, elem));
  sema->value++;
  intr_set_level (old_level);
}

只唤醒一个waiters队首的进程

windr0id commented 6 years ago

如果存在阻塞于sema却被V操作以外的情况唤醒的话,while是必要的,会有这种情况吗?

windr0id commented 6 years ago

key words: Mesa vs. Hoare monitors

windr0id commented 6 years ago

https://github.com/windr0id/pintos/blob/a2f2c8e9fb9c5df58d5f69390e7582aa6f17e12a/src/threads/thread.c#L269

/* Transitions a blocked thread T to the ready-to-run state.
   This is an error if T is not blocked.  (Use thread_yield() to
   make the running thread ready.)
   This function does not preempt the running thread.  This can
   be important: if the caller had disabled interrupts itself,
   it may expect that it can atomically unblock a thread and
   update other data. */
void
thread_unblock (struct thread *t) 
{
  enum intr_level old_level;

  ASSERT (is_thread (t));

  old_level = intr_disable ();
  ASSERT (t->status == THREAD_BLOCKED);
  list_push_back (&ready_list, &t->elem);
  t->status = THREAD_READY;
  intr_set_level (old_level);
}

thread_unblock()修改进程状态后并没有立即进行调度

windr0id commented 6 years ago

Hoare monitors:V操作后立即进行调度。 Mesa monitors:V操作后只将进程unblock,然后继续运行等待系统进行调度。所以,unblock的进程在被调度的时候,sema并不一定可用,比如其他进程进行了P操作,所以必须再次检查sema,如果不可用则继续block,PintOs使用了Mesa monitors,它的优点在于,减少了调度次数,系统开销低