- 论坛徽章:
- 0
|
今天看linux的内核信号量,有个问题没搞懂,求助大神!
书上说的up( )函数释放信号量的代码:
movl $sem->count,%ecx
lock; incl(%ecx)
jg 1f
lea %ecx,%eax
pushl %edx
pushl %ecx
call __up
popl %ecx
popl %edx
__up( )c函数:
__attribute__((regparm(3))) void __up(struct semaphore *sem)
{
wake_up(&sem->wait);
}
获取信号量的down函数代码
down:
movl $sem->count,%ecx
lock;decl (%ecx)
jns 1f
lea %ecx,%eax
pushl %edx
pushl %ecx
call __down
popl %ecx
popl %edx
1:
__down函数的实现如下:
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->sleepers;
/*
* Add "everybody else" into it. They aren't
* playing, because we own the spinlock in
* the wait_queue_head.
*/
if (!atomic_add_negative(sleepers - 1, &sem->count)) { //这一条语句*
sem->sleepers = 0;
break;
}
sem->sleepers = 1; /* us - see -1 above */
spin_unlock_irqrestore(&sem->wait.lock, flags);
schedule();
spin_lock_irqsave(&sem->wait.lock, flags);
tsk->state = TASK_UNINTERRUPTIBLE;
}
remove_wait_queue_locked(&sem->wait, &wait);
wake_up_locked(&sem->wait);
spin_unlock_irqrestore(&sem->wait.lock, flags);
tsk->state = TASK_RUNNING;
}
假设此时有5个线程阻塞在信号量上,此时sem->count=-5,那么当有一个线程调用up()释放了信号量**了一个阻塞的线程,那么按照以上*号语句处的条件这个被**的线程还是要被挂起,这里是怎么一回事儿?求助.
|
|