2249
2250 // sun.misc.Signal
2251
2252 extern "C" {
2253 static void UserHandler(int sig, void *siginfo, void *context) {
2254 // Ctrl-C is pressed during error reporting, likely because the error
2255 // handler fails to abort. Let VM die immediately.
2256 if (sig == SIGINT && is_error_reported()) {
2257 os::die();
2258 }
2259
2260 os::signal_notify(sig);
2261 // We do not need to reinstate the signal handler each time...
2262 }
2263 }
2264
2265 void* os::user_handler() {
2266 return CAST_FROM_FN_PTR(void*, UserHandler);
2267 }
2268
2269 class Semaphore : public StackObj {
2270 public:
2271 Semaphore();
2272 ~Semaphore();
2273 void signal();
2274 void wait();
2275 bool trywait();
2276 bool timedwait(unsigned int sec, int nsec);
2277 private:
2278 sema_t _semaphore;
2279 };
2280
2281
2282 Semaphore::Semaphore() {
2283 sema_init(&_semaphore, 0, NULL, NULL);
2284 }
2285
2286 Semaphore::~Semaphore() {
2287 sema_destroy(&_semaphore);
2288 }
2289
2290 void Semaphore::signal() {
2291 sema_post(&_semaphore);
2292 }
2293
2294 void Semaphore::wait() {
2295 sema_wait(&_semaphore);
2296 }
2297
2298 bool Semaphore::trywait() {
2299 return sema_trywait(&_semaphore) == 0;
2300 }
2301
2302 bool Semaphore::timedwait(unsigned int sec, int nsec) {
2303 struct timespec ts;
2304 unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
2305
2306 while (1) {
2307 int result = sema_timedwait(&_semaphore, &ts);
2308 if (result == 0) {
2309 return true;
2310 } else if (errno == EINTR) {
2311 continue;
2312 } else if (errno == ETIME) {
2313 return false;
2314 } else {
2315 return false;
2316 }
2317 }
2318 }
2319
2320 extern "C" {
2321 typedef void (*sa_handler_t)(int);
2322 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
2323 }
2324
2325 void* os::signal(int signal_number, void* handler) {
2326 struct sigaction sigAct, oldSigAct;
2327 sigfillset(&(sigAct.sa_mask));
2328 sigAct.sa_flags = SA_RESTART & ~SA_RESETHAND;
2329 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
2330
2331 if (sigaction(signal_number, &sigAct, &oldSigAct)) {
2332 // -1 means registration failed
2333 return (void *)-1;
2334 }
2335
2336 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
2337 }
2338
3697 }
3698 *priority_ptr = p;
3699 return OS_OK;
3700 }
3701
3702
3703 // Hint to the underlying OS that a task switch would not be good.
3704 // Void return because it's a hint and can fail.
3705 void os::hint_no_preempt() {
3706 schedctl_start(schedctl_init());
3707 }
3708
3709 static void resume_clear_context(OSThread *osthread) {
3710 osthread->set_ucontext(NULL);
3711 }
3712
3713 static void suspend_save_context(OSThread *osthread, ucontext_t* context) {
3714 osthread->set_ucontext(context);
3715 }
3716
3717 static Semaphore sr_semaphore;
3718
3719 void os::Solaris::SR_handler(Thread* thread, ucontext_t* uc) {
3720 // Save and restore errno to avoid confusing native code with EINTR
3721 // after sigsuspend.
3722 int old_errno = errno;
3723
3724 OSThread* osthread = thread->osthread();
3725 assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
3726
3727 os::SuspendResume::State current = osthread->sr.state();
3728 if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
3729 suspend_save_context(osthread, uc);
3730
3731 // attempt to switch the state, we assume we had a SUSPEND_REQUEST
3732 os::SuspendResume::State state = osthread->sr.suspended();
3733 if (state == os::SuspendResume::SR_SUSPENDED) {
3734 sigset_t suspend_set; // signals for sigsuspend()
3735
3736 // get current set of blocked signals and unblock resume signal
3737 thr_sigsetmask(SIG_BLOCK, NULL, &suspend_set);
|
2249
2250 // sun.misc.Signal
2251
2252 extern "C" {
2253 static void UserHandler(int sig, void *siginfo, void *context) {
2254 // Ctrl-C is pressed during error reporting, likely because the error
2255 // handler fails to abort. Let VM die immediately.
2256 if (sig == SIGINT && is_error_reported()) {
2257 os::die();
2258 }
2259
2260 os::signal_notify(sig);
2261 // We do not need to reinstate the signal handler each time...
2262 }
2263 }
2264
2265 void* os::user_handler() {
2266 return CAST_FROM_FN_PTR(void*, UserHandler);
2267 }
2268
2269 class SolarisSemaphore : public os::PosixSemaphore {
2270 public:
2271 SolarisSemaphore(uint value = 0) : os::PosixSemaphore(value) {}
2272
2273 bool timedwait(unsigned int sec, int nsec) {
2274 struct timespec ts;
2275 unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
2276
2277 return os::PosixSemaphore::timedwait(ts);
2278 }
2279 };
2280
2281 extern "C" {
2282 typedef void (*sa_handler_t)(int);
2283 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
2284 }
2285
2286 void* os::signal(int signal_number, void* handler) {
2287 struct sigaction sigAct, oldSigAct;
2288 sigfillset(&(sigAct.sa_mask));
2289 sigAct.sa_flags = SA_RESTART & ~SA_RESETHAND;
2290 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
2291
2292 if (sigaction(signal_number, &sigAct, &oldSigAct)) {
2293 // -1 means registration failed
2294 return (void *)-1;
2295 }
2296
2297 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
2298 }
2299
3658 }
3659 *priority_ptr = p;
3660 return OS_OK;
3661 }
3662
3663
3664 // Hint to the underlying OS that a task switch would not be good.
3665 // Void return because it's a hint and can fail.
3666 void os::hint_no_preempt() {
3667 schedctl_start(schedctl_init());
3668 }
3669
3670 static void resume_clear_context(OSThread *osthread) {
3671 osthread->set_ucontext(NULL);
3672 }
3673
3674 static void suspend_save_context(OSThread *osthread, ucontext_t* context) {
3675 osthread->set_ucontext(context);
3676 }
3677
3678 static SolarisSemaphore sr_semaphore;
3679
3680 void os::Solaris::SR_handler(Thread* thread, ucontext_t* uc) {
3681 // Save and restore errno to avoid confusing native code with EINTR
3682 // after sigsuspend.
3683 int old_errno = errno;
3684
3685 OSThread* osthread = thread->osthread();
3686 assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
3687
3688 os::SuspendResume::State current = osthread->sr.state();
3689 if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
3690 suspend_save_context(osthread, uc);
3691
3692 // attempt to switch the state, we assume we had a SUSPEND_REQUEST
3693 os::SuspendResume::State state = osthread->sr.suspended();
3694 if (state == os::SuspendResume::SR_SUSPENDED) {
3695 sigset_t suspend_set; // signals for sigsuspend()
3696
3697 // get current set of blocked signals and unblock resume signal
3698 thr_sigsetmask(SIG_BLOCK, NULL, &suspend_set);
|