diff options
author | Oleg Nesterov <oleg@tv-sign.ru> | 2008-04-30 03:52:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-30 11:29:34 -0400 |
commit | ad16a4606939ce1bedb79c87e412467be803e990 (patch) | |
tree | d9b1e96c2520c9c08660c4dfd5258b2acdc8d1ef /kernel | |
parent | fc321d2e60d6f4eee17206612d0b50519f526daf (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')
-rw-r--r-- | kernel/signal.c | 28 |
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 | */ |
567 | static void handle_stop_signal(int sig, struct task_struct *p) | 567 | static 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 | ||