src/os/bsd/vm/os_bsd.cpp

Print this page
rev 4205 : Fix non-PCH build on Linux, Windows and MacOS X


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   }