Mercurial > hg > truffle
comparison src/os/linux/vm/os_linux.cpp @ 14392:b5c8a61d7fa0
Merge
author | kvn |
---|---|
date | Fri, 21 Jun 2013 15:56:24 -0700 |
parents | d2907f74462e f2110083203d |
children | f4f6ae481e1a |
comparison
equal
deleted
inserted
replaced
14391:d2907f74462e | 14392:b5c8a61d7fa0 |
---|---|
99 # include <link.h> | 99 # include <link.h> |
100 # include <stdint.h> | 100 # include <stdint.h> |
101 # include <inttypes.h> | 101 # include <inttypes.h> |
102 # include <sys/ioctl.h> | 102 # include <sys/ioctl.h> |
103 | 103 |
104 // if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling | |
105 // getrusage() is prepared to handle the associated failure. | |
106 #ifndef RUSAGE_THREAD | |
107 #define RUSAGE_THREAD (1) /* only the calling thread */ | |
108 #endif | |
109 | |
104 #define MAX_PATH (2 * K) | 110 #define MAX_PATH (2 * K) |
105 | 111 |
106 // for timer info max values which include all bits | 112 // for timer info max values which include all bits |
107 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) | 113 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) |
108 | 114 |
142 static int SR_signum = SIGUSR2; | 148 static int SR_signum = SIGUSR2; |
143 sigset_t SR_sigset; | 149 sigset_t SR_sigset; |
144 | 150 |
145 /* Used to protect dlsym() calls */ | 151 /* Used to protect dlsym() calls */ |
146 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); | |
147 | 156 |
148 #ifdef JAVASE_EMBEDDED | 157 #ifdef JAVASE_EMBEDDED |
149 class MemNotifyThread: public Thread { | 158 class MemNotifyThread: public Thread { |
150 friend class VMStructs; | 159 friend class VMStructs; |
151 public: | 160 public: |
1336 | 1345 |
1337 jlong os::elapsed_frequency() { | 1346 jlong os::elapsed_frequency() { |
1338 return (1000 * 1000); | 1347 return (1000 * 1000); |
1339 } | 1348 } |
1340 | 1349 |
1341 // For now, we say that linux does not support vtime. I have no idea | 1350 bool os::supports_vtime() { return true; } |
1342 // whether it can actually be made to (DLD, 9/13/05). | |
1343 | |
1344 bool os::supports_vtime() { return false; } | |
1345 bool os::enable_vtime() { return false; } | 1351 bool os::enable_vtime() { return false; } |
1346 bool os::vtime_enabled() { return false; } | 1352 bool os::vtime_enabled() { return false; } |
1353 | |
1347 double os::elapsedVTime() { | 1354 double os::elapsedVTime() { |
1348 // better than nothing, but not much | 1355 struct rusage usage; |
1349 return elapsedTime(); | 1356 int retval = getrusage(RUSAGE_THREAD, &usage); |
1357 if (retval == 0) { | |
1358 return (double) (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) + (double) (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / (1000 * 1000); | |
1359 } else { | |
1360 // better than nothing, but not much | |
1361 return elapsedTime(); | |
1362 } | |
1350 } | 1363 } |
1351 | 1364 |
1352 jlong os::javaTimeMillis() { | 1365 jlong os::javaTimeMillis() { |
1353 timeval time; | 1366 timeval time; |
1354 int status = gettimeofday(&time, NULL); | 1367 int status = gettimeofday(&time, NULL); |
2397 | 2410 |
2398 void* os::user_handler() { | 2411 void* os::user_handler() { |
2399 return CAST_FROM_FN_PTR(void*, UserHandler); | 2412 return CAST_FROM_FN_PTR(void*, UserHandler); |
2400 } | 2413 } |
2401 | 2414 |
2415 class Semaphore : public StackObj { | |
2416 public: | |
2417 Semaphore(); | |
2418 ~Semaphore(); | |
2419 void signal(); | |
2420 void wait(); | |
2421 bool trywait(); | |
2422 bool timedwait(unsigned int sec, int nsec); | |
2423 private: | |
2424 sem_t _semaphore; | |
2425 }; | |
2426 | |
2427 | |
2428 Semaphore::Semaphore() { | |
2429 sem_init(&_semaphore, 0, 0); | |
2430 } | |
2431 | |
2432 Semaphore::~Semaphore() { | |
2433 sem_destroy(&_semaphore); | |
2434 } | |
2435 | |
2436 void Semaphore::signal() { | |
2437 sem_post(&_semaphore); | |
2438 } | |
2439 | |
2440 void Semaphore::wait() { | |
2441 sem_wait(&_semaphore); | |
2442 } | |
2443 | |
2444 bool Semaphore::trywait() { | |
2445 return sem_trywait(&_semaphore) == 0; | |
2446 } | |
2447 | |
2448 bool Semaphore::timedwait(unsigned int sec, int nsec) { | |
2449 struct timespec ts; | |
2450 unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec); | |
2451 | |
2452 while (1) { | |
2453 int result = sem_timedwait(&_semaphore, &ts); | |
2454 if (result == 0) { | |
2455 return true; | |
2456 } else if (errno == EINTR) { | |
2457 continue; | |
2458 } else if (errno == ETIMEDOUT) { | |
2459 return false; | |
2460 } else { | |
2461 return false; | |
2462 } | |
2463 } | |
2464 } | |
2465 | |
2402 extern "C" { | 2466 extern "C" { |
2403 typedef void (*sa_handler_t)(int); | 2467 typedef void (*sa_handler_t)(int); |
2404 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); | 2468 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); |
2405 } | 2469 } |
2406 | 2470 |
2436 // a counter for each possible signal value | 2500 // a counter for each possible signal value |
2437 static volatile jint pending_signals[NSIG+1] = { 0 }; | 2501 static volatile jint pending_signals[NSIG+1] = { 0 }; |
2438 | 2502 |
2439 // Linux(POSIX) specific hand shaking semaphore. | 2503 // Linux(POSIX) specific hand shaking semaphore. |
2440 static sem_t sig_sem; | 2504 static sem_t sig_sem; |
2505 static Semaphore sr_semaphore; | |
2441 | 2506 |
2442 void os::signal_init_pd() { | 2507 void os::signal_init_pd() { |
2443 // Initialize signal structures | 2508 // Initialize signal structures |
2444 ::memset((void*)pending_signals, 0, sizeof(pending_signals)); | 2509 ::memset((void*)pending_signals, 0, sizeof(pending_signals)); |
2445 | 2510 |
3549 // | 3614 // |
3550 | 3615 |
3551 static void resume_clear_context(OSThread *osthread) { | 3616 static void resume_clear_context(OSThread *osthread) { |
3552 osthread->set_ucontext(NULL); | 3617 osthread->set_ucontext(NULL); |
3553 osthread->set_siginfo(NULL); | 3618 osthread->set_siginfo(NULL); |
3554 | |
3555 // notify the suspend action is completed, we have now resumed | |
3556 osthread->sr.clear_suspended(); | |
3557 } | 3619 } |
3558 | 3620 |
3559 static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) { | 3621 static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) { |
3560 osthread->set_ucontext(context); | 3622 osthread->set_ucontext(context); |
3561 osthread->set_siginfo(siginfo); | 3623 osthread->set_siginfo(siginfo); |
3571 // interface point of view, but sigwait() prevents the signal hander | 3633 // interface point of view, but sigwait() prevents the signal hander |
3572 // from being run. libpthread would get very confused by not having | 3634 // from being run. libpthread would get very confused by not having |
3573 // its signal handlers run and prevents sigwait()'s use with the | 3635 // its signal handlers run and prevents sigwait()'s use with the |
3574 // mutex granting granting signal. | 3636 // mutex granting granting signal. |
3575 // | 3637 // |
3576 // Currently only ever called on the VMThread | 3638 // Currently only ever called on the VMThread and JavaThreads (PC sampling) |
3577 // | 3639 // |
3578 static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) { | 3640 static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) { |
3579 // Save and restore errno to avoid confusing native code with EINTR | 3641 // Save and restore errno to avoid confusing native code with EINTR |
3580 // after sigsuspend. | 3642 // after sigsuspend. |
3581 int old_errno = errno; | 3643 int old_errno = errno; |
3582 | 3644 |
3583 Thread* thread = Thread::current(); | 3645 Thread* thread = Thread::current(); |
3584 OSThread* osthread = thread->osthread(); | 3646 OSThread* osthread = thread->osthread(); |
3585 assert(thread->is_VM_thread(), "Must be VMThread"); | 3647 assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); |
3586 // read current suspend action | 3648 |
3587 int action = osthread->sr.suspend_action(); | 3649 os::SuspendResume::State current = osthread->sr.state(); |
3588 if (action == os::Linux::SuspendResume::SR_SUSPEND) { | 3650 if (current == os::SuspendResume::SR_SUSPEND_REQUEST) { |
3589 suspend_save_context(osthread, siginfo, context); | 3651 suspend_save_context(osthread, siginfo, context); |
3590 | 3652 |
3591 // Notify the suspend action is about to be completed. do_suspend() | 3653 // attempt to switch the state, we assume we had a SUSPEND_REQUEST |
3592 // waits until SR_SUSPENDED is set and then returns. We will wait | 3654 os::SuspendResume::State state = osthread->sr.suspended(); |
3593 // here for a resume signal and that completes the suspend-other | 3655 if (state == os::SuspendResume::SR_SUSPENDED) { |
3594 // action. do_suspend/do_resume is always called as a pair from | 3656 sigset_t suspend_set; // signals for sigsuspend() |
3595 // the same thread - so there are no races | 3657 |
3596 | 3658 // get current set of blocked signals and unblock resume signal |
3597 // notify the caller | 3659 pthread_sigmask(SIG_BLOCK, NULL, &suspend_set); |
3598 osthread->sr.set_suspended(); | 3660 sigdelset(&suspend_set, SR_signum); |
3599 | 3661 |
3600 sigset_t suspend_set; // signals for sigsuspend() | 3662 sr_semaphore.signal(); |
3601 | 3663 // wait here until we are resumed |
3602 // get current set of blocked signals and unblock resume signal | 3664 while (1) { |
3603 pthread_sigmask(SIG_BLOCK, NULL, &suspend_set); | 3665 sigsuspend(&suspend_set); |
3604 sigdelset(&suspend_set, SR_signum); | 3666 |
3605 | 3667 os::SuspendResume::State result = osthread->sr.running(); |
3606 // wait here until we are resumed | 3668 if (result == os::SuspendResume::SR_RUNNING) { |
3607 do { | 3669 sr_semaphore.signal(); |
3608 sigsuspend(&suspend_set); | 3670 break; |
3609 // ignore all returns until we get a resume signal | 3671 } |
3610 } while (osthread->sr.suspend_action() != os::Linux::SuspendResume::SR_CONTINUE); | 3672 } |
3673 | |
3674 } else if (state == os::SuspendResume::SR_RUNNING) { | |
3675 // request was cancelled, continue | |
3676 } else { | |
3677 ShouldNotReachHere(); | |
3678 } | |
3611 | 3679 |
3612 resume_clear_context(osthread); | 3680 resume_clear_context(osthread); |
3613 | 3681 } else if (current == os::SuspendResume::SR_RUNNING) { |
3682 // request was cancelled, continue | |
3683 } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) { | |
3684 // ignore | |
3614 } else { | 3685 } else { |
3615 assert(action == os::Linux::SuspendResume::SR_CONTINUE, "unexpected sr action"); | 3686 // ignore |
3616 // nothing special to do - just leave the handler | |
3617 } | 3687 } |
3618 | 3688 |
3619 errno = old_errno; | 3689 errno = old_errno; |
3620 } | 3690 } |
3621 | 3691 |
3655 // Save signal flag | 3725 // Save signal flag |
3656 os::Linux::set_our_sigflags(SR_signum, act.sa_flags); | 3726 os::Linux::set_our_sigflags(SR_signum, act.sa_flags); |
3657 return 0; | 3727 return 0; |
3658 } | 3728 } |
3659 | 3729 |
3730 static int sr_notify(OSThread* osthread) { | |
3731 int status = pthread_kill(osthread->pthread_id(), SR_signum); | |
3732 assert_status(status == 0, status, "pthread_kill"); | |
3733 return status; | |
3734 } | |
3735 | |
3736 // "Randomly" selected value for how long we want to spin | |
3737 // before bailing out on suspending a thread, also how often | |
3738 // we send a signal to a thread we want to resume | |
3739 static const int RANDOMLY_LARGE_INTEGER = 1000000; | |
3740 static const int RANDOMLY_LARGE_INTEGER2 = 100; | |
3660 | 3741 |
3661 // returns true on success and false on error - really an error is fatal | 3742 // returns true on success and false on error - really an error is fatal |
3662 // but this seems the normal response to library errors | 3743 // but this seems the normal response to library errors |
3663 static bool do_suspend(OSThread* osthread) { | 3744 static bool do_suspend(OSThread* osthread) { |
3745 assert(osthread->sr.is_running(), "thread should be running"); | |
3746 assert(!sr_semaphore.trywait(), "semaphore has invalid state"); | |
3747 | |
3664 // mark as suspended and send signal | 3748 // mark as suspended and send signal |
3665 osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_SUSPEND); | 3749 if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) { |
3666 int status = pthread_kill(osthread->pthread_id(), SR_signum); | 3750 // failed to switch, state wasn't running? |
3667 assert_status(status == 0, status, "pthread_kill"); | 3751 ShouldNotReachHere(); |
3668 | |
3669 // check status and wait until notified of suspension | |
3670 if (status == 0) { | |
3671 for (int i = 0; !osthread->sr.is_suspended(); i++) { | |
3672 os::yield_all(i); | |
3673 } | |
3674 osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE); | |
3675 return true; | |
3676 } | |
3677 else { | |
3678 osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE); | |
3679 return false; | 3752 return false; |
3680 } | 3753 } |
3754 | |
3755 if (sr_notify(osthread) != 0) { | |
3756 ShouldNotReachHere(); | |
3757 } | |
3758 | |
3759 // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED | |
3760 while (true) { | |
3761 if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) { | |
3762 break; | |
3763 } else { | |
3764 // timeout | |
3765 os::SuspendResume::State cancelled = osthread->sr.cancel_suspend(); | |
3766 if (cancelled == os::SuspendResume::SR_RUNNING) { | |
3767 return false; | |
3768 } else if (cancelled == os::SuspendResume::SR_SUSPENDED) { | |
3769 // make sure that we consume the signal on the semaphore as well | |
3770 sr_semaphore.wait(); | |
3771 break; | |
3772 } else { | |
3773 ShouldNotReachHere(); | |
3774 return false; | |
3775 } | |
3776 } | |
3777 } | |
3778 | |
3779 guarantee(osthread->sr.is_suspended(), "Must be suspended"); | |
3780 return true; | |
3681 } | 3781 } |
3682 | 3782 |
3683 static void do_resume(OSThread* osthread) { | 3783 static void do_resume(OSThread* osthread) { |
3684 assert(osthread->sr.is_suspended(), "thread should be suspended"); | 3784 assert(osthread->sr.is_suspended(), "thread should be suspended"); |
3685 osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_CONTINUE); | 3785 assert(!sr_semaphore.trywait(), "invalid semaphore state"); |
3686 | 3786 |
3687 int status = pthread_kill(osthread->pthread_id(), SR_signum); | 3787 if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) { |
3688 assert_status(status == 0, status, "pthread_kill"); | 3788 // failed to switch to WAKEUP_REQUEST |
3689 // check status and wait unit notified of resumption | 3789 ShouldNotReachHere(); |
3690 if (status == 0) { | 3790 return; |
3691 for (int i = 0; osthread->sr.is_suspended(); i++) { | 3791 } |
3692 os::yield_all(i); | 3792 |
3693 } | 3793 while (true) { |
3694 } | 3794 if (sr_notify(osthread) == 0) { |
3695 osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE); | 3795 if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) { |
3796 if (osthread->sr.is_running()) { | |
3797 return; | |
3798 } | |
3799 } | |
3800 } else { | |
3801 ShouldNotReachHere(); | |
3802 } | |
3803 } | |
3804 | |
3805 guarantee(osthread->sr.is_running(), "Must be running!"); | |
3696 } | 3806 } |
3697 | 3807 |
3698 //////////////////////////////////////////////////////////////////////////////// | 3808 //////////////////////////////////////////////////////////////////////////////// |
3699 // interrupt support | 3809 // interrupt support |
3700 | 3810 |
4461 return false; | 4571 return false; |
4462 } | 4572 } |
4463 | 4573 |
4464 /// | 4574 /// |
4465 | 4575 |
4576 void os::SuspendedThreadTask::internal_do_task() { | |
4577 if (do_suspend(_thread->osthread())) { | |
4578 SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext()); | |
4579 do_task(context); | |
4580 do_resume(_thread->osthread()); | |
4581 } | |
4582 } | |
4583 | |
4584 class PcFetcher : public os::SuspendedThreadTask { | |
4585 public: | |
4586 PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {} | |
4587 ExtendedPC result(); | |
4588 protected: | |
4589 void do_task(const os::SuspendedThreadTaskContext& context); | |
4590 private: | |
4591 ExtendedPC _epc; | |
4592 }; | |
4593 | |
4594 ExtendedPC PcFetcher::result() { | |
4595 guarantee(is_done(), "task is not done yet."); | |
4596 return _epc; | |
4597 } | |
4598 | |
4599 void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) { | |
4600 Thread* thread = context.thread(); | |
4601 OSThread* osthread = thread->osthread(); | |
4602 if (osthread->ucontext() != NULL) { | |
4603 _epc = os::Linux::ucontext_get_pc((ucontext_t *) context.ucontext()); | |
4604 } else { | |
4605 // NULL context is unexpected, double-check this is the VMThread | |
4606 guarantee(thread->is_VM_thread(), "can only be called for VMThread"); | |
4607 } | |
4608 } | |
4609 | |
4466 // Suspends the target using the signal mechanism and then grabs the PC before | 4610 // Suspends the target using the signal mechanism and then grabs the PC before |
4467 // resuming the target. Used by the flat-profiler only | 4611 // resuming the target. Used by the flat-profiler only |
4468 ExtendedPC os::get_thread_pc(Thread* thread) { | 4612 ExtendedPC os::get_thread_pc(Thread* thread) { |
4469 // Make sure that it is called by the watcher for the VMThread | 4613 // Make sure that it is called by the watcher for the VMThread |
4470 assert(Thread::current()->is_Watcher_thread(), "Must be watcher"); | 4614 assert(Thread::current()->is_Watcher_thread(), "Must be watcher"); |
4471 assert(thread->is_VM_thread(), "Can only be called for VMThread"); | 4615 assert(thread->is_VM_thread(), "Can only be called for VMThread"); |
4472 | 4616 |
4473 ExtendedPC epc; | 4617 PcFetcher fetcher(thread); |
4474 | 4618 fetcher.run(); |
4475 OSThread* osthread = thread->osthread(); | 4619 return fetcher.result(); |
4476 if (do_suspend(osthread)) { | |
4477 if (osthread->ucontext() != NULL) { | |
4478 epc = os::Linux::ucontext_get_pc(osthread->ucontext()); | |
4479 } else { | |
4480 // NULL context is unexpected, double-check this is the VMThread | |
4481 guarantee(thread->is_VM_thread(), "can only be called for VMThread"); | |
4482 } | |
4483 do_resume(osthread); | |
4484 } | |
4485 // failure means pthread_kill failed for some reason - arguably this is | |
4486 // a fatal problem, but such problems are ignored elsewhere | |
4487 | |
4488 return epc; | |
4489 } | 4620 } |
4490 | 4621 |
4491 int os::Linux::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime) | 4622 int os::Linux::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime) |
4492 { | 4623 { |
4493 if (is_NPTL()) { | 4624 if (is_NPTL()) { |
5605 | 5736 |
5606 if (memnotify_thread() == NULL) { | 5737 if (memnotify_thread() == NULL) { |
5607 new MemNotifyThread(fd); | 5738 new MemNotifyThread(fd); |
5608 } | 5739 } |
5609 } | 5740 } |
5741 | |
5610 #endif // JAVASE_EMBEDDED | 5742 #endif // JAVASE_EMBEDDED |