aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2005-01-04 05:38:28 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-04 05:38:28 -0800
commit10d6e374ae2e96a43033cf7cf289e0411cf25fe7 (patch)
treefc04ab0c2fbcb6616ae175330ecbbda26aa656fa /kernel
parent66519f549ae516e7ff2f24a8a5134713411a4a58 (diff)
downloadhistory-10d6e374ae2e96a43033cf7cf289e0411cf25fe7.tar.gz
[PATCH] move waitchld_exit from task_struct to signal_struct
There is really no point in each task_struct having its own waitchld_exit. In the only use of it, the waitchld_exit of each thread in a group gets woken up at the same time. So, there might as well just be one wait queue for the whole thread group. This patch does that by moving the field from task_struct to signal_struct. It should have no effect on the behavior, but saves a little work and a little storage in the multithreaded case. Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/exit.c4
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/signal.c22
3 files changed, 6 insertions, 22 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 3aed197c6b858b..d7b09c996f6d58 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1319,7 +1319,7 @@ static long do_wait(pid_t pid, int options, struct siginfo __user *infop,
struct task_struct *tsk;
int flag, retval;
- add_wait_queue(&current->wait_chldexit,&wait);
+ add_wait_queue(&current->signal->wait_chldexit,&wait);
repeat:
/*
* We will set this flag if we see any child that might later
@@ -1433,7 +1433,7 @@ check_continued:
retval = -ECHILD;
end:
current->state = TASK_RUNNING;
- remove_wait_queue(&current->wait_chldexit,&wait);
+ remove_wait_queue(&current->signal->wait_chldexit,&wait);
if (infop) {
if (retval > 0)
retval = 0;
diff --git a/kernel/fork.c b/kernel/fork.c
index f3a8a8d5db908d..e861703f11e8d2 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -733,6 +733,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
return -ENOMEM;
atomic_set(&sig->count, 1);
atomic_set(&sig->live, 1);
+ init_waitqueue_head(&sig->wait_chldexit);
sig->flags = 0;
sig->group_exit_code = 0;
sig->group_exit_task = NULL;
@@ -860,7 +861,6 @@ static task_t *copy_process(unsigned long clone_flags,
INIT_LIST_HEAD(&p->children);
INIT_LIST_HEAD(&p->sibling);
- init_waitqueue_head(&p->wait_chldexit);
p->vfork_done = NULL;
spin_lock_init(&p->alloc_lock);
spin_lock_init(&p->proc_lock);
diff --git a/kernel/signal.c b/kernel/signal.c
index 1e05e102cf1f3c..7191de92659bf5 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1437,28 +1437,12 @@ out:
}
/*
- * Joy. Or not. Pthread wants us to wake up every thread
- * in our parent group.
+ * Wake up any threads in the parent blocked in wait* syscalls.
*/
-static void __wake_up_parent(struct task_struct *p,
+static inline void __wake_up_parent(struct task_struct *p,
struct task_struct *parent)
{
- struct task_struct *tsk = parent;
-
- /*
- * Fortunately this is not necessary for thread groups:
- */
- if (p->tgid == tsk->tgid) {
- wake_up_interruptible_sync(&tsk->wait_chldexit);
- return;
- }
-
- do {
- wake_up_interruptible_sync(&tsk->wait_chldexit);
- tsk = next_thread(tsk);
- if (tsk->signal != parent->signal)
- BUG();
- } while (tsk != parent);
+ wake_up_interruptible_sync(&parent->signal->wait_chldexit);
}
/*