src/os/solaris/vm/os_solaris.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
webrev Cdiff src/os/solaris/vm/os_solaris.cpp
src/os/solaris/vm/os_solaris.cpp
Print this page
*** 3494,3524 ****
// Void return because it's a hint and can fail.
void os::hint_no_preempt() {
schedctl_start(schedctl_init());
}
static void resume_clear_context(OSThread *osthread) {
osthread->set_ucontext(NULL);
}
static void suspend_save_context(OSThread *osthread, ucontext_t* context) {
osthread->set_ucontext(context);
}
static PosixSemaphore sr_semaphore;
! void os::Solaris::SR_handler(Thread* thread, ucontext_t* uc) {
// Save and restore errno to avoid confusing native code with EINTR
// after sigsuspend.
int old_errno = errno;
OSThread* osthread = thread->osthread();
assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
os::SuspendResume::State current = osthread->sr.state();
if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
! suspend_save_context(osthread, uc);
// attempt to switch the state, we assume we had a SUSPEND_REQUEST
os::SuspendResume::State state = osthread->sr.suspended();
if (state == os::SuspendResume::SR_SUSPENDED) {
sigset_t suspend_set; // signals for sigsuspend()
--- 3494,3551 ----
// Void return because it's a hint and can fail.
void os::hint_no_preempt() {
schedctl_start(schedctl_init());
}
+ ////////////////////////////////////////////////////////////////////////////////
+ // suspend/resume support
+
+ // The low-level signal-based suspend/resume support is a remnant from the
+ // old VM-suspension that used to be for java-suspension, safepoints etc,
+ // within hotspot. Needed for fetch_frame_from_ucontext(), which is used by:
+ // - Forte Analyzer: AsyncGetCallTrace()
+ // - StackBanging: get_frame_at_stack_banging_point()
+ // - JFR: get_topframe()-->....-->get_valid_uc_in_signal_handler()
+ //
+ // The remaining code is greatly simplified from the more general suspension
+ // code that used to be used.
+ //
+ // The protocol is quite simple:
+ // - suspend:
+ // - sends a signal to the target thread
+ // - polls the suspend state of the osthread using a yield loop
+ // - target thread signal handler (SR_handler) sets suspend state
+ // and blocks in sigsuspend until continued
+ // - resume:
+ // - sets target osthread state to continue
+ // - sends signal to end the sigsuspend loop in the SR_handler
+ //
+ // Note that the SR_lock plays no role in this suspend/resume protocol,
+ // but is checked for NULL in SR_handler as a thread termination indicator.
+ //
+
static void resume_clear_context(OSThread *osthread) {
osthread->set_ucontext(NULL);
}
static void suspend_save_context(OSThread *osthread, ucontext_t* context) {
osthread->set_ucontext(context);
}
static PosixSemaphore sr_semaphore;
! void os::Solaris::SR_handler(Thread* thread, ucontext_t* context) {
// Save and restore errno to avoid confusing native code with EINTR
// after sigsuspend.
int old_errno = errno;
OSThread* osthread = thread->osthread();
assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
os::SuspendResume::State current = osthread->sr.state();
if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
! suspend_save_context(osthread, context);
// attempt to switch the state, we assume we had a SUSPEND_REQUEST
os::SuspendResume::State state = osthread->sr.suspended();
if (state == os::SuspendResume::SR_SUSPENDED) {
sigset_t suspend_set; // signals for sigsuspend()
*** 3661,3709 ****
do_task(context);
do_resume(_thread->osthread());
}
}
- class PcFetcher : public os::SuspendedThreadTask {
- public:
- PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
- ExtendedPC result();
- protected:
- void do_task(const os::SuspendedThreadTaskContext& context);
- private:
- ExtendedPC _epc;
- };
-
- ExtendedPC PcFetcher::result() {
- guarantee(is_done(), "task is not done yet.");
- return _epc;
- }
-
- void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
- Thread* thread = context.thread();
- OSThread* osthread = thread->osthread();
- if (osthread->ucontext() != NULL) {
- _epc = os::Solaris::ucontext_get_pc((const ucontext_t *) context.ucontext());
- } else {
- // NULL context is unexpected, double-check this is the VMThread
- guarantee(thread->is_VM_thread(), "can only be called for VMThread");
- }
- }
-
- // A lightweight implementation that does not suspend the target thread and
- // thus returns only a hint. Used for profiling only!
- ExtendedPC os::get_thread_pc(Thread* thread) {
- // Make sure that it is called by the watcher and the Threads lock is owned.
- assert(Thread::current()->is_Watcher_thread(), "Must be watcher and own Threads_lock");
- // For now, is only used to profile the VM Thread
- assert(thread->is_VM_thread(), "Can only be called for VMThread");
- PcFetcher fetcher(thread);
- fetcher.run();
- return fetcher.result();
- }
-
-
// This does not do anything on Solaris. This is basically a hook for being
// able to use structured exception handling (thread-local exception filters) on, e.g., Win32.
void os::os_exception_wrapper(java_call_t f, JavaValue* value,
const methodHandle& method, JavaCallArguments* args,
Thread* thread) {
--- 3688,3697 ----
src/os/solaris/vm/os_solaris.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File