< prev index next >

src/os/solaris/vm/os_solaris.cpp

Print this page




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);


< prev index next >