Open windr0id opened 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队首的进程
如果存在阻塞于sema却被V操作以外的情况唤醒的话,while是必要的,会有这种情况吗?
key words: Mesa vs. Hoare monitors
/* 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()修改进程状态后并没有立即进行调度
Hoare monitors:V操作后立即进行调度。 Mesa monitors:V操作后只将进程unblock,然后继续运行等待系统进行调度。所以,unblock的进程在被调度的时候,sema并不一定可用,比如其他进程进行了P操作,所以必须再次检查sema,如果不可用则继续block,PintOs使用了Mesa monitors,它的优点在于,减少了调度次数,系统开销低
https://github.com/windr0id/pintos/blob/a2f2c8e9fb9c5df58d5f69390e7582aa6f17e12a/src/threads/synch.c#L69