src/os/solaris/vm/os_solaris.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File webrev Sdiff src/os/solaris/vm

src/os/solaris/vm/os_solaris.cpp

Print this page




3479   int p;
3480   if (!UseThreadPriorities) {
3481     *priority_ptr = NormalPriority;
3482     return OS_OK;
3483   }
3484   int status = thr_getprio(thread->osthread()->thread_id(), &p);
3485   if (status != 0) {
3486     return OS_ERR;
3487   }
3488   *priority_ptr = p;
3489   return OS_OK;
3490 }
3491 
3492 
3493 // Hint to the underlying OS that a task switch would not be good.
3494 // Void return because it's a hint and can fail.
3495 void os::hint_no_preempt() {
3496   schedctl_start(schedctl_init());
3497 }
3498 































3499 static void resume_clear_context(OSThread *osthread) {
3500   osthread->set_ucontext(NULL);
3501 }
3502 
3503 static void suspend_save_context(OSThread *osthread, ucontext_t* context) {
3504   osthread->set_ucontext(context);
3505 }
3506 
3507 static PosixSemaphore sr_semaphore;
3508 
3509 void os::Solaris::SR_handler(Thread* thread, ucontext_t* uc) {
3510   // Save and restore errno to avoid confusing native code with EINTR
3511   // after sigsuspend.
3512   int old_errno = errno;
3513 
3514   OSThread* osthread = thread->osthread();
3515   assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
3516 
3517   os::SuspendResume::State current = osthread->sr.state();
3518   if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
3519     suspend_save_context(osthread, uc);
3520 
3521     // attempt to switch the state, we assume we had a SUSPEND_REQUEST
3522     os::SuspendResume::State state = osthread->sr.suspended();
3523     if (state == os::SuspendResume::SR_SUSPENDED) {
3524       sigset_t suspend_set;  // signals for sigsuspend()
3525 
3526       // get current set of blocked signals and unblock resume signal
3527       pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
3528       sigdelset(&suspend_set, ASYNC_SIGNAL);
3529 
3530       sr_semaphore.signal();
3531       // wait here until we are resumed
3532       while (1) {
3533         sigsuspend(&suspend_set);
3534 
3535         os::SuspendResume::State result = osthread->sr.running();
3536         if (result == os::SuspendResume::SR_RUNNING) {
3537           sr_semaphore.signal();
3538           break;
3539         }


3646         if (osthread->sr.is_running()) {
3647           return;
3648         }
3649       }
3650     } else {
3651       ShouldNotReachHere();
3652     }
3653   }
3654 
3655   guarantee(osthread->sr.is_running(), "Must be running!");
3656 }
3657 
3658 void os::SuspendedThreadTask::internal_do_task() {
3659   if (do_suspend(_thread->osthread())) {
3660     SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
3661     do_task(context);
3662     do_resume(_thread->osthread());
3663   }
3664 }
3665 
3666 class PcFetcher : public os::SuspendedThreadTask {
3667  public:
3668   PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
3669   ExtendedPC result();
3670  protected:
3671   void do_task(const os::SuspendedThreadTaskContext& context);
3672  private:
3673   ExtendedPC _epc;
3674 };
3675 
3676 ExtendedPC PcFetcher::result() {
3677   guarantee(is_done(), "task is not done yet.");
3678   return _epc;
3679 }
3680 
3681 void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
3682   Thread* thread = context.thread();
3683   OSThread* osthread = thread->osthread();
3684   if (osthread->ucontext() != NULL) {
3685     _epc = os::Solaris::ucontext_get_pc((const ucontext_t *) context.ucontext());
3686   } else {
3687     // NULL context is unexpected, double-check this is the VMThread
3688     guarantee(thread->is_VM_thread(), "can only be called for VMThread");
3689   }
3690 }
3691 
3692 // A lightweight implementation that does not suspend the target thread and
3693 // thus returns only a hint. Used for profiling only!
3694 ExtendedPC os::get_thread_pc(Thread* thread) {
3695   // Make sure that it is called by the watcher and the Threads lock is owned.
3696   assert(Thread::current()->is_Watcher_thread(), "Must be watcher and own Threads_lock");
3697   // For now, is only used to profile the VM Thread
3698   assert(thread->is_VM_thread(), "Can only be called for VMThread");
3699   PcFetcher fetcher(thread);
3700   fetcher.run();
3701   return fetcher.result();
3702 }
3703 
3704 
3705 // This does not do anything on Solaris. This is basically a hook for being
3706 // able to use structured exception handling (thread-local exception filters) on, e.g., Win32.
3707 void os::os_exception_wrapper(java_call_t f, JavaValue* value,
3708                               const methodHandle& method, JavaCallArguments* args,
3709                               Thread* thread) {
3710   f(value, method, args, thread);
3711 }
3712 
3713 // This routine may be used by user applications as a "hook" to catch signals.
3714 // The user-defined signal handler must pass unrecognized signals to this
3715 // routine, and if it returns true (non-zero), then the signal handler must
3716 // return immediately.  If the flag "abort_if_unrecognized" is true, then this
3717 // routine will never retun false (zero), but instead will execute a VM panic
3718 // routine kill the process.
3719 //
3720 // If this routine returns false, it is OK to call it again.  This allows
3721 // the user-defined signal handler to perform checks either before or after
3722 // the VM performs its own checks.  Naturally, the user code would be making
3723 // a serious error if it tried to handle an exception (such as a null check
3724 // or breakpoint) that the VM was generating for its own correct operation.




3479   int p;
3480   if (!UseThreadPriorities) {
3481     *priority_ptr = NormalPriority;
3482     return OS_OK;
3483   }
3484   int status = thr_getprio(thread->osthread()->thread_id(), &p);
3485   if (status != 0) {
3486     return OS_ERR;
3487   }
3488   *priority_ptr = p;
3489   return OS_OK;
3490 }
3491 
3492 
3493 // Hint to the underlying OS that a task switch would not be good.
3494 // Void return because it's a hint and can fail.
3495 void os::hint_no_preempt() {
3496   schedctl_start(schedctl_init());
3497 }
3498 
3499 ////////////////////////////////////////////////////////////////////////////////
3500 // suspend/resume support
3501 
3502 //  The low-level signal-based suspend/resume support is a remnant from the
3503 //  old VM-suspension that used to be for java-suspension, safepoints etc,
3504 //  within hotspot. Currently used by JFR's OSThreadSampler
3505 //
3506 //  The remaining code is greatly simplified from the more general suspension
3507 //  code that used to be used.
3508 //
3509 //  The protocol is quite simple:
3510 //  - suspend:
3511 //      - sends a signal to the target thread
3512 //      - polls the suspend state of the osthread using a yield loop
3513 //      - target thread signal handler (SR_handler) sets suspend state
3514 //        and blocks in sigsuspend until continued
3515 //  - resume:
3516 //      - sets target osthread state to continue
3517 //      - sends signal to end the sigsuspend loop in the SR_handler
3518 //
3519 //  Note that the SR_lock plays no role in this suspend/resume protocol,
3520 //  but is checked for NULL in SR_handler as a thread termination indicator.
3521 //  The SR_lock is, however, used by JavaThread::java_suspend()/java_resume() APIs.
3522 //
3523 //  Note that resume_clear_context() and suspend_save_context() are needed
3524 //  by SR_handler(), so that fetch_frame_from_ucontext() works,
3525 //  which in part is used by:
3526 //    - Forte Analyzer: AsyncGetCallTrace()
3527 //    - StackBanging: get_frame_at_stack_banging_point()
3528 //    - JFR: get_topframe()-->....-->get_valid_uc_in_signal_handler()
3529 
3530 static void resume_clear_context(OSThread *osthread) {
3531   osthread->set_ucontext(NULL);
3532 }
3533 
3534 static void suspend_save_context(OSThread *osthread, ucontext_t* context) {
3535   osthread->set_ucontext(context);
3536 }
3537 
3538 static PosixSemaphore sr_semaphore;
3539 
3540 void os::Solaris::SR_handler(Thread* thread, ucontext_t* context) {
3541   // Save and restore errno to avoid confusing native code with EINTR
3542   // after sigsuspend.
3543   int old_errno = errno;
3544 
3545   OSThread* osthread = thread->osthread();
3546   assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
3547 
3548   os::SuspendResume::State current = osthread->sr.state();
3549   if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
3550     suspend_save_context(osthread, context);
3551 
3552     // attempt to switch the state, we assume we had a SUSPEND_REQUEST
3553     os::SuspendResume::State state = osthread->sr.suspended();
3554     if (state == os::SuspendResume::SR_SUSPENDED) {
3555       sigset_t suspend_set;  // signals for sigsuspend()
3556 
3557       // get current set of blocked signals and unblock resume signal
3558       pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
3559       sigdelset(&suspend_set, ASYNC_SIGNAL);
3560 
3561       sr_semaphore.signal();
3562       // wait here until we are resumed
3563       while (1) {
3564         sigsuspend(&suspend_set);
3565 
3566         os::SuspendResume::State result = osthread->sr.running();
3567         if (result == os::SuspendResume::SR_RUNNING) {
3568           sr_semaphore.signal();
3569           break;
3570         }


3677         if (osthread->sr.is_running()) {
3678           return;
3679         }
3680       }
3681     } else {
3682       ShouldNotReachHere();
3683     }
3684   }
3685 
3686   guarantee(osthread->sr.is_running(), "Must be running!");
3687 }
3688 
3689 void os::SuspendedThreadTask::internal_do_task() {
3690   if (do_suspend(_thread->osthread())) {
3691     SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
3692     do_task(context);
3693     do_resume(_thread->osthread());
3694   }
3695 }
3696 







































3697 // This does not do anything on Solaris. This is basically a hook for being
3698 // able to use structured exception handling (thread-local exception filters) on, e.g., Win32.
3699 void os::os_exception_wrapper(java_call_t f, JavaValue* value,
3700                               const methodHandle& method, JavaCallArguments* args,
3701                               Thread* thread) {
3702   f(value, method, args, thread);
3703 }
3704 
3705 // This routine may be used by user applications as a "hook" to catch signals.
3706 // The user-defined signal handler must pass unrecognized signals to this
3707 // routine, and if it returns true (non-zero), then the signal handler must
3708 // return immediately.  If the flag "abort_if_unrecognized" is true, then this
3709 // routine will never retun false (zero), but instead will execute a VM panic
3710 // routine kill the process.
3711 //
3712 // If this routine returns false, it is OK to call it again.  This allows
3713 // the user-defined signal handler to perform checks either before or after
3714 // the VM performs its own checks.  Naturally, the user code would be making
3715 // a serious error if it tried to handle an exception (such as a null check
3716 // or breakpoint) that the VM was generating for its own correct operation.


src/os/solaris/vm/os_solaris.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File