patch-2.3.1 linux/kernel/sched.c
Next file: linux/kernel/signal.c
Previous file: linux/kernel/printk.c
Back to the patch index
Back to the overall index
- Lines: 175
- Date:
Wed May 12 14:41:36 1999
- Orig file:
v2.3.0/linux/kernel/sched.c
- Orig date:
Mon May 10 09:55:21 1999
diff -u --recursive --new-file v2.3.0/linux/kernel/sched.c linux/kernel/sched.c
@@ -866,52 +866,48 @@
return;
}
-rwlock_t waitqueue_lock = RW_LOCK_UNLOCKED;
-
-/*
- * wake_up doesn't wake up stopped processes - they have to be awakened
- * with signals or similar.
- *
- * Note that we only need a read lock for the wait queue (and thus do not
- * have to protect against interrupts), as the actual removal from the
- * queue is handled by the process itself.
- */
-void __wake_up(struct wait_queue **q, unsigned int mode)
+void __wake_up(wait_queue_head_t *q, unsigned int mode)
{
+ struct list_head *tmp, *head;
struct task_struct *p;
- struct wait_queue *head, *next;
+ unsigned long flags;
if (!q)
goto out;
- /*
- * this is safe to be done before the check because it
- * means no deference, just pointer operations.
- */
- head = WAIT_QUEUE_HEAD(q);
-
- read_lock(&waitqueue_lock);
- next = *q;
- if (!next)
- goto out_unlock;
-
- while (next != head) {
- p = next->task;
- next = next->next;
- if (p->state & mode) {
- /*
- * We can drop the read-lock early if this
- * is the only/last process.
- */
- if (next == head) {
- read_unlock(&waitqueue_lock);
- wake_up_process(p);
- goto out;
- }
+
+ wq_write_lock_irqsave(&q->lock, flags);
+
+#if WAITQUEUE_DEBUG
+ CHECK_MAGIC_WQHEAD(q);
+#endif
+
+ head = &q->task_list;
+#if WAITQUEUE_DEBUG
+ if (!head->next || !head->prev)
+ WQ_BUG();
+#endif
+ tmp = head->next;
+ while (tmp != head) {
+ unsigned int state;
+ wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list);
+
+ tmp = tmp->next;
+
+#if WAITQUEUE_DEBUG
+ CHECK_MAGIC(curr->__magic);
+#endif
+ p = curr->task;
+ state = p->state;
+ if (state & mode) {
+#if WAITQUEUE_DEBUG
+ curr->__waker = (long)__builtin_return_address(0);
+#endif
wake_up_process(p);
+ if (state & TASK_EXCLUSIVE)
+ break;
}
}
-out_unlock:
- read_unlock(&waitqueue_lock);
+ wq_write_unlock_irqrestore(&q->lock, flags);
out:
return;
}
@@ -972,7 +968,8 @@
#define DOWN_VAR \
struct task_struct *tsk = current; \
- struct wait_queue wait = { tsk, NULL };
+ wait_queue_t wait; \
+ init_waitqueue_entry(&wait, tsk);
#define DOWN_HEAD(task_state) \
\
@@ -1015,8 +1012,8 @@
int __down_interruptible(struct semaphore * sem)
{
- DOWN_VAR
int ret = 0;
+ DOWN_VAR
DOWN_HEAD(TASK_INTERRUPTIBLE)
ret = waking_non_zero_interruptible(sem, tsk);
@@ -1039,20 +1036,20 @@
#define SLEEP_ON_VAR \
unsigned long flags; \
- struct wait_queue wait;
+ wait_queue_t wait; \
+ init_waitqueue_entry(&wait, current);
#define SLEEP_ON_HEAD \
- wait.task = current; \
- write_lock_irqsave(&waitqueue_lock,flags); \
- __add_wait_queue(p, &wait); \
- write_unlock(&waitqueue_lock);
+ wq_write_lock_irqsave(&q->lock,flags); \
+ __add_wait_queue(q, &wait); \
+ wq_write_unlock(&q->lock);
#define SLEEP_ON_TAIL \
- write_lock_irq(&waitqueue_lock); \
- __remove_wait_queue(p, &wait); \
- write_unlock_irqrestore(&waitqueue_lock,flags);
+ wq_write_lock_irq(&q->lock); \
+ __remove_wait_queue(q, &wait); \
+ wq_write_unlock_irqrestore(&q->lock,flags);
-void interruptible_sleep_on(struct wait_queue **p)
+void interruptible_sleep_on(wait_queue_head_t *q)
{
SLEEP_ON_VAR
@@ -1063,7 +1060,7 @@
SLEEP_ON_TAIL
}
-long interruptible_sleep_on_timeout(struct wait_queue **p, long timeout)
+long interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout)
{
SLEEP_ON_VAR
@@ -1076,7 +1073,7 @@
return timeout;
}
-void sleep_on(struct wait_queue **p)
+void sleep_on(wait_queue_head_t *q)
{
SLEEP_ON_VAR
@@ -1087,7 +1084,7 @@
SLEEP_ON_TAIL
}
-long sleep_on_timeout(struct wait_queue **p, long timeout)
+long sleep_on_timeout(wait_queue_head_t *q, long timeout)
{
SLEEP_ON_VAR
@@ -1199,8 +1196,8 @@
read_lock(&tasklist_lock);
for_each_task(p) {
if ((p->state == TASK_RUNNING ||
- p->state == TASK_UNINTERRUPTIBLE ||
- p->state == TASK_SWAPPING))
+ (p->state & TASK_UNINTERRUPTIBLE) ||
+ (p->state & TASK_SWAPPING)))
nr += FIXED_1;
}
read_unlock(&tasklist_lock);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)