aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@tv-sign.ru>2008-04-30 03:52:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:34 -0400
commitad16a4606939ce1bedb79c87e412467be803e990 (patch)
treed9b1e96c2520c9c08660c4dfd5258b2acdc8d1ef /kernel/signal.c
parentfc321d2e60d6f4eee17206612d0b50519f526daf (diff)
handle_stop_signal: use the cached p->signal value
Cache the value of p->signal, and change the code to use while_each_thread() helper. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Cc: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c28
1 files changed, 13 insertions, 15 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index dee8cc927a63..b266fa46402a 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -566,9 +566,10 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, int why);
566 */ 566 */
567static void handle_stop_signal(int sig, struct task_struct *p) 567static void handle_stop_signal(int sig, struct task_struct *p)
568{ 568{
569 struct signal_struct *signal = p->signal;
569 struct task_struct *t; 570 struct task_struct *t;
570 571
571 if (p->signal->flags & SIGNAL_GROUP_EXIT) 572 if (signal->flags & SIGNAL_GROUP_EXIT)
572 /* 573 /*
573 * The process is in the middle of dying already. 574 * The process is in the middle of dying already.
574 */ 575 */
@@ -578,19 +579,18 @@ static void handle_stop_signal(int sig, struct task_struct *p)
578 /* 579 /*
579 * This is a stop signal. Remove SIGCONT from all queues. 580 * This is a stop signal. Remove SIGCONT from all queues.
580 */ 581 */
581 rm_from_queue(sigmask(SIGCONT), &p->signal->shared_pending); 582 rm_from_queue(sigmask(SIGCONT), &signal->shared_pending);
582 t = p; 583 t = p;
583 do { 584 do {
584 rm_from_queue(sigmask(SIGCONT), &t->pending); 585 rm_from_queue(sigmask(SIGCONT), &t->pending);
585 t = next_thread(t); 586 } while_each_thread(p, t);
586 } while (t != p);
587 } else if (sig == SIGCONT) { 587 } else if (sig == SIGCONT) {
588 unsigned int why; 588 unsigned int why;
589 /* 589 /*
590 * Remove all stop signals from all queues, 590 * Remove all stop signals from all queues,
591 * and wake all threads. 591 * and wake all threads.
592 */ 592 */
593 rm_from_queue(SIG_KERNEL_STOP_MASK, &p->signal->shared_pending); 593 rm_from_queue(SIG_KERNEL_STOP_MASK, &signal->shared_pending);
594 t = p; 594 t = p;
595 do { 595 do {
596 unsigned int state; 596 unsigned int state;
@@ -615,9 +615,7 @@ static void handle_stop_signal(int sig, struct task_struct *p)
615 state |= TASK_INTERRUPTIBLE; 615 state |= TASK_INTERRUPTIBLE;
616 } 616 }
617 wake_up_state(t, state); 617 wake_up_state(t, state);
618 618 } while_each_thread(p, t);
619 t = next_thread(t);
620 } while (t != p);
621 619
622 /* 620 /*
623 * Notify the parent with CLD_CONTINUED if we were stopped. 621 * Notify the parent with CLD_CONTINUED if we were stopped.
@@ -628,29 +626,29 @@ static void handle_stop_signal(int sig, struct task_struct *p)
628 * CLD_CONTINUED was dropped. 626 * CLD_CONTINUED was dropped.
629 */ 627 */
630 why = 0; 628 why = 0;
631 if (p->signal->flags & SIGNAL_STOP_STOPPED) 629 if (signal->flags & SIGNAL_STOP_STOPPED)
632 why |= SIGNAL_CLD_CONTINUED; 630 why |= SIGNAL_CLD_CONTINUED;
633 else if (p->signal->group_stop_count) 631 else if (signal->group_stop_count)
634 why |= SIGNAL_CLD_STOPPED; 632 why |= SIGNAL_CLD_STOPPED;
635 633
636 if (why) { 634 if (why) {
637 p->signal->flags = why | SIGNAL_STOP_CONTINUED; 635 signal->flags = why | SIGNAL_STOP_CONTINUED;
638 p->signal->group_stop_count = 0; 636 signal->group_stop_count = 0;
639 p->signal->group_exit_code = 0; 637 signal->group_exit_code = 0;
640 } else { 638 } else {
641 /* 639 /*
642 * We are not stopped, but there could be a stop 640 * We are not stopped, but there could be a stop
643 * signal in the middle of being processed after 641 * signal in the middle of being processed after
644 * being removed from the queue. Clear that too. 642 * being removed from the queue. Clear that too.
645 */ 643 */
646 p->signal->flags &= ~SIGNAL_STOP_DEQUEUED; 644 signal->flags &= ~SIGNAL_STOP_DEQUEUED;
647 } 645 }
648 } else if (sig == SIGKILL) { 646 } else if (sig == SIGKILL) {
649 /* 647 /*
650 * Make sure that any pending stop signal already dequeued 648 * Make sure that any pending stop signal already dequeued
651 * is undone by the wakeup for SIGKILL. 649 * is undone by the wakeup for SIGKILL.
652 */ 650 */
653 p->signal->flags &= ~SIGNAL_STOP_DEQUEUED; 651 signal->flags &= ~SIGNAL_STOP_DEQUEUED;
654 } 652 }
655} 653}
656 654