2678 // should be avoided.)
2679 //
2680 // Note: sigwait() is a more natural fit than sigsuspend() from an
2681 // interface point of view, but sigwait() prevents the signal hander
2682 // from being run. libpthread would get very confused by not having
2683 // its signal handlers run and prevents sigwait()'s use with the
2684 // mutex granting granting signal.
2685 //
2686 // Currently only ever called on the VMThread
2687 //
2688 static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
2689 // Save and restore errno to avoid confusing native code with EINTR
2690 // after sigsuspend.
2691 int old_errno = errno;
2692
2693 Thread* thread = Thread::current();
2694 OSThread* osthread = thread->osthread();
2695 assert(thread->is_VM_thread(), "Must be VMThread");
2696 // read current suspend action
2697 int action = osthread->sr.suspend_action();
2698 if (action == SR_SUSPEND) {
2699 suspend_save_context(osthread, siginfo, context);
2700
2701 // Notify the suspend action is about to be completed. do_suspend()
2702 // waits until SR_SUSPENDED is set and then returns. We will wait
2703 // here for a resume signal and that completes the suspend-other
2704 // action. do_suspend/do_resume is always called as a pair from
2705 // the same thread - so there are no races
2706
2707 // notify the caller
2708 osthread->sr.set_suspended();
2709
2710 sigset_t suspend_set; // signals for sigsuspend()
2711
2712 // get current set of blocked signals and unblock resume signal
2713 pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
2714 sigdelset(&suspend_set, SR_signum);
2715
2716 // wait here until we are resumed
2717 do {
2718 sigsuspend(&suspend_set);
2719 // ignore all returns until we get a resume signal
2720 } while (osthread->sr.suspend_action() != SR_CONTINUE);
2721
2722 resume_clear_context(osthread);
2723
2724 } else {
2725 assert(action == SR_CONTINUE, "unexpected sr action");
2726 // nothing special to do - just leave the handler
2727 }
2728
2729 errno = old_errno;
2730 }
2731
2732
2733 static int SR_initialize() {
2734 struct sigaction act;
2735 char *s;
2736 /* Get signal number to use for suspend/resume */
2737 if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
2738 int sig = ::strtol(s, 0, 10);
2739 if (sig > 0 || sig < NSIG) {
2740 SR_signum = sig;
2741 }
2742 }
2743
2744 assert(SR_signum > SIGSEGV && SR_signum > SIGBUS,
2745 "SR_signum must be greater than max(SIGSEGV, SIGBUS), see 4355769");
2759 pthread_sigmask(SIG_BLOCK, NULL, &act.sa_mask);
2760
2761 if (sigaction(SR_signum, &act, 0) == -1) {
2762 return -1;
2763 }
2764
2765 // Save signal flag
2766 os::Bsd::set_our_sigflags(SR_signum, act.sa_flags);
2767 return 0;
2768 }
2769
2770 static int SR_finalize() {
2771 return 0;
2772 }
2773
2774
2775 // returns true on success and false on error - really an error is fatal
2776 // but this seems the normal response to library errors
2777 static bool do_suspend(OSThread* osthread) {
2778 // mark as suspended and send signal
2779 osthread->sr.set_suspend_action(SR_SUSPEND);
2780 int status = pthread_kill(osthread->pthread_id(), SR_signum);
2781 assert_status(status == 0, status, "pthread_kill");
2782
2783 // check status and wait until notified of suspension
2784 if (status == 0) {
2785 for (int i = 0; !osthread->sr.is_suspended(); i++) {
2786 os::yield_all(i);
2787 }
2788 osthread->sr.set_suspend_action(SR_NONE);
2789 return true;
2790 }
2791 else {
2792 osthread->sr.set_suspend_action(SR_NONE);
2793 return false;
2794 }
2795 }
2796
2797 static void do_resume(OSThread* osthread) {
2798 assert(osthread->sr.is_suspended(), "thread should be suspended");
2799 osthread->sr.set_suspend_action(SR_CONTINUE);
2800
2801 int status = pthread_kill(osthread->pthread_id(), SR_signum);
2802 assert_status(status == 0, status, "pthread_kill");
2803 // check status and wait unit notified of resumption
2804 if (status == 0) {
2805 for (int i = 0; osthread->sr.is_suspended(); i++) {
2806 os::yield_all(i);
2807 }
2808 }
2809 osthread->sr.set_suspend_action(SR_NONE);
2810 }
2811
2812 ////////////////////////////////////////////////////////////////////////////////
2813 // interrupt support
2814
2815 void os::interrupt(Thread* thread) {
2816 assert(Thread::current() == thread || Threads_lock->owned_by_self(),
2817 "possibility of dangling Thread pointer");
2818
2819 OSThread* osthread = thread->osthread();
2820
2821 if (!osthread->interrupted()) {
2822 osthread->set_interrupted(true);
2823 // More than one thread can get here with the same value of osthread,
2824 // resulting in multiple notifications. We do, however, want the store
2825 // to interrupted() to be visible to other threads before we execute unpark().
2826 OrderAccess::fence();
2827 ParkEvent * const slp = thread->_SleepEvent ;
2828 if (slp != NULL) slp->unpark() ;
2829 }
|
2678 // should be avoided.)
2679 //
2680 // Note: sigwait() is a more natural fit than sigsuspend() from an
2681 // interface point of view, but sigwait() prevents the signal hander
2682 // from being run. libpthread would get very confused by not having
2683 // its signal handlers run and prevents sigwait()'s use with the
2684 // mutex granting granting signal.
2685 //
2686 // Currently only ever called on the VMThread
2687 //
2688 static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
2689 // Save and restore errno to avoid confusing native code with EINTR
2690 // after sigsuspend.
2691 int old_errno = errno;
2692
2693 Thread* thread = Thread::current();
2694 OSThread* osthread = thread->osthread();
2695 assert(thread->is_VM_thread(), "Must be VMThread");
2696 // read current suspend action
2697 int action = osthread->sr.suspend_action();
2698 if (action == os::Bsd::SuspendResume::SR_SUSPEND) {
2699 suspend_save_context(osthread, siginfo, context);
2700
2701 // Notify the suspend action is about to be completed. do_suspend()
2702 // waits until SR_SUSPENDED is set and then returns. We will wait
2703 // here for a resume signal and that completes the suspend-other
2704 // action. do_suspend/do_resume is always called as a pair from
2705 // the same thread - so there are no races
2706
2707 // notify the caller
2708 osthread->sr.set_suspended();
2709
2710 sigset_t suspend_set; // signals for sigsuspend()
2711
2712 // get current set of blocked signals and unblock resume signal
2713 pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
2714 sigdelset(&suspend_set, SR_signum);
2715
2716 // wait here until we are resumed
2717 do {
2718 sigsuspend(&suspend_set);
2719 // ignore all returns until we get a resume signal
2720 } while (osthread->sr.suspend_action() != os::Bsd::SuspendResume::SR_CONTINUE);
2721
2722 resume_clear_context(osthread);
2723
2724 } else {
2725 assert(action == os::Bsd::SuspendResume::SR_CONTINUE, "unexpected sr action");
2726 // nothing special to do - just leave the handler
2727 }
2728
2729 errno = old_errno;
2730 }
2731
2732
2733 static int SR_initialize() {
2734 struct sigaction act;
2735 char *s;
2736 /* Get signal number to use for suspend/resume */
2737 if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
2738 int sig = ::strtol(s, 0, 10);
2739 if (sig > 0 || sig < NSIG) {
2740 SR_signum = sig;
2741 }
2742 }
2743
2744 assert(SR_signum > SIGSEGV && SR_signum > SIGBUS,
2745 "SR_signum must be greater than max(SIGSEGV, SIGBUS), see 4355769");
2759 pthread_sigmask(SIG_BLOCK, NULL, &act.sa_mask);
2760
2761 if (sigaction(SR_signum, &act, 0) == -1) {
2762 return -1;
2763 }
2764
2765 // Save signal flag
2766 os::Bsd::set_our_sigflags(SR_signum, act.sa_flags);
2767 return 0;
2768 }
2769
2770 static int SR_finalize() {
2771 return 0;
2772 }
2773
2774
2775 // returns true on success and false on error - really an error is fatal
2776 // but this seems the normal response to library errors
2777 static bool do_suspend(OSThread* osthread) {
2778 // mark as suspended and send signal
2779 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_SUSPEND);
2780 int status = pthread_kill(osthread->pthread_id(), SR_signum);
2781 assert_status(status == 0, status, "pthread_kill");
2782
2783 // check status and wait until notified of suspension
2784 if (status == 0) {
2785 for (int i = 0; !osthread->sr.is_suspended(); i++) {
2786 os::yield_all(i);
2787 }
2788 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
2789 return true;
2790 }
2791 else {
2792 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
2793 return false;
2794 }
2795 }
2796
2797 static void do_resume(OSThread* osthread) {
2798 assert(osthread->sr.is_suspended(), "thread should be suspended");
2799 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_CONTINUE);
2800
2801 int status = pthread_kill(osthread->pthread_id(), SR_signum);
2802 assert_status(status == 0, status, "pthread_kill");
2803 // check status and wait unit notified of resumption
2804 if (status == 0) {
2805 for (int i = 0; osthread->sr.is_suspended(); i++) {
2806 os::yield_all(i);
2807 }
2808 }
2809 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
2810 }
2811
2812 ////////////////////////////////////////////////////////////////////////////////
2813 // interrupt support
2814
2815 void os::interrupt(Thread* thread) {
2816 assert(Thread::current() == thread || Threads_lock->owned_by_self(),
2817 "possibility of dangling Thread pointer");
2818
2819 OSThread* osthread = thread->osthread();
2820
2821 if (!osthread->interrupted()) {
2822 osthread->set_interrupted(true);
2823 // More than one thread can get here with the same value of osthread,
2824 // resulting in multiple notifications. We do, however, want the store
2825 // to interrupted() to be visible to other threads before we execute unpark().
2826 OrderAccess::fence();
2827 ParkEvent * const slp = thread->_SleepEvent ;
2828 if (slp != NULL) slp->unpark() ;
2829 }
|