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. Needed for fetch_frame_from_ucontext(), which is used by:
3505 //    - Forte Analyzer: AsyncGetCallTrace()
3506 //    - StackBanging: get_frame_at_stack_banging_point()
3507 //    - JFR: get_topframe()-->....-->get_valid_uc_in_signal_handler()
3508 //
3509 //  The remaining code is greatly simplified from the more general suspension
3510 //  code that used to be used.
3511 //
3512 //  The protocol is quite simple:
3513 //  - suspend:
3514 //      - sends a signal to the target thread
3515 //      - polls the suspend state of the osthread using a yield loop
3516 //      - target thread signal handler (SR_handler) sets suspend state
3517 //        and blocks in sigsuspend until continued
3518 //  - resume:
3519 //      - sets target osthread state to continue
3520 //      - sends signal to end the sigsuspend loop in the SR_handler
3521 //
3522 //  Note that the SR_lock plays no role in this suspend/resume protocol,
3523 //  but is checked for NULL in SR_handler as a thread termination indicator.
3524 //
3525 
3526 static void resume_clear_context(OSThread *osthread) {
3527   osthread->set_ucontext(NULL);
3528 }
3529 
3530 static void suspend_save_context(OSThread *osthread, ucontext_t* context) {
3531   osthread->set_ucontext(context);
3532 }
3533 
3534 static PosixSemaphore sr_semaphore;
3535 
3536 void os::Solaris::SR_handler(Thread* thread, ucontext_t* context) {
3537   // Save and restore errno to avoid confusing native code with EINTR
3538   // after sigsuspend.
3539   int old_errno = errno;
3540 
3541   OSThread* osthread = thread->osthread();
3542   assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
3543 
3544   os::SuspendResume::State current = osthread->sr.state();
3545   if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
3546     suspend_save_context(osthread, context);
3547 
3548     // attempt to switch the state, we assume we had a SUSPEND_REQUEST
3549     os::SuspendResume::State state = osthread->sr.suspended();
3550     if (state == os::SuspendResume::SR_SUSPENDED) {
3551       sigset_t suspend_set;  // signals for sigsuspend()
3552 
3553       // get current set of blocked signals and unblock resume signal
3554       pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
3555       sigdelset(&suspend_set, ASYNC_SIGNAL);
3556 
3557       sr_semaphore.signal();
3558       // wait here until we are resumed
3559       while (1) {
3560         sigsuspend(&suspend_set);
3561 
3562         os::SuspendResume::State result = osthread->sr.running();
3563         if (result == os::SuspendResume::SR_RUNNING) {
3564           sr_semaphore.signal();
3565           break;
3566         }


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







































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