Linux 共有两种信号量——内核信号量和System V IPC 信号量,这里仅讨论内核信号量所用到的子程序 __down()
(Linux 2.6.11.12) ,其他讨论见《深入理解Linux内核》(Understanding the Linux Kernel, 2nd edition, 中文版211页,英文版208页,顺带对国人翻译书名的功力表示称(tu)赞(cao))。
这里先放一下主要的代码,方便后面讨论
// file: include/asm-i386/semaphore.h
struct semaphore {
atomic_t count;
int sleepers;
wait_queue_head_t wait;
};
// file: arch/i386/kernel/semaphore.c
fastcall void __sched __down(struct semaphore * sem)
{
struct task_struct *tsk = current;
DECLARE_WAITQUEUE(wait, tsk);
unsigned long flags;
tsk->state = TASK_UNINTERRUPTIBLE;
spin_lock_irqsave(&sem->wait.lock, flags);
add_wait_queue_exclusive_locked(&sem->wait, &wait);
sem->sleepers++;
for (;;) {
int sleepers = sem