Commit 183986a7 authored by Roland McGrath's avatar Roland McGrath Committed by Linus Torvalds

[PATCH] move group_exit flag into signal_struct.flags word

After my last change, there are plenty of unused bits available in the new
flags word in signal_struct.  This patch moves the `group_exit' flag into
one of those bits, saving a word in signal_struct.
Signed-off-by: default avatarRoland McGrath <roland@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0b4eff5d
......@@ -601,7 +601,7 @@ static inline int de_thread(struct task_struct *tsk)
*/
read_lock(&tasklist_lock);
spin_lock_irq(lock);
if (sig->group_exit) {
if (sig->flags & SIGNAL_GROUP_EXIT) {
/*
* Another group action in progress, just
* return so that the signal is processed.
......@@ -611,7 +611,6 @@ static inline int de_thread(struct task_struct *tsk)
kmem_cache_free(sighand_cachep, newsighand);
return -EAGAIN;
}
sig->group_exit = 1;
zap_other_threads(current);
read_unlock(&tasklist_lock);
......@@ -709,7 +708,7 @@ static inline int de_thread(struct task_struct *tsk)
* Now there are really no other threads at all,
* so it's safe to stop telling them to kill themselves.
*/
sig->group_exit = 0;
sig->flags = 0;
no_thread_group:
BUG_ON(atomic_read(&sig->count) != 1);
......@@ -1396,7 +1395,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
}
mm->dumpable = 0;
init_completion(&mm->core_done);
current->signal->group_exit = 1;
current->signal->flags = SIGNAL_GROUP_EXIT;
current->signal->group_exit_code = exit_code;
coredump_wait(mm);
......
......@@ -281,7 +281,6 @@ struct signal_struct {
struct sigpending shared_pending;
/* thread group exit support */
int group_exit;
int group_exit_code;
/* overloaded:
* - notify group_exit_task when ->count is equal to notify_count
......@@ -335,6 +334,7 @@ struct signal_struct {
#define SIGNAL_STOP_STOPPED 0x00000001 /* job control stop in effect */
#define SIGNAL_STOP_DEQUEUED 0x00000002 /* stop signal dequeued */
#define SIGNAL_STOP_CONTINUED 0x00000004 /* SIGCONT since WCONTINUED reap */
#define SIGNAL_GROUP_EXIT 0x00000008 /* group exit in progress */
/*
......
......@@ -656,7 +656,7 @@ static void exit_notify(struct task_struct *tsk)
struct task_struct *t;
struct list_head ptrace_dead, *_p, *_n;
if (signal_pending(tsk) && !tsk->signal->group_exit
if (signal_pending(tsk) && !(tsk->signal->flags & SIGNAL_GROUP_EXIT)
&& !thread_group_empty(tsk)) {
/*
* This occurs when there was a race between our exit
......@@ -879,18 +879,18 @@ do_group_exit(int exit_code)
{
BUG_ON(exit_code & 0x80); /* core dumps don't get here */
if (current->signal->group_exit)
if (current->signal->flags & SIGNAL_GROUP_EXIT)
exit_code = current->signal->group_exit_code;
else if (!thread_group_empty(current)) {
struct signal_struct *const sig = current->signal;
struct sighand_struct *const sighand = current->sighand;
read_lock(&tasklist_lock);
spin_lock_irq(&sighand->siglock);
if (sig->group_exit)
if (sig->flags & SIGNAL_GROUP_EXIT)
/* Another thread got here before we took the lock. */
exit_code = sig->group_exit_code;
else {
sig->group_exit = 1;
sig->flags = SIGNAL_GROUP_EXIT;
sig->group_exit_code = exit_code;
zap_other_threads(current);
}
......@@ -1070,7 +1070,7 @@ static int wait_task_zombie(task_t *p, int noreap,
read_unlock(&tasklist_lock);
retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
status = p->signal->group_exit
status = (p->signal->flags & SIGNAL_GROUP_EXIT)
? p->signal->group_exit_code : p->exit_code;
if (!retval && stat_addr)
retval = put_user(status, stat_addr);
......
......@@ -734,7 +734,6 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
atomic_set(&sig->count, 1);
atomic_set(&sig->live, 1);
sig->flags = 0;
sig->group_exit = 0;
sig->group_exit_code = 0;
sig->group_exit_task = NULL;
sig->group_stop_count = 0;
......@@ -1000,7 +999,7 @@ static task_t *copy_process(unsigned long clone_flags,
* do not create this new thread - the whole thread
* group is supposed to exit anyway.
*/
if (current->signal->group_exit) {
if (current->signal->flags & SIGNAL_GROUP_EXIT) {
spin_unlock(&current->sighand->siglock);
write_unlock_irq(&tasklist_lock);
retval = -EAGAIN;
......
......@@ -661,6 +661,12 @@ static void handle_stop_signal(int sig, struct task_struct *p)
{
struct task_struct *t;
if (p->flags & SIGNAL_GROUP_EXIT)
/*
* The process is in the middle of dying already.
*/
return;
if (sig_kernel_stop(sig)) {
/*
* This is a stop signal. Remove SIGCONT from all queues.
......@@ -976,7 +982,7 @@ __group_complete_signal(int sig, struct task_struct *p)
* Found a killable thread. If the signal will be fatal,
* then start taking the whole group down immediately.
*/
if (sig_fatal(p, sig) && !p->signal->group_exit &&
if (sig_fatal(p, sig) && !(p->signal->flags & SIGNAL_GROUP_EXIT) &&
!sigismember(&t->real_blocked, sig) &&
(sig == SIGKILL || !(t->ptrace & PT_PTRACED))) {
/*
......@@ -989,10 +995,9 @@ __group_complete_signal(int sig, struct task_struct *p)
* running and doing things after a slower
* thread has the fatal signal pending.
*/
p->signal->group_exit = 1;
p->signal->flags = SIGNAL_GROUP_EXIT;
p->signal->group_exit_code = sig;
p->signal->group_stop_count = 0;
p->signal->flags = 0;
t = p;
do {
sigaddset(&t->pending.signal, SIGKILL);
......@@ -1079,8 +1084,8 @@ void zap_other_threads(struct task_struct *p)
{
struct task_struct *t;
p->signal->flags = SIGNAL_GROUP_EXIT;
p->signal->group_stop_count = 0;
p->signal->flags = 0;
if (thread_group_empty(p))
return;
......@@ -1785,7 +1790,7 @@ static inline int handle_group_stop(void)
return 0;
}
if (current->signal->group_exit)
if (current->signal->flags & SIGNAL_GROUP_EXIT)
/*
* Group stop is so another thread can do a core dump,
* or else we are racing against a death signal.
......
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