Commit 73accc3d authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] add notify_count for de_thread

From: Manfred Spraul <manfred@colorfullife.com>

de_thread is called by exec to kill all threads in the thread group except
the threads required for exec.

The waiting is implemented by waiting for a wakeup from __exit_signal: If
the reference count is less or equal to 2, then the waiter is woken up.  If
exec is called by a non-leader thread, then two threads are required for
exec.

But if a thread group leader calls exec, then only one thread is required
for exec.  Thus the hardcoded "2" leads to a superfluous wakeup.  The patch
fixes that by adding a "notify_count" field to the signal structure.
parent 9ee208ea
...@@ -609,6 +609,7 @@ static inline int de_thread(struct task_struct *tsk) ...@@ -609,6 +609,7 @@ static inline int de_thread(struct task_struct *tsk)
count = 1; count = 1;
while (atomic_read(&oldsig->count) > count) { while (atomic_read(&oldsig->count) > count) {
oldsig->group_exit_task = current; oldsig->group_exit_task = current;
oldsig->notify_count = count;
__set_current_state(TASK_UNINTERRUPTIBLE); __set_current_state(TASK_UNINTERRUPTIBLE);
spin_unlock_irq(lock); spin_unlock_irq(lock);
schedule(); schedule();
......
...@@ -245,7 +245,13 @@ struct signal_struct { ...@@ -245,7 +245,13 @@ struct signal_struct {
/* thread group exit support */ /* thread group exit support */
int group_exit; int group_exit;
int group_exit_code; int group_exit_code;
/* overloaded:
* - notify group_exit_task when ->count is equal to notify_count
* - everyone except group_exit_task is stopped during signal delivery
* of fatal signals, group_exit_task processes the signal.
*/
struct task_struct *group_exit_task; struct task_struct *group_exit_task;
int notify_count;
/* thread group stop support, overloads group_exit_code too */ /* thread group stop support, overloads group_exit_code too */
int group_stop_count; int group_stop_count;
......
...@@ -336,7 +336,7 @@ void __exit_signal(struct task_struct *tsk) ...@@ -336,7 +336,7 @@ void __exit_signal(struct task_struct *tsk)
* If there is any task waiting for the group exit * If there is any task waiting for the group exit
* then notify it: * then notify it:
*/ */
if (sig->group_exit_task && atomic_read(&sig->count) <= 2) { if (sig->group_exit_task && atomic_read(&sig->count) == sig->notify_count) {
wake_up_process(sig->group_exit_task); wake_up_process(sig->group_exit_task);
sig->group_exit_task = NULL; sig->group_exit_task = NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment