Mercurial > hg > graal-compiler
comparison src/os/linux/vm/os_linux.cpp @ 10405:f2110083203d
8005849: JEP 167: Event-Based JVM Tracing
Reviewed-by: acorn, coleenp, sla
Contributed-by: Karen Kinnear <karen.kinnear@oracle.com>, Bengt Rutisson <bengt.rutisson@oracle.com>, Calvin Cheung <calvin.cheung@oracle.com>, Erik Gahlin <erik.gahlin@oracle.com>, Erik Helin <erik.helin@oracle.com>, Jesper Wilhelmsson <jesper.wilhelmsson@oracle.com>, Keith McGuigan <keith.mcguigan@oracle.com>, Mattias Tobiasson <mattias.tobiasson@oracle.com>, Markus Gronlund <markus.gronlund@oracle.com>, Mikael Auno <mikael.auno@oracle.com>, Nils Eliasson <nils.eliasson@oracle.com>, Nils Loodin <nils.loodin@oracle.com>, Rickard Backman <rickard.backman@oracle.com>, Staffan Larsen <staffan.larsen@oracle.com>, Stefan Karlsson <stefan.karlsson@oracle.com>, Yekaterina Kantserova <yekaterina.kantserova@oracle.com>
author | sla |
---|---|
date | Mon, 10 Jun 2013 11:30:51 +0200 |
parents | e72f7eecc96d |
children | 836a62f43af9 a837fa3d3f86 b5c8a61d7fa0 |
comparison
equal
deleted
inserted
replaced
10404:d0add7016434 | 10405:f2110083203d |
---|---|
148 static int SR_signum = SIGUSR2; | 148 static int SR_signum = SIGUSR2; |
149 sigset_t SR_sigset; | 149 sigset_t SR_sigset; |
150 | 150 |
151 /* Used to protect dlsym() calls */ | 151 /* Used to protect dlsym() calls */ |
152 static pthread_mutex_t dl_mutex; | 152 static pthread_mutex_t dl_mutex; |
153 | |
154 // Declarations | |
155 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time); | |
153 | 156 |
154 #ifdef JAVASE_EMBEDDED | 157 #ifdef JAVASE_EMBEDDED |
155 class MemNotifyThread: public Thread { | 158 class MemNotifyThread: public Thread { |
156 friend class VMStructs; | 159 friend class VMStructs; |
157 public: | 160 public: |
2405 | 2408 |
2406 void* os::user_handler() { | 2409 void* os::user_handler() { |
2407 return CAST_FROM_FN_PTR(void*, UserHandler); | 2410 return CAST_FROM_FN_PTR(void*, UserHandler); |
2408 } | 2411 } |
2409 | 2412 |
2413 class Semaphore : public StackObj { | |
2414 public: | |
2415 Semaphore(); | |
2416 ~Semaphore(); | |
2417 void signal(); | |
2418 void wait(); | |
2419 bool trywait(); | |
2420 bool timedwait(unsigned int sec, int nsec); | |
2421 private: | |
2422 sem_t _semaphore; | |
2423 }; | |
2424 | |
2425 | |
2426 Semaphore::Semaphore() { | |
2427 sem_init(&_semaphore, 0, 0); | |
2428 } | |
2429 | |
2430 Semaphore::~Semaphore() { | |
2431 sem_destroy(&_semaphore); | |
2432 } | |
2433 | |
2434 void Semaphore::signal() { | |
2435 sem_post(&_semaphore); | |
2436 } | |
2437 | |
2438 void Semaphore::wait() { | |
2439 sem_wait(&_semaphore); | |
2440 } | |
2441 | |
2442 bool Semaphore::trywait() { | |
2443 return sem_trywait(&_semaphore) == 0; | |
2444 } | |
2445 | |
2446 bool Semaphore::timedwait(unsigned int sec, int nsec) { | |
2447 struct timespec ts; | |
2448 unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec); | |
2449 | |
2450 while (1) { | |
2451 int result = sem_timedwait(&_semaphore, &ts); | |
2452 if (result == 0) { | |
2453 return true; | |
2454 } else if (errno == EINTR) { | |
2455 continue; | |
2456 } else if (errno == ETIMEDOUT) { | |
2457 return false; | |
2458 } else { | |
2459 return false; | |
2460 } | |
2461 } | |
2462 } | |
2463 | |
2410 extern "C" { | 2464 extern "C" { |
2411 typedef void (*sa_handler_t)(int); | 2465 typedef void (*sa_handler_t)(int); |
2412 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); | 2466 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); |
2413 } | 2467 } |
2414 | 2468 |
2444 // a counter for each possible signal value | 2498 // a counter for each possible signal value |
2445 static volatile jint pending_signals[NSIG+1] = { 0 }; | 2499 static volatile jint pending_signals[NSIG+1] = { 0 }; |
2446 | 2500 |
2447 // Linux(POSIX) specific hand shaking semaphore. | 2501 // Linux(POSIX) specific hand shaking semaphore. |
2448 static sem_t sig_sem; | 2502 static sem_t sig_sem; |
2503 static Semaphore sr_semaphore; | |
2449 | 2504 |
2450 void os::signal_init_pd() { | 2505 void os::signal_init_pd() { |
2451 // Initialize signal structures | 2506 // Initialize signal structures |
2452 ::memset((void*)pending_signals, 0, sizeof(pending_signals)); | 2507 ::memset((void*)pending_signals, 0, sizeof(pending_signals)); |
2453 | 2508 |
3557 // | 3612 // |
3558 | 3613 |
3559 static void resume_clear_context(OSThread *osthread) { | 3614 static void resume_clear_context(OSThread *osthread) { |
3560 osthread->set_ucontext(NULL); | 3615 osthread->set_ucontext(NULL); |
3561 osthread->set_siginfo(NULL); | 3616 osthread->set_siginfo(NULL); |
3562 | |
3563 // notify the suspend action is completed, we have now resumed | |
3564 osthread->sr.clear_suspended(); | |
3565 } | 3617 } |
3566 | 3618 |
3567 static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) { | 3619 static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) { |
3568 osthread->set_ucontext(context); | 3620 osthread->set_ucontext(context); |
3569 osthread->set_siginfo(siginfo); | 3621 osthread->set_siginfo(siginfo); |
3579 // interface point of view, but sigwait() prevents the signal hander | 3631 // interface point of view, but sigwait() prevents the signal hander |
3580 // from being run. libpthread would get very confused by not having | 3632 // from being run. libpthread would get very confused by not having |
3581 // its signal handlers run and prevents sigwait()'s use with the | 3633 // its signal handlers run and prevents sigwait()'s use with the |
3582 // mutex granting granting signal. | 3634 // mutex granting granting signal. |
3583 // | 3635 // |
3584 // Currently only ever called on the VMThread | 3636 // Currently only ever called on the VMThread and JavaThreads (PC sampling) |
3585 // | 3637 // |
3586 static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) { | 3638 static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) { |
3587 // Save and restore errno to avoid confusing native code with EINTR | 3639 // Save and restore errno to avoid confusing native code with EINTR |
3588 // after sigsuspend. | 3640 // after sigsuspend. |
3589 int old_errno = errno; | 3641 int old_errno = errno; |
3590 | 3642 |
3591 Thread* thread = Thread::current(); | 3643 Thread* thread = Thread::current(); |
3592 OSThread* osthread = thread->osthread(); | 3644 OSThread* osthread = thread->osthread(); |
3593 assert(thread->is_VM_thread(), "Must be VMThread"); | 3645 assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); |
3594 // read current suspend action | 3646 |
3595 int action = osthread->sr.suspend_action(); | 3647 os::SuspendResume::State current = osthread->sr.state(); |
3596 if (action == os::Linux::SuspendResume::SR_SUSPEND) { | 3648 if (current == os::SuspendResume::SR_SUSPEND_REQUEST) { |
3597 suspend_save_context(osthread, siginfo, context); | 3649 suspend_save_context(osthread, siginfo, context); |
3598 | 3650 |
3599 // Notify the suspend action is about to be completed. do_suspend() | 3651 // attempt to switch the state, we assume we had a SUSPEND_REQUEST |
3600 // waits until SR_SUSPENDED is set and then returns. We will wait | 3652 os::SuspendResume::State state = osthread->sr.suspended(); |
3601 // here for a resume signal and that completes the suspend-other | 3653 if (state == os::SuspendResume::SR_SUSPENDED) { |
3602 // action. do_suspend/do_resume is always called as a pair from | 3654 sigset_t suspend_set; // signals for sigsuspend() |
3603 // the same thread - so there are no races | 3655 |
3604 | 3656 // get current set of blocked signals and unblock resume signal |
3605 // notify the caller | 3657 pthread_sigmask(SIG_BLOCK, NULL, &suspend_set); |
3606 osthread->sr.set_suspended(); | 3658 sigdelset(&suspend_set, SR_signum); |
3607 | 3659 |
3608 sigset_t suspend_set; // signals for sigsuspend() | 3660 sr_semaphore.signal(); |
3609 | 3661 // wait here until we are resumed |
3610 // get current set of blocked signals and unblock resume signal | 3662 while (1) { |
3611 pthread_sigmask(SIG_BLOCK, NULL, &suspend_set); | 3663 sigsuspend(&suspend_set); |
3612 sigdelset(&suspend_set, SR_signum); | 3664 |
3613 | 3665 os::SuspendResume::State result = osthread->sr.running(); |
3614 // wait here until we are resumed | 3666 if (result == os::SuspendResume::SR_RUNNING) { |
3615 do { | 3667 sr_semaphore.signal(); |
3616 sigsuspend(&suspend_set); | 3668 break; |
3617 // ignore all returns until we get a resume signal | 3669 } |
3618 } while (osthread->sr.suspend_action() != os::Linux::SuspendResume::SR_CONTINUE); | 3670 } |
3671 | |
3672 } else if (state == os::SuspendResume::SR_RUNNING) { | |
3673 // request was cancelled, continue | |
3674 } else { | |
3675 ShouldNotReachHere(); | |
3676 } | |
3619 | 3677 |
3620 resume_clear_context(osthread); | 3678 resume_clear_context(osthread); |
3621 | 3679 } else if (current == os::SuspendResume::SR_RUNNING) { |
3680 // request was cancelled, continue | |
3681 } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) { | |
3682 // ignore | |
3622 } else { | 3683 } else { |
3623 assert(action == os::Linux::SuspendResume::SR_CONTINUE, "unexpected sr action"); | 3684 // ignore |
3624 // nothing special to do - just leave the handler | |
3625 } | 3685 } |
3626 | 3686 |
3627 errno = old_errno; | 3687 errno = old_errno; |
3628 } | 3688 } |
3629 | 3689 |
3663 // Save signal flag | 3723 // Save signal flag |
3664 os::Linux::set_our_sigflags(SR_signum, act.sa_flags); | 3724 os::Linux::set_our_sigflags(SR_signum, act.sa_flags); |
3665 return 0; | 3725 return 0; |
3666 } | 3726 } |
3667 | 3727 |
3728 static int sr_notify(OSThread* osthread) { | |
3729 int status = pthread_kill(osthread->pthread_id(), SR_signum); | |
3730 assert_status(status == 0, status, "pthread_kill"); | |
3731 return status; | |
3732 } | |
3733 | |
3734 // "Randomly" selected value for how long we want to spin | |
3735 // before bailing out on suspending a thread, also how often | |
3736 // we send a signal to a thread we want to resume | |
3737 static const int RANDOMLY_LARGE_INTEGER = 1000000; | |
3738 static const int RANDOMLY_LARGE_INTEGER2 = 100; | |
3668 | 3739 |
3669 // returns true on success and false on error - really an error is fatal | 3740 // returns true on success and false on error - really an error is fatal |
3670 // but this seems the normal response to library errors | 3741 // but this seems the normal response to library errors |
3671 static bool do_suspend(OSThread* osthread) { | 3742 static bool do_suspend(OSThread* osthread) { |
3743 assert(osthread->sr.is_running(), "thread should be running"); | |
3744 assert(!sr_semaphore.trywait(), "semaphore has invalid state"); | |
3745 | |
3672 // mark as suspended and send signal | 3746 // mark as suspended and send signal |
3673 osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_SUSPEND); | 3747 if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) { |
3674 int status = pthread_kill(osthread->pthread_id(), SR_signum); | 3748 // failed to switch, state wasn't running? |
3675 assert_status(status == 0, status, "pthread_kill"); | 3749 ShouldNotReachHere(); |
3676 | |
3677 // check status and wait until notified of suspension | |
3678 if (status == 0) { | |
3679 for (int i = 0; !osthread->sr.is_suspended(); i++) { | |
3680 os::yield_all(i); | |
3681 } | |
3682 osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE); | |
3683 return true; | |
3684 } | |
3685 else { | |
3686 osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE); | |
3687 return false; | 3750 return false; |
3688 } | 3751 } |
3752 | |
3753 if (sr_notify(osthread) != 0) { | |
3754 ShouldNotReachHere(); | |
3755 } | |
3756 | |
3757 // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED | |
3758 while (true) { | |
3759 if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) { | |
3760 break; | |
3761 } else { | |
3762 // timeout | |
3763 os::SuspendResume::State cancelled = osthread->sr.cancel_suspend(); | |
3764 if (cancelled == os::SuspendResume::SR_RUNNING) { | |
3765 return false; | |
3766 } else if (cancelled == os::SuspendResume::SR_SUSPENDED) { | |
3767 // make sure that we consume the signal on the semaphore as well | |
3768 sr_semaphore.wait(); | |
3769 break; | |
3770 } else { | |
3771 ShouldNotReachHere(); | |
3772 return false; | |
3773 } | |
3774 } | |
3775 } | |
3776 | |
3777 guarantee(osthread->sr.is_suspended(), "Must be suspended"); | |
3778 return true; | |
3689 } | 3779 } |
3690 | 3780 |
3691 static void do_resume(OSThread* osthread) { | 3781 static void do_resume(OSThread* osthread) { |
3692 assert(osthread->sr.is_suspended(), "thread should be suspended"); | 3782 assert(osthread->sr.is_suspended(), "thread should be suspended"); |
3693 osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_CONTINUE); | 3783 assert(!sr_semaphore.trywait(), "invalid semaphore state"); |
3694 | 3784 |
3695 int status = pthread_kill(osthread->pthread_id(), SR_signum); | 3785 if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) { |
3696 assert_status(status == 0, status, "pthread_kill"); | 3786 // failed to switch to WAKEUP_REQUEST |
3697 // check status and wait unit notified of resumption | 3787 ShouldNotReachHere(); |
3698 if (status == 0) { | 3788 return; |
3699 for (int i = 0; osthread->sr.is_suspended(); i++) { | 3789 } |
3700 os::yield_all(i); | 3790 |
3701 } | 3791 while (true) { |
3702 } | 3792 if (sr_notify(osthread) == 0) { |
3703 osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE); | 3793 if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) { |
3794 if (osthread->sr.is_running()) { | |
3795 return; | |
3796 } | |
3797 } | |
3798 } else { | |
3799 ShouldNotReachHere(); | |
3800 } | |
3801 } | |
3802 | |
3803 guarantee(osthread->sr.is_running(), "Must be running!"); | |
3704 } | 3804 } |
3705 | 3805 |
3706 //////////////////////////////////////////////////////////////////////////////// | 3806 //////////////////////////////////////////////////////////////////////////////// |
3707 // interrupt support | 3807 // interrupt support |
3708 | 3808 |
4470 return false; | 4570 return false; |
4471 } | 4571 } |
4472 | 4572 |
4473 /// | 4573 /// |
4474 | 4574 |
4575 void os::SuspendedThreadTask::internal_do_task() { | |
4576 if (do_suspend(_thread->osthread())) { | |
4577 SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext()); | |
4578 do_task(context); | |
4579 do_resume(_thread->osthread()); | |
4580 } | |
4581 } | |
4582 | |
4583 class PcFetcher : public os::SuspendedThreadTask { | |
4584 public: | |
4585 PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {} | |
4586 ExtendedPC result(); | |
4587 protected: | |
4588 void do_task(const os::SuspendedThreadTaskContext& context); | |
4589 private: | |
4590 ExtendedPC _epc; | |
4591 }; | |
4592 | |
4593 ExtendedPC PcFetcher::result() { | |
4594 guarantee(is_done(), "task is not done yet."); | |
4595 return _epc; | |
4596 } | |
4597 | |
4598 void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) { | |
4599 Thread* thread = context.thread(); | |
4600 OSThread* osthread = thread->osthread(); | |
4601 if (osthread->ucontext() != NULL) { | |
4602 _epc = os::Linux::ucontext_get_pc((ucontext_t *) context.ucontext()); | |
4603 } else { | |
4604 // NULL context is unexpected, double-check this is the VMThread | |
4605 guarantee(thread->is_VM_thread(), "can only be called for VMThread"); | |
4606 } | |
4607 } | |
4608 | |
4475 // Suspends the target using the signal mechanism and then grabs the PC before | 4609 // Suspends the target using the signal mechanism and then grabs the PC before |
4476 // resuming the target. Used by the flat-profiler only | 4610 // resuming the target. Used by the flat-profiler only |
4477 ExtendedPC os::get_thread_pc(Thread* thread) { | 4611 ExtendedPC os::get_thread_pc(Thread* thread) { |
4478 // Make sure that it is called by the watcher for the VMThread | 4612 // Make sure that it is called by the watcher for the VMThread |
4479 assert(Thread::current()->is_Watcher_thread(), "Must be watcher"); | 4613 assert(Thread::current()->is_Watcher_thread(), "Must be watcher"); |
4480 assert(thread->is_VM_thread(), "Can only be called for VMThread"); | 4614 assert(thread->is_VM_thread(), "Can only be called for VMThread"); |
4481 | 4615 |
4482 ExtendedPC epc; | 4616 PcFetcher fetcher(thread); |
4483 | 4617 fetcher.run(); |
4484 OSThread* osthread = thread->osthread(); | 4618 return fetcher.result(); |
4485 if (do_suspend(osthread)) { | |
4486 if (osthread->ucontext() != NULL) { | |
4487 epc = os::Linux::ucontext_get_pc(osthread->ucontext()); | |
4488 } else { | |
4489 // NULL context is unexpected, double-check this is the VMThread | |
4490 guarantee(thread->is_VM_thread(), "can only be called for VMThread"); | |
4491 } | |
4492 do_resume(osthread); | |
4493 } | |
4494 // failure means pthread_kill failed for some reason - arguably this is | |
4495 // a fatal problem, but such problems are ignored elsewhere | |
4496 | |
4497 return epc; | |
4498 } | 4619 } |
4499 | 4620 |
4500 int os::Linux::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime) | 4621 int os::Linux::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime) |
4501 { | 4622 { |
4502 if (is_NPTL()) { | 4623 if (is_NPTL()) { |
5614 | 5735 |
5615 if (memnotify_thread() == NULL) { | 5736 if (memnotify_thread() == NULL) { |
5616 new MemNotifyThread(fd); | 5737 new MemNotifyThread(fd); |
5617 } | 5738 } |
5618 } | 5739 } |
5740 | |
5619 #endif // JAVASE_EMBEDDED | 5741 #endif // JAVASE_EMBEDDED |