hotspot/src/os/linux/vm/os_linux.cpp
changeset 47106 bed18a111b90
parent 47089 27050b653624
equal deleted inserted replaced
47104:6bdc0c9c44af 47106:bed18a111b90
  3998 void os::hint_no_preempt() {}
  3998 void os::hint_no_preempt() {}
  3999 
  3999 
  4000 ////////////////////////////////////////////////////////////////////////////////
  4000 ////////////////////////////////////////////////////////////////////////////////
  4001 // suspend/resume support
  4001 // suspend/resume support
  4002 
  4002 
  4003 //  the low-level signal-based suspend/resume support is a remnant from the
  4003 //  The low-level signal-based suspend/resume support is a remnant from the
  4004 //  old VM-suspension that used to be for java-suspension, safepoints etc,
  4004 //  old VM-suspension that used to be for java-suspension, safepoints etc,
  4005 //  within hotspot. Now there is a single use-case for this:
  4005 //  within hotspot. Currently used by JFR's OSThreadSampler
  4006 //    - calling get_thread_pc() on the VMThread by the flat-profiler task
  4006 //
  4007 //      that runs in the watcher thread.
       
  4008 //  The remaining code is greatly simplified from the more general suspension
  4007 //  The remaining code is greatly simplified from the more general suspension
  4009 //  code that used to be used.
  4008 //  code that used to be used.
  4010 //
  4009 //
  4011 //  The protocol is quite simple:
  4010 //  The protocol is quite simple:
  4012 //  - suspend:
  4011 //  - suspend:
  4018 //      - sets target osthread state to continue
  4017 //      - sets target osthread state to continue
  4019 //      - sends signal to end the sigsuspend loop in the SR_handler
  4018 //      - sends signal to end the sigsuspend loop in the SR_handler
  4020 //
  4019 //
  4021 //  Note that the SR_lock plays no role in this suspend/resume protocol,
  4020 //  Note that the SR_lock plays no role in this suspend/resume protocol,
  4022 //  but is checked for NULL in SR_handler as a thread termination indicator.
  4021 //  but is checked for NULL in SR_handler as a thread termination indicator.
       
  4022 //  The SR_lock is, however, used by JavaThread::java_suspend()/java_resume() APIs.
       
  4023 //
       
  4024 //  Note that resume_clear_context() and suspend_save_context() are needed
       
  4025 //  by SR_handler(), so that fetch_frame_from_ucontext() works,
       
  4026 //  which in part is used by:
       
  4027 //    - Forte Analyzer: AsyncGetCallTrace()
       
  4028 //    - StackBanging: get_frame_at_stack_banging_point()
  4023 
  4029 
  4024 static void resume_clear_context(OSThread *osthread) {
  4030 static void resume_clear_context(OSThread *osthread) {
  4025   osthread->set_ucontext(NULL);
  4031   osthread->set_ucontext(NULL);
  4026   osthread->set_siginfo(NULL);
  4032   osthread->set_siginfo(NULL);
  4027 }
  4033 }
  5056   if (do_suspend(_thread->osthread())) {
  5062   if (do_suspend(_thread->osthread())) {
  5057     SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
  5063     SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
  5058     do_task(context);
  5064     do_task(context);
  5059     do_resume(_thread->osthread());
  5065     do_resume(_thread->osthread());
  5060   }
  5066   }
  5061 }
       
  5062 
       
  5063 class PcFetcher : public os::SuspendedThreadTask {
       
  5064  public:
       
  5065   PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
       
  5066   ExtendedPC result();
       
  5067  protected:
       
  5068   void do_task(const os::SuspendedThreadTaskContext& context);
       
  5069  private:
       
  5070   ExtendedPC _epc;
       
  5071 };
       
  5072 
       
  5073 ExtendedPC PcFetcher::result() {
       
  5074   guarantee(is_done(), "task is not done yet.");
       
  5075   return _epc;
       
  5076 }
       
  5077 
       
  5078 void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
       
  5079   Thread* thread = context.thread();
       
  5080   OSThread* osthread = thread->osthread();
       
  5081   if (osthread->ucontext() != NULL) {
       
  5082     _epc = os::Linux::ucontext_get_pc((const ucontext_t *) context.ucontext());
       
  5083   } else {
       
  5084     // NULL context is unexpected, double-check this is the VMThread
       
  5085     guarantee(thread->is_VM_thread(), "can only be called for VMThread");
       
  5086   }
       
  5087 }
       
  5088 
       
  5089 // Suspends the target using the signal mechanism and then grabs the PC before
       
  5090 // resuming the target. Used by the flat-profiler only
       
  5091 ExtendedPC os::get_thread_pc(Thread* thread) {
       
  5092   // Make sure that it is called by the watcher for the VMThread
       
  5093   assert(Thread::current()->is_Watcher_thread(), "Must be watcher");
       
  5094   assert(thread->is_VM_thread(), "Can only be called for VMThread");
       
  5095 
       
  5096   PcFetcher fetcher(thread);
       
  5097   fetcher.run();
       
  5098   return fetcher.result();
       
  5099 }
  5067 }
  5100 
  5068 
  5101 ////////////////////////////////////////////////////////////////////////////////
  5069 ////////////////////////////////////////////////////////////////////////////////
  5102 // debug support
  5070 // debug support
  5103 
  5071