Mercurial > hg > graal-jvmci-8
comparison src/os/bsd/vm/os_bsd.cpp @ 14392:b5c8a61d7fa0
Merge
author | kvn |
---|---|
date | Fri, 21 Jun 2013 15:56:24 -0700 |
parents | 0f03ff49c720 f2110083203d |
children | f4f6ae481e1a |
comparison
equal
deleted
inserted
replaced
14391:d2907f74462e | 14392:b5c8a61d7fa0 |
---|---|
624 | 624 |
625 | 625 |
626 ////////////////////////////////////////////////////////////////////////////// | 626 ////////////////////////////////////////////////////////////////////////////// |
627 // create new thread | 627 // create new thread |
628 | 628 |
629 static address highest_vm_reserved_address(); | |
630 | |
631 // check if it's safe to start a new thread | 629 // check if it's safe to start a new thread |
632 static bool _thread_safety_check(Thread* thread) { | 630 static bool _thread_safety_check(Thread* thread) { |
633 return true; | 631 return true; |
634 } | 632 } |
635 | 633 |
933 | 931 |
934 jlong os::elapsed_frequency() { | 932 jlong os::elapsed_frequency() { |
935 return (1000 * 1000); | 933 return (1000 * 1000); |
936 } | 934 } |
937 | 935 |
938 // XXX: For now, code this as if BSD does not support vtime. | 936 bool os::supports_vtime() { return true; } |
939 bool os::supports_vtime() { return false; } | |
940 bool os::enable_vtime() { return false; } | 937 bool os::enable_vtime() { return false; } |
941 bool os::vtime_enabled() { return false; } | 938 bool os::vtime_enabled() { return false; } |
939 | |
942 double os::elapsedVTime() { | 940 double os::elapsedVTime() { |
943 // better than nothing, but not much | 941 // better than nothing, but not much |
944 return elapsedTime(); | 942 return elapsedTime(); |
945 } | 943 } |
946 | 944 |
1852 // a counter for each possible signal value | 1850 // a counter for each possible signal value |
1853 static volatile jint pending_signals[NSIG+1] = { 0 }; | 1851 static volatile jint pending_signals[NSIG+1] = { 0 }; |
1854 | 1852 |
1855 // Bsd(POSIX) specific hand shaking semaphore. | 1853 // Bsd(POSIX) specific hand shaking semaphore. |
1856 #ifdef __APPLE__ | 1854 #ifdef __APPLE__ |
1857 static semaphore_t sig_sem; | 1855 typedef semaphore_t os_semaphore_t; |
1858 #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) |
1859 #define SEM_WAIT(sem) semaphore_wait(sem); | 1857 #define SEM_WAIT(sem) semaphore_wait(sem) |
1860 #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) | |
1861 #else | 1860 #else |
1862 static sem_t sig_sem; | 1861 typedef sem_t os_semaphore_t; |
1863 #define SEM_INIT(sem, value) sem_init(&sem, 0, value) | 1862 #define SEM_INIT(sem, value) sem_init(&sem, 0, value) |
1864 #define SEM_WAIT(sem) sem_wait(&sem); | 1863 #define SEM_WAIT(sem) sem_wait(&sem) |
1865 #define SEM_POST(sem) sem_post(&sem); | 1864 #define SEM_POST(sem) sem_post(&sem) |
1866 #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; | |
1867 | 1966 |
1868 void os::signal_init_pd() { | 1967 void os::signal_init_pd() { |
1869 // Initialize signal structures | 1968 // Initialize signal structures |
1870 ::memset((void*)pending_signals, 0, sizeof(pending_signals)); | 1969 ::memset((void*)pending_signals, 0, sizeof(pending_signals)); |
1871 | 1970 |
2110 | 2209 |
2111 bool os::pd_release_memory(char* addr, size_t size) { | 2210 bool os::pd_release_memory(char* addr, size_t size) { |
2112 return anon_munmap(addr, size); | 2211 return anon_munmap(addr, size); |
2113 } | 2212 } |
2114 | 2213 |
2115 static address highest_vm_reserved_address() { | |
2116 return _highest_vm_reserved_address; | |
2117 } | |
2118 | |
2119 static bool bsd_mprotect(char* addr, size_t size, int prot) { | 2214 static bool bsd_mprotect(char* addr, size_t size, int prot) { |
2120 // Bsd wants the mprotect address argument to be page aligned. | 2215 // Bsd wants the mprotect address argument to be page aligned. |
2121 char* bottom = (char*)align_size_down((intptr_t)addr, os::Bsd::page_size()); | 2216 char* bottom = (char*)align_size_down((intptr_t)addr, os::Bsd::page_size()); |
2122 | 2217 |
2123 // According to SUSv3, mprotect() should only be used with mappings | 2218 // According to SUSv3, mprotect() should only be used with mappings |
2155 return bsd_mprotect(addr, size, PROT_READ|PROT_WRITE); | 2250 return bsd_mprotect(addr, size, PROT_READ|PROT_WRITE); |
2156 } | 2251 } |
2157 | 2252 |
2158 bool os::Bsd::hugetlbfs_sanity_check(bool warn, size_t page_size) { | 2253 bool os::Bsd::hugetlbfs_sanity_check(bool warn, size_t page_size) { |
2159 return false; | 2254 return false; |
2160 } | |
2161 | |
2162 /* | |
2163 * Set the coredump_filter bits to include largepages in core dump (bit 6) | |
2164 * | |
2165 * From the coredump_filter documentation: | |
2166 * | |
2167 * - (bit 0) anonymous private memory | |
2168 * - (bit 1) anonymous shared memory | |
2169 * - (bit 2) file-backed private memory | |
2170 * - (bit 3) file-backed shared memory | |
2171 * - (bit 4) ELF header pages in file-backed private memory areas (it is | |
2172 * effective only if the bit 2 is cleared) | |
2173 * - (bit 5) hugetlb private memory | |
2174 * - (bit 6) hugetlb shared memory | |
2175 */ | |
2176 static void set_coredump_filter(void) { | |
2177 FILE *f; | |
2178 long cdm; | |
2179 | |
2180 if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) { | |
2181 return; | |
2182 } | |
2183 | |
2184 if (fscanf(f, "%lx", &cdm) != 1) { | |
2185 fclose(f); | |
2186 return; | |
2187 } | |
2188 | |
2189 rewind(f); | |
2190 | |
2191 if ((cdm & LARGEPAGES_BIT) == 0) { | |
2192 cdm |= LARGEPAGES_BIT; | |
2193 fprintf(f, "%#lx", cdm); | |
2194 } | |
2195 | |
2196 fclose(f); | |
2197 } | 2255 } |
2198 | 2256 |
2199 // Large page support | 2257 // Large page support |
2200 | 2258 |
2201 static size_t _large_page_size = 0; | 2259 static size_t _large_page_size = 0; |
2657 // | 2715 // |
2658 | 2716 |
2659 static void resume_clear_context(OSThread *osthread) { | 2717 static void resume_clear_context(OSThread *osthread) { |
2660 osthread->set_ucontext(NULL); | 2718 osthread->set_ucontext(NULL); |
2661 osthread->set_siginfo(NULL); | 2719 osthread->set_siginfo(NULL); |
2662 | |
2663 // notify the suspend action is completed, we have now resumed | |
2664 osthread->sr.clear_suspended(); | |
2665 } | 2720 } |
2666 | 2721 |
2667 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) { |
2668 osthread->set_ucontext(context); | 2723 osthread->set_ucontext(context); |
2669 osthread->set_siginfo(siginfo); | 2724 osthread->set_siginfo(siginfo); |
2679 // interface point of view, but sigwait() prevents the signal hander | 2734 // interface point of view, but sigwait() prevents the signal hander |
2680 // from being run. libpthread would get very confused by not having | 2735 // from being run. libpthread would get very confused by not having |
2681 // its signal handlers run and prevents sigwait()'s use with the | 2736 // its signal handlers run and prevents sigwait()'s use with the |
2682 // mutex granting granting signal. | 2737 // mutex granting granting signal. |
2683 // | 2738 // |
2684 // Currently only ever called on the VMThread | 2739 // Currently only ever called on the VMThread or JavaThread |
2685 // | 2740 // |
2686 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) { |
2687 // Save and restore errno to avoid confusing native code with EINTR | 2742 // Save and restore errno to avoid confusing native code with EINTR |
2688 // after sigsuspend. | 2743 // after sigsuspend. |
2689 int old_errno = errno; | 2744 int old_errno = errno; |
2690 | 2745 |
2691 Thread* thread = Thread::current(); | 2746 Thread* thread = Thread::current(); |
2692 OSThread* osthread = thread->osthread(); | 2747 OSThread* osthread = thread->osthread(); |
2693 assert(thread->is_VM_thread(), "Must be VMThread"); | 2748 assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); |
2694 // read current suspend action | 2749 |
2695 int action = osthread->sr.suspend_action(); | 2750 os::SuspendResume::State current = osthread->sr.state(); |
2696 if (action == os::Bsd::SuspendResume::SR_SUSPEND) { | 2751 if (current == os::SuspendResume::SR_SUSPEND_REQUEST) { |
2697 suspend_save_context(osthread, siginfo, context); | 2752 suspend_save_context(osthread, siginfo, context); |
2698 | 2753 |
2699 // Notify the suspend action is about to be completed. do_suspend() | 2754 // attempt to switch the state, we assume we had a SUSPEND_REQUEST |
2700 // waits until SR_SUSPENDED is set and then returns. We will wait | 2755 os::SuspendResume::State state = osthread->sr.suspended(); |
2701 // here for a resume signal and that completes the suspend-other | 2756 if (state == os::SuspendResume::SR_SUSPENDED) { |
2702 // action. do_suspend/do_resume is always called as a pair from | 2757 sigset_t suspend_set; // signals for sigsuspend() |
2703 // the same thread - so there are no races | 2758 |
2704 | 2759 // get current set of blocked signals and unblock resume signal |
2705 // notify the caller | 2760 pthread_sigmask(SIG_BLOCK, NULL, &suspend_set); |
2706 osthread->sr.set_suspended(); | 2761 sigdelset(&suspend_set, SR_signum); |
2707 | 2762 |
2708 sigset_t suspend_set; // signals for sigsuspend() | 2763 sr_semaphore.signal(); |
2709 | 2764 // wait here until we are resumed |
2710 // get current set of blocked signals and unblock resume signal | 2765 while (1) { |
2711 pthread_sigmask(SIG_BLOCK, NULL, &suspend_set); | 2766 sigsuspend(&suspend_set); |
2712 sigdelset(&suspend_set, SR_signum); | 2767 |
2713 | 2768 os::SuspendResume::State result = osthread->sr.running(); |
2714 // wait here until we are resumed | 2769 if (result == os::SuspendResume::SR_RUNNING) { |
2715 do { | 2770 sr_semaphore.signal(); |
2716 sigsuspend(&suspend_set); | 2771 break; |
2717 // ignore all returns until we get a resume signal | 2772 } else if (result != os::SuspendResume::SR_SUSPENDED) { |
2718 } 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 } | |
2719 | 2782 |
2720 resume_clear_context(osthread); | 2783 resume_clear_context(osthread); |
2721 | 2784 } else if (current == os::SuspendResume::SR_RUNNING) { |
2785 // request was cancelled, continue | |
2786 } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) { | |
2787 // ignore | |
2722 } else { | 2788 } else { |
2723 assert(action == os::Bsd::SuspendResume::SR_CONTINUE, "unexpected sr action"); | 2789 // ignore |
2724 // nothing special to do - just leave the handler | |
2725 } | 2790 } |
2726 | 2791 |
2727 errno = old_errno; | 2792 errno = old_errno; |
2728 } | 2793 } |
2729 | 2794 |
2763 // Save signal flag | 2828 // Save signal flag |
2764 os::Bsd::set_our_sigflags(SR_signum, act.sa_flags); | 2829 os::Bsd::set_our_sigflags(SR_signum, act.sa_flags); |
2765 return 0; | 2830 return 0; |
2766 } | 2831 } |
2767 | 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; | |
2768 | 2844 |
2769 // 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 |
2770 // but this seems the normal response to library errors | 2846 // but this seems the normal response to library errors |
2771 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 | |
2772 // mark as suspended and send signal | 2851 // mark as suspended and send signal |
2773 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_SUSPEND); | 2852 if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) { |
2774 int status = pthread_kill(osthread->pthread_id(), SR_signum); | 2853 // failed to switch, state wasn't running? |
2775 assert_status(status == 0, status, "pthread_kill"); | 2854 ShouldNotReachHere(); |
2776 | |
2777 // check status and wait until notified of suspension | |
2778 if (status == 0) { | |
2779 for (int i = 0; !osthread->sr.is_suspended(); i++) { | |
2780 os::yield_all(i); | |
2781 } | |
2782 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE); | |
2783 return true; | |
2784 } | |
2785 else { | |
2786 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE); | |
2787 return false; | 2855 return false; |
2788 } | 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; | |
2789 } | 2884 } |
2790 | 2885 |
2791 static void do_resume(OSThread* osthread) { | 2886 static void do_resume(OSThread* osthread) { |
2792 assert(osthread->sr.is_suspended(), "thread should be suspended"); | 2887 assert(osthread->sr.is_suspended(), "thread should be suspended"); |
2793 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_CONTINUE); | 2888 assert(!sr_semaphore.trywait(), "invalid semaphore state"); |
2794 | 2889 |
2795 int status = pthread_kill(osthread->pthread_id(), SR_signum); | 2890 if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) { |
2796 assert_status(status == 0, status, "pthread_kill"); | 2891 // failed to switch to WAKEUP_REQUEST |
2797 // check status and wait unit notified of resumption | 2892 ShouldNotReachHere(); |
2798 if (status == 0) { | 2893 return; |
2799 for (int i = 0; osthread->sr.is_suspended(); i++) { | 2894 } |
2800 os::yield_all(i); | 2895 |
2801 } | 2896 while (true) { |
2802 } | 2897 if (sr_notify(osthread) == 0) { |
2803 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!"); | |
2804 } | 2909 } |
2805 | 2910 |
2806 //////////////////////////////////////////////////////////////////////////////// | 2911 //////////////////////////////////////////////////////////////////////////////// |
2807 // interrupt support | 2912 // interrupt support |
2808 | 2913 |
3028 sigAct.sa_flags = SA_SIGINFO|SA_RESTART; | 3133 sigAct.sa_flags = SA_SIGINFO|SA_RESTART; |
3029 } else { | 3134 } else { |
3030 sigAct.sa_sigaction = signalHandler; | 3135 sigAct.sa_sigaction = signalHandler; |
3031 sigAct.sa_flags = SA_SIGINFO|SA_RESTART; | 3136 sigAct.sa_flags = SA_SIGINFO|SA_RESTART; |
3032 } | 3137 } |
3138 #if __APPLE__ | |
3139 // Needed for main thread as XNU (Mac OS X kernel) will only deliver SIGSEGV | |
3140 // (which starts as SIGBUS) on main thread with faulting address inside "stack+guard pages" | |
3141 // if the signal handler declares it will handle it on alternate stack. | |
3142 // Notice we only declare we will handle it on alt stack, but we are not | |
3143 // actually going to use real alt stack - this is just a workaround. | |
3144 // Please see ux_exception.c, method catch_mach_exception_raise for details | |
3145 // link http://www.opensource.apple.com/source/xnu/xnu-2050.18.24/bsd/uxkern/ux_exception.c | |
3146 if (sig == SIGSEGV) { | |
3147 sigAct.sa_flags |= SA_ONSTACK; | |
3148 } | |
3149 #endif | |
3150 | |
3033 // Save flags, which are set by ours | 3151 // Save flags, which are set by ours |
3034 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); | 3152 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); |
3035 sigflags[sig] = sigAct.sa_flags; | 3153 sigflags[sig] = sigAct.sa_flags; |
3036 | 3154 |
3037 int ret = sigaction(sig, &sigAct, &oldAct); | 3155 int ret = sigaction(sig, &sigAct, &oldAct); |
3536 bool os::bind_to_processor(uint processor_id) { | 3654 bool os::bind_to_processor(uint processor_id) { |
3537 // Not yet implemented. | 3655 // Not yet implemented. |
3538 return false; | 3656 return false; |
3539 } | 3657 } |
3540 | 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 | |
3541 /// | 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 } | |
3542 | 3693 |
3543 // 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 |
3544 // resuming the target. Used by the flat-profiler only | 3695 // resuming the target. Used by the flat-profiler only |
3545 ExtendedPC os::get_thread_pc(Thread* thread) { | 3696 ExtendedPC os::get_thread_pc(Thread* thread) { |
3546 // 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 |
3547 assert(Thread::current()->is_Watcher_thread(), "Must be watcher"); | 3698 assert(Thread::current()->is_Watcher_thread(), "Must be watcher"); |
3548 assert(thread->is_VM_thread(), "Can only be called for VMThread"); | 3699 assert(thread->is_VM_thread(), "Can only be called for VMThread"); |
3549 | 3700 |
3550 ExtendedPC epc; | 3701 PcFetcher fetcher(thread); |
3551 | 3702 fetcher.run(); |
3552 OSThread* osthread = thread->osthread(); | 3703 return fetcher.result(); |
3553 if (do_suspend(osthread)) { | |
3554 if (osthread->ucontext() != NULL) { | |
3555 epc = os::Bsd::ucontext_get_pc(osthread->ucontext()); | |
3556 } else { | |
3557 // NULL context is unexpected, double-check this is the VMThread | |
3558 guarantee(thread->is_VM_thread(), "can only be called for VMThread"); | |
3559 } | |
3560 do_resume(osthread); | |
3561 } | |
3562 // failure means pthread_kill failed for some reason - arguably this is | |
3563 // a fatal problem, but such problems are ignored elsewhere | |
3564 | |
3565 return epc; | |
3566 } | 3704 } |
3567 | 3705 |
3568 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) |
3569 { | 3707 { |
3570 return pthread_cond_timedwait(_cond, _mutex, _abstime); | 3708 return pthread_cond_timedwait(_cond, _mutex, _abstime); |
4545 // Truncate if theoretical string was longer than bufferSize | 4683 // Truncate if theoretical string was longer than bufferSize |
4546 n = MIN2(n, (int)bufferSize); | 4684 n = MIN2(n, (int)bufferSize); |
4547 | 4685 |
4548 return n; | 4686 return n; |
4549 } | 4687 } |
4688 |