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