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 }
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 struct timespec os::PosixSemaphore::create_timespec(unsigned int sec, int nsec) {
2270 struct timespec ts;
2271 unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
2272
2273 return ts;
2274 }
2275
2276 extern "C" {
2277 typedef void (*sa_handler_t)(int);
2278 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
2279 }
2280
2281 void* os::signal(int signal_number, void* handler) {
2282 struct sigaction sigAct, oldSigAct;
2283 sigfillset(&(sigAct.sa_mask));
2284 sigAct.sa_flags = SA_RESTART & ~SA_RESETHAND;
2285 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
2286
2287 if (sigaction(signal_number, &sigAct, &oldSigAct)) {
2288 // -1 means registration failed
2289 return (void *)-1;
2290 }
2291
2292 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
2293 }
3653 }
3654 *priority_ptr = p;
3655 return OS_OK;
3656 }
3657
3658
3659 // Hint to the underlying OS that a task switch would not be good.
3660 // Void return because it's a hint and can fail.
3661 void os::hint_no_preempt() {
3662 schedctl_start(schedctl_init());
3663 }
3664
3665 static void resume_clear_context(OSThread *osthread) {
3666 osthread->set_ucontext(NULL);
3667 }
3668
3669 static void suspend_save_context(OSThread *osthread, ucontext_t* context) {
3670 osthread->set_ucontext(context);
3671 }
3672
3673 static os::PosixSemaphore sr_semaphore;
3674
3675 void os::Solaris::SR_handler(Thread* thread, ucontext_t* uc) {
3676 // Save and restore errno to avoid confusing native code with EINTR
3677 // after sigsuspend.
3678 int old_errno = errno;
3679
3680 OSThread* osthread = thread->osthread();
3681 assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
3682
3683 os::SuspendResume::State current = osthread->sr.state();
3684 if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
3685 suspend_save_context(osthread, uc);
3686
3687 // attempt to switch the state, we assume we had a SUSPEND_REQUEST
3688 os::SuspendResume::State state = osthread->sr.suspended();
3689 if (state == os::SuspendResume::SR_SUSPENDED) {
3690 sigset_t suspend_set; // signals for sigsuspend()
3691
3692 // get current set of blocked signals and unblock resume signal
3693 thr_sigsetmask(SIG_BLOCK, NULL, &suspend_set);
|