Mercurial > hg > graal-compiler
comparison src/os/bsd/vm/os_bsd.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 | ef1818846c22 |
children | 836a62f43af9 a837fa3d3f86 b5c8a61d7fa0 |
comparison
equal
deleted
inserted
replaced
10404:d0add7016434 | 10405:f2110083203d |
---|---|
1850 // a counter for each possible signal value | 1850 // a counter for each possible signal value |
1851 static volatile jint pending_signals[NSIG+1] = { 0 }; | 1851 static volatile jint pending_signals[NSIG+1] = { 0 }; |
1852 | 1852 |
1853 // Bsd(POSIX) specific hand shaking semaphore. | 1853 // Bsd(POSIX) specific hand shaking semaphore. |
1854 #ifdef __APPLE__ | 1854 #ifdef __APPLE__ |
1855 static semaphore_t sig_sem; | 1855 typedef semaphore_t os_semaphore_t; |
1856 #define SEM_INIT(sem, value) semaphore_create(mach_task_self(), &sem, SYNC_POLICY_FIFO, value) | 1856 #define SEM_INIT(sem, value) semaphore_create(mach_task_self(), &sem, SYNC_POLICY_FIFO, value) |
1857 #define SEM_WAIT(sem) semaphore_wait(sem); | 1857 #define SEM_WAIT(sem) semaphore_wait(sem) |
1858 #define SEM_POST(sem) semaphore_signal(sem); | 1858 #define SEM_POST(sem) semaphore_signal(sem) |
1859 #define SEM_DESTROY(sem) semaphore_destroy(mach_task_self(), sem) | |
1859 #else | 1860 #else |
1860 static sem_t sig_sem; | 1861 typedef sem_t os_semaphore_t; |
1861 #define SEM_INIT(sem, value) sem_init(&sem, 0, value) | 1862 #define SEM_INIT(sem, value) sem_init(&sem, 0, value) |
1862 #define SEM_WAIT(sem) sem_wait(&sem); | 1863 #define SEM_WAIT(sem) sem_wait(&sem) |
1863 #define SEM_POST(sem) sem_post(&sem); | 1864 #define SEM_POST(sem) sem_post(&sem) |
1864 #endif | 1865 #define SEM_DESTROY(sem) sem_destroy(&sem) |
1866 #endif | |
1867 | |
1868 class Semaphore : public StackObj { | |
1869 public: | |
1870 Semaphore(); | |
1871 ~Semaphore(); | |
1872 void signal(); | |
1873 void wait(); | |
1874 bool trywait(); | |
1875 bool timedwait(unsigned int sec, int nsec); | |
1876 private: | |
1877 jlong currenttime() const; | |
1878 semaphore_t _semaphore; | |
1879 }; | |
1880 | |
1881 Semaphore::Semaphore() : _semaphore(0) { | |
1882 SEM_INIT(_semaphore, 0); | |
1883 } | |
1884 | |
1885 Semaphore::~Semaphore() { | |
1886 SEM_DESTROY(_semaphore); | |
1887 } | |
1888 | |
1889 void Semaphore::signal() { | |
1890 SEM_POST(_semaphore); | |
1891 } | |
1892 | |
1893 void Semaphore::wait() { | |
1894 SEM_WAIT(_semaphore); | |
1895 } | |
1896 | |
1897 jlong Semaphore::currenttime() const { | |
1898 struct timeval tv; | |
1899 gettimeofday(&tv, NULL); | |
1900 return (tv.tv_sec * NANOSECS_PER_SEC) + (tv.tv_usec * 1000); | |
1901 } | |
1902 | |
1903 #ifdef __APPLE__ | |
1904 bool Semaphore::trywait() { | |
1905 return timedwait(0, 0); | |
1906 } | |
1907 | |
1908 bool Semaphore::timedwait(unsigned int sec, int nsec) { | |
1909 kern_return_t kr = KERN_ABORTED; | |
1910 mach_timespec_t waitspec; | |
1911 waitspec.tv_sec = sec; | |
1912 waitspec.tv_nsec = nsec; | |
1913 | |
1914 jlong starttime = currenttime(); | |
1915 | |
1916 kr = semaphore_timedwait(_semaphore, waitspec); | |
1917 while (kr == KERN_ABORTED) { | |
1918 jlong totalwait = (sec * NANOSECS_PER_SEC) + nsec; | |
1919 | |
1920 jlong current = currenttime(); | |
1921 jlong passedtime = current - starttime; | |
1922 | |
1923 if (passedtime >= totalwait) { | |
1924 waitspec.tv_sec = 0; | |
1925 waitspec.tv_nsec = 0; | |
1926 } else { | |
1927 jlong waittime = totalwait - (current - starttime); | |
1928 waitspec.tv_sec = waittime / NANOSECS_PER_SEC; | |
1929 waitspec.tv_nsec = waittime % NANOSECS_PER_SEC; | |
1930 } | |
1931 | |
1932 kr = semaphore_timedwait(_semaphore, waitspec); | |
1933 } | |
1934 | |
1935 return kr == KERN_SUCCESS; | |
1936 } | |
1937 | |
1938 #else | |
1939 | |
1940 bool Semaphore::trywait() { | |
1941 return sem_trywait(&_semaphore) == 0; | |
1942 } | |
1943 | |
1944 bool Semaphore::timedwait(unsigned int sec, int nsec) { | |
1945 struct timespec ts; | |
1946 jlong endtime = unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec); | |
1947 | |
1948 while (1) { | |
1949 int result = sem_timedwait(&_semaphore, &ts); | |
1950 if (result == 0) { | |
1951 return true; | |
1952 } else if (errno == EINTR) { | |
1953 continue; | |
1954 } else if (errno == ETIMEDOUT) { | |
1955 return false; | |
1956 } else { | |
1957 return false; | |
1958 } | |
1959 } | |
1960 } | |
1961 | |
1962 #endif // __APPLE__ | |
1963 | |
1964 static os_semaphore_t sig_sem; | |
1965 static Semaphore sr_semaphore; | |
1865 | 1966 |
1866 void os::signal_init_pd() { | 1967 void os::signal_init_pd() { |
1867 // Initialize signal structures | 1968 // Initialize signal structures |
1868 ::memset((void*)pending_signals, 0, sizeof(pending_signals)); | 1969 ::memset((void*)pending_signals, 0, sizeof(pending_signals)); |
1869 | 1970 |
2614 // | 2715 // |
2615 | 2716 |
2616 static void resume_clear_context(OSThread *osthread) { | 2717 static void resume_clear_context(OSThread *osthread) { |
2617 osthread->set_ucontext(NULL); | 2718 osthread->set_ucontext(NULL); |
2618 osthread->set_siginfo(NULL); | 2719 osthread->set_siginfo(NULL); |
2619 | |
2620 // notify the suspend action is completed, we have now resumed | |
2621 osthread->sr.clear_suspended(); | |
2622 } | 2720 } |
2623 | 2721 |
2624 static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) { | 2722 static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) { |
2625 osthread->set_ucontext(context); | 2723 osthread->set_ucontext(context); |
2626 osthread->set_siginfo(siginfo); | 2724 osthread->set_siginfo(siginfo); |
2636 // interface point of view, but sigwait() prevents the signal hander | 2734 // interface point of view, but sigwait() prevents the signal hander |
2637 // from being run. libpthread would get very confused by not having | 2735 // from being run. libpthread would get very confused by not having |
2638 // its signal handlers run and prevents sigwait()'s use with the | 2736 // its signal handlers run and prevents sigwait()'s use with the |
2639 // mutex granting granting signal. | 2737 // mutex granting granting signal. |
2640 // | 2738 // |
2641 // Currently only ever called on the VMThread | 2739 // Currently only ever called on the VMThread or JavaThread |
2642 // | 2740 // |
2643 static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) { | 2741 static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) { |
2644 // Save and restore errno to avoid confusing native code with EINTR | 2742 // Save and restore errno to avoid confusing native code with EINTR |
2645 // after sigsuspend. | 2743 // after sigsuspend. |
2646 int old_errno = errno; | 2744 int old_errno = errno; |
2647 | 2745 |
2648 Thread* thread = Thread::current(); | 2746 Thread* thread = Thread::current(); |
2649 OSThread* osthread = thread->osthread(); | 2747 OSThread* osthread = thread->osthread(); |
2650 assert(thread->is_VM_thread(), "Must be VMThread"); | 2748 assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); |
2651 // read current suspend action | 2749 |
2652 int action = osthread->sr.suspend_action(); | 2750 os::SuspendResume::State current = osthread->sr.state(); |
2653 if (action == os::Bsd::SuspendResume::SR_SUSPEND) { | 2751 if (current == os::SuspendResume::SR_SUSPEND_REQUEST) { |
2654 suspend_save_context(osthread, siginfo, context); | 2752 suspend_save_context(osthread, siginfo, context); |
2655 | 2753 |
2656 // Notify the suspend action is about to be completed. do_suspend() | 2754 // attempt to switch the state, we assume we had a SUSPEND_REQUEST |
2657 // waits until SR_SUSPENDED is set and then returns. We will wait | 2755 os::SuspendResume::State state = osthread->sr.suspended(); |
2658 // here for a resume signal and that completes the suspend-other | 2756 if (state == os::SuspendResume::SR_SUSPENDED) { |
2659 // action. do_suspend/do_resume is always called as a pair from | 2757 sigset_t suspend_set; // signals for sigsuspend() |
2660 // the same thread - so there are no races | 2758 |
2661 | 2759 // get current set of blocked signals and unblock resume signal |
2662 // notify the caller | 2760 pthread_sigmask(SIG_BLOCK, NULL, &suspend_set); |
2663 osthread->sr.set_suspended(); | 2761 sigdelset(&suspend_set, SR_signum); |
2664 | 2762 |
2665 sigset_t suspend_set; // signals for sigsuspend() | 2763 sr_semaphore.signal(); |
2666 | 2764 // wait here until we are resumed |
2667 // get current set of blocked signals and unblock resume signal | 2765 while (1) { |
2668 pthread_sigmask(SIG_BLOCK, NULL, &suspend_set); | 2766 sigsuspend(&suspend_set); |
2669 sigdelset(&suspend_set, SR_signum); | 2767 |
2670 | 2768 os::SuspendResume::State result = osthread->sr.running(); |
2671 // wait here until we are resumed | 2769 if (result == os::SuspendResume::SR_RUNNING) { |
2672 do { | 2770 sr_semaphore.signal(); |
2673 sigsuspend(&suspend_set); | 2771 break; |
2674 // ignore all returns until we get a resume signal | 2772 } else if (result != os::SuspendResume::SR_SUSPENDED) { |
2675 } while (osthread->sr.suspend_action() != os::Bsd::SuspendResume::SR_CONTINUE); | 2773 ShouldNotReachHere(); |
2774 } | |
2775 } | |
2776 | |
2777 } else if (state == os::SuspendResume::SR_RUNNING) { | |
2778 // request was cancelled, continue | |
2779 } else { | |
2780 ShouldNotReachHere(); | |
2781 } | |
2676 | 2782 |
2677 resume_clear_context(osthread); | 2783 resume_clear_context(osthread); |
2678 | 2784 } else if (current == os::SuspendResume::SR_RUNNING) { |
2785 // request was cancelled, continue | |
2786 } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) { | |
2787 // ignore | |
2679 } else { | 2788 } else { |
2680 assert(action == os::Bsd::SuspendResume::SR_CONTINUE, "unexpected sr action"); | 2789 // ignore |
2681 // nothing special to do - just leave the handler | |
2682 } | 2790 } |
2683 | 2791 |
2684 errno = old_errno; | 2792 errno = old_errno; |
2685 } | 2793 } |
2686 | 2794 |
2720 // Save signal flag | 2828 // Save signal flag |
2721 os::Bsd::set_our_sigflags(SR_signum, act.sa_flags); | 2829 os::Bsd::set_our_sigflags(SR_signum, act.sa_flags); |
2722 return 0; | 2830 return 0; |
2723 } | 2831 } |
2724 | 2832 |
2833 static int sr_notify(OSThread* osthread) { | |
2834 int status = pthread_kill(osthread->pthread_id(), SR_signum); | |
2835 assert_status(status == 0, status, "pthread_kill"); | |
2836 return status; | |
2837 } | |
2838 | |
2839 // "Randomly" selected value for how long we want to spin | |
2840 // before bailing out on suspending a thread, also how often | |
2841 // we send a signal to a thread we want to resume | |
2842 static const int RANDOMLY_LARGE_INTEGER = 1000000; | |
2843 static const int RANDOMLY_LARGE_INTEGER2 = 100; | |
2725 | 2844 |
2726 // returns true on success and false on error - really an error is fatal | 2845 // returns true on success and false on error - really an error is fatal |
2727 // but this seems the normal response to library errors | 2846 // but this seems the normal response to library errors |
2728 static bool do_suspend(OSThread* osthread) { | 2847 static bool do_suspend(OSThread* osthread) { |
2848 assert(osthread->sr.is_running(), "thread should be running"); | |
2849 assert(!sr_semaphore.trywait(), "semaphore has invalid state"); | |
2850 | |
2729 // mark as suspended and send signal | 2851 // mark as suspended and send signal |
2730 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_SUSPEND); | 2852 if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) { |
2731 int status = pthread_kill(osthread->pthread_id(), SR_signum); | 2853 // failed to switch, state wasn't running? |
2732 assert_status(status == 0, status, "pthread_kill"); | 2854 ShouldNotReachHere(); |
2733 | |
2734 // check status and wait until notified of suspension | |
2735 if (status == 0) { | |
2736 for (int i = 0; !osthread->sr.is_suspended(); i++) { | |
2737 os::yield_all(i); | |
2738 } | |
2739 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE); | |
2740 return true; | |
2741 } | |
2742 else { | |
2743 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE); | |
2744 return false; | 2855 return false; |
2745 } | 2856 } |
2857 | |
2858 if (sr_notify(osthread) != 0) { | |
2859 ShouldNotReachHere(); | |
2860 } | |
2861 | |
2862 // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED | |
2863 while (true) { | |
2864 if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) { | |
2865 break; | |
2866 } else { | |
2867 // timeout | |
2868 os::SuspendResume::State cancelled = osthread->sr.cancel_suspend(); | |
2869 if (cancelled == os::SuspendResume::SR_RUNNING) { | |
2870 return false; | |
2871 } else if (cancelled == os::SuspendResume::SR_SUSPENDED) { | |
2872 // make sure that we consume the signal on the semaphore as well | |
2873 sr_semaphore.wait(); | |
2874 break; | |
2875 } else { | |
2876 ShouldNotReachHere(); | |
2877 return false; | |
2878 } | |
2879 } | |
2880 } | |
2881 | |
2882 guarantee(osthread->sr.is_suspended(), "Must be suspended"); | |
2883 return true; | |
2746 } | 2884 } |
2747 | 2885 |
2748 static void do_resume(OSThread* osthread) { | 2886 static void do_resume(OSThread* osthread) { |
2749 assert(osthread->sr.is_suspended(), "thread should be suspended"); | 2887 assert(osthread->sr.is_suspended(), "thread should be suspended"); |
2750 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_CONTINUE); | 2888 assert(!sr_semaphore.trywait(), "invalid semaphore state"); |
2751 | 2889 |
2752 int status = pthread_kill(osthread->pthread_id(), SR_signum); | 2890 if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) { |
2753 assert_status(status == 0, status, "pthread_kill"); | 2891 // failed to switch to WAKEUP_REQUEST |
2754 // check status and wait unit notified of resumption | 2892 ShouldNotReachHere(); |
2755 if (status == 0) { | 2893 return; |
2756 for (int i = 0; osthread->sr.is_suspended(); i++) { | 2894 } |
2757 os::yield_all(i); | 2895 |
2758 } | 2896 while (true) { |
2759 } | 2897 if (sr_notify(osthread) == 0) { |
2760 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE); | 2898 if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) { |
2899 if (osthread->sr.is_running()) { | |
2900 return; | |
2901 } | |
2902 } | |
2903 } else { | |
2904 ShouldNotReachHere(); | |
2905 } | |
2906 } | |
2907 | |
2908 guarantee(osthread->sr.is_running(), "Must be running!"); | |
2761 } | 2909 } |
2762 | 2910 |
2763 //////////////////////////////////////////////////////////////////////////////// | 2911 //////////////////////////////////////////////////////////////////////////////// |
2764 // interrupt support | 2912 // interrupt support |
2765 | 2913 |
3506 bool os::bind_to_processor(uint processor_id) { | 3654 bool os::bind_to_processor(uint processor_id) { |
3507 // Not yet implemented. | 3655 // Not yet implemented. |
3508 return false; | 3656 return false; |
3509 } | 3657 } |
3510 | 3658 |
3659 void os::SuspendedThreadTask::internal_do_task() { | |
3660 if (do_suspend(_thread->osthread())) { | |
3661 SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext()); | |
3662 do_task(context); | |
3663 do_resume(_thread->osthread()); | |
3664 } | |
3665 } | |
3666 | |
3511 /// | 3667 /// |
3668 class PcFetcher : public os::SuspendedThreadTask { | |
3669 public: | |
3670 PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {} | |
3671 ExtendedPC result(); | |
3672 protected: | |
3673 void do_task(const os::SuspendedThreadTaskContext& context); | |
3674 private: | |
3675 ExtendedPC _epc; | |
3676 }; | |
3677 | |
3678 ExtendedPC PcFetcher::result() { | |
3679 guarantee(is_done(), "task is not done yet."); | |
3680 return _epc; | |
3681 } | |
3682 | |
3683 void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) { | |
3684 Thread* thread = context.thread(); | |
3685 OSThread* osthread = thread->osthread(); | |
3686 if (osthread->ucontext() != NULL) { | |
3687 _epc = os::Bsd::ucontext_get_pc((ucontext_t *) context.ucontext()); | |
3688 } else { | |
3689 // NULL context is unexpected, double-check this is the VMThread | |
3690 guarantee(thread->is_VM_thread(), "can only be called for VMThread"); | |
3691 } | |
3692 } | |
3512 | 3693 |
3513 // Suspends the target using the signal mechanism and then grabs the PC before | 3694 // Suspends the target using the signal mechanism and then grabs the PC before |
3514 // resuming the target. Used by the flat-profiler only | 3695 // resuming the target. Used by the flat-profiler only |
3515 ExtendedPC os::get_thread_pc(Thread* thread) { | 3696 ExtendedPC os::get_thread_pc(Thread* thread) { |
3516 // Make sure that it is called by the watcher for the VMThread | 3697 // Make sure that it is called by the watcher for the VMThread |
3517 assert(Thread::current()->is_Watcher_thread(), "Must be watcher"); | 3698 assert(Thread::current()->is_Watcher_thread(), "Must be watcher"); |
3518 assert(thread->is_VM_thread(), "Can only be called for VMThread"); | 3699 assert(thread->is_VM_thread(), "Can only be called for VMThread"); |
3519 | 3700 |
3520 ExtendedPC epc; | 3701 PcFetcher fetcher(thread); |
3521 | 3702 fetcher.run(); |
3522 OSThread* osthread = thread->osthread(); | 3703 return fetcher.result(); |
3523 if (do_suspend(osthread)) { | |
3524 if (osthread->ucontext() != NULL) { | |
3525 epc = os::Bsd::ucontext_get_pc(osthread->ucontext()); | |
3526 } else { | |
3527 // NULL context is unexpected, double-check this is the VMThread | |
3528 guarantee(thread->is_VM_thread(), "can only be called for VMThread"); | |
3529 } | |
3530 do_resume(osthread); | |
3531 } | |
3532 // failure means pthread_kill failed for some reason - arguably this is | |
3533 // a fatal problem, but such problems are ignored elsewhere | |
3534 | |
3535 return epc; | |
3536 } | 3704 } |
3537 | 3705 |
3538 int os::Bsd::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime) | 3706 int os::Bsd::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime) |
3539 { | 3707 { |
3540 return pthread_cond_timedwait(_cond, _mutex, _abstime); | 3708 return pthread_cond_timedwait(_cond, _mutex, _abstime); |
4515 // Truncate if theoretical string was longer than bufferSize | 4683 // Truncate if theoretical string was longer than bufferSize |
4516 n = MIN2(n, (int)bufferSize); | 4684 n = MIN2(n, (int)bufferSize); |
4517 | 4685 |
4518 return n; | 4686 return n; |
4519 } | 4687 } |
4688 |