Messages in this thread Patch in this message | | | Date | Fri, 11 Jun 1999 16:08:32 +0200 (CEST) | From | Andrea Arcangeli <> | Subject | Re: New semaphore __wake_up() implementation ... |
| |
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/
| |