Re: New semaphore __wake_up() implementation ...

Andrea Arcangeli (andrea@suse.de)
Fri, 11 Jun 1999 16:08:32 +0200 (CEST)


On Fri, 11 Jun 1999, V Ganesh wrote:

>but if the semaphore was being used for mutual exclusion then you should
>wake up the highest priority process, which is what I think Davide is
>doing. previously we just kicked the herd in the ass and they all thundered

I think we should wakeup the last process that gone to sleep even in the
up() case. We should simple ask for an EXCLUSIVE wakeup.

Here a patch to do that:

Index: linux/kernel/sched.c
===================================================================
RCS file: /var/cvs/linux/kernel/sched.c,v
retrieving revision 1.1.2.46
diff -u -r1.1.2.46 sched.c
--- linux/kernel/sched.c 1999/05/24 01:50:14 1.1.2.46
+++ linux/kernel/sched.c 1999/06/11 12:32:28
@@ -930,9 +930,6 @@
init_waitqueue_entry(&wait, tsk);

#define DOWN_HEAD(task_state) \
- \
- \
- tsk->state = (task_state); \
add_wait_queue(&sem->wait, &wait); \
\
/* \
@@ -950,10 +947,11 @@
* Multiple waiters contend for the semaphore lock to see \
* who gets to gate through and who has to wait some more. \
*/ \
- for (;;) {
+ for (;;) { \
+ tsk->state = (task_state|TASK_EXCLUSIVE);

-#define DOWN_TAIL(task_state) \
- tsk->state = (task_state); \
+#define DOWN_TAIL() \
+ schedule(); \
} \
tsk->state = TASK_RUNNING; \
remove_wait_queue(&sem->wait, &wait);
@@ -964,8 +962,7 @@
DOWN_HEAD(TASK_UNINTERRUPTIBLE)
if (waking_non_zero(sem))
break;
- schedule();
- DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+ DOWN_TAIL()
}

int __down_interruptible(struct semaphore * sem)
@@ -973,7 +970,6 @@
int ret = 0;
DOWN_VAR
DOWN_HEAD(TASK_INTERRUPTIBLE)
-
ret = waking_non_zero_interruptible(sem, tsk);
if (ret)
{
@@ -982,8 +978,7 @@
ret = 0;
break;
}
- schedule();
- DOWN_TAIL(TASK_INTERRUPTIBLE)
+ DOWN_TAIL()
return ret;
}

NOTE: There is at least one very important detail in the
semaphore-helper.h. The i386 port would be just fine about this detail.
The detail is that waking_non_zero_interruptible() _must_ first check if
it can exits succesfully from down_interruptible(). Only if it can't own
the seamphore it has to check if there is a signal pending and fail only
in such case. Otherwise we may wakeup a task in exclusive mode, and then
such task will exit because it's been interrupted and other tasks won't be
wokenup for the exclusive thing -> deadlock.

Davide if you'll do benchmarkes of your wake_up_sem, please do a bench
also over the patch above. Thanks.

Andrea Arcangeli

PS. for the equation complain, sorry, I mistaken M for N :) (you defined N
but you never used it).

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/