2045 2046 // sun.misc.Signal 2047 2048 extern "C" { 2049 static void UserHandler(int sig, void *siginfo, void *context) { 2050 // Ctrl-C is pressed during error reporting, likely because the error 2051 // handler fails to abort. Let VM die immediately. 2052 if (sig == SIGINT && VMError::is_error_reported()) { 2053 os::die(); 2054 } 2055 2056 os::signal_notify(sig); 2057 // We do not need to reinstate the signal handler each time... 2058 } 2059 } 2060 2061 void* os::user_handler() { 2062 return CAST_FROM_FN_PTR(void*, UserHandler); 2063 } 2064 2065 struct timespec PosixSemaphore::create_timespec(unsigned int sec, int nsec) { 2066 struct timespec ts; 2067 unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec); 2068 2069 return ts; 2070 } 2071 2072 extern "C" { 2073 typedef void (*sa_handler_t)(int); 2074 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); 2075 } 2076 2077 void* os::signal(int signal_number, void* handler) { 2078 struct sigaction sigAct, oldSigAct; 2079 sigfillset(&(sigAct.sa_mask)); 2080 sigAct.sa_flags = SA_RESTART & ~SA_RESETHAND; 2081 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler); 2082 2083 if (sigaction(signal_number, &sigAct, &oldSigAct)) { 2084 // -1 means registration failed 2085 return (void *)-1; 2086 } 2087 2088 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler); 2089 } 2090 2091 void os::signal_raise(int signal_number) { 2092 raise(signal_number); 2093 } 2094 2095 // The following code is moved from os.cpp for making this 2096 // code platform specific, which it is by its very nature. 2097 2098 // a counter for each possible signal value 2099 static int Sigexit = 0; 2100 static jint *pending_signals = NULL; 2101 static int *preinstalled_sigs = NULL; 2102 static struct sigaction *chainedsigactions = NULL; 2103 static sema_t sig_sem; 2104 typedef int (*version_getting_t)(); 2105 version_getting_t os::Solaris::get_libjsig_version = NULL; 2106 2107 int os::sigexitnum_pd() { 2108 assert(Sigexit > 0, "signal memory not yet initialized"); 2109 return Sigexit; 2110 } 2111 2112 void os::Solaris::init_signal_mem() { 2113 // Initialize signal structures 2114 Maxsignum = SIGRTMAX; 2115 Sigexit = Maxsignum+1; 2116 assert(Maxsignum >0, "Unable to obtain max signal number"); 2117 2118 // pending_signals has one int per signal 2119 // The additional signal is for SIGEXIT - exit signal to signal_thread 2120 pending_signals = (jint *)os::malloc(sizeof(jint) * (Sigexit+1), mtInternal); 2121 memset(pending_signals, 0, (sizeof(jint) * (Sigexit+1))); 2122 2123 if (UseSignalChaining) { 2124 chainedsigactions = (struct sigaction *)malloc(sizeof(struct sigaction) 2125 * (Maxsignum + 1), mtInternal); 2126 memset(chainedsigactions, 0, (sizeof(struct sigaction) * (Maxsignum + 1))); 2127 preinstalled_sigs = (int *)os::malloc(sizeof(int) * (Maxsignum + 1), mtInternal); 2128 memset(preinstalled_sigs, 0, (sizeof(int) * (Maxsignum + 1))); 2129 } 2130 ourSigFlags = (int*)malloc(sizeof(int) * (Maxsignum + 1), mtInternal); 2131 memset(ourSigFlags, 0, sizeof(int) * (Maxsignum + 1)); 2132 } 2133 2134 void os::signal_init_pd() { 2135 int ret; 2136 2137 ret = ::sema_init(&sig_sem, 0, NULL, NULL); 2138 assert(ret == 0, "sema_init() failed"); 2139 } 2140 2141 void os::signal_notify(int signal_number) { 2142 int ret; 2143 2144 Atomic::inc(&pending_signals[signal_number]); 2145 ret = ::sema_post(&sig_sem); 2146 assert(ret == 0, "sema_post() failed"); 2147 } 2148 2149 static int check_pending_signals(bool wait_for_signal) { 2150 int ret; 2151 while (true) { 2152 for (int i = 0; i < Sigexit + 1; i++) { 2153 jint n = pending_signals[i]; 2154 if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) { 2155 return i; 2156 } 2157 } 2158 if (!wait_for_signal) { 2159 return -1; 2160 } 2161 JavaThread *thread = JavaThread::current(); 2162 ThreadBlockInVM tbivm(thread); 2163 2164 bool threadIsSuspended; 2165 do { 2166 thread->set_suspend_equivalent(); 2167 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() 2168 while ((ret = ::sema_wait(&sig_sem)) == EINTR) 2169 ; 2170 assert(ret == 0, "sema_wait() failed"); 2171 2172 // were we externally suspended while we were waiting? 2173 threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); 2174 if (threadIsSuspended) { 2175 // The semaphore has been incremented, but while we were waiting 2176 // another thread suspended us. We don't want to continue running 2177 // while suspended because that would surprise the thread that 2178 // suspended us. 2179 ret = ::sema_post(&sig_sem); 2180 assert(ret == 0, "sema_post() failed"); 2181 2182 thread->java_suspend_self(); 2183 } 2184 } while (threadIsSuspended); 2185 } 2186 } 2187 2188 int os::signal_lookup() { 2189 return check_pending_signals(false); 2190 } 2191 2192 int os::signal_wait() { 2193 return check_pending_signals(true); 2194 } 2195 2196 //////////////////////////////////////////////////////////////////////////////// 2197 // Virtual Memory 2198 2199 static int page_size = -1; 2200 2201 int os::vm_page_size() { 2202 assert(page_size != -1, "must call os::init"); 2203 return page_size; 2204 } 2205 2206 // Solaris allocates memory by pages. 2207 int os::vm_allocation_granularity() { 2208 assert(page_size != -1, "must call os::init"); 2209 return page_size; 2210 } 2211 3582 static const int RANDOMLY_LARGE_INTEGER = 1000000; 3583 static const int RANDOMLY_LARGE_INTEGER2 = 100; 3584 3585 static bool do_suspend(OSThread* osthread) { 3586 assert(osthread->sr.is_running(), "thread should be running"); 3587 assert(!sr_semaphore.trywait(), "semaphore has invalid state"); 3588 3589 // mark as suspended and send signal 3590 if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) { 3591 // failed to switch, state wasn't running? 3592 ShouldNotReachHere(); 3593 return false; 3594 } 3595 3596 if (sr_notify(osthread) != 0) { 3597 ShouldNotReachHere(); 3598 } 3599 3600 // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED 3601 while (true) { 3602 if (sr_semaphore.timedwait(0, 2000 * NANOSECS_PER_MILLISEC)) { 3603 break; 3604 } else { 3605 // timeout 3606 os::SuspendResume::State cancelled = osthread->sr.cancel_suspend(); 3607 if (cancelled == os::SuspendResume::SR_RUNNING) { 3608 return false; 3609 } else if (cancelled == os::SuspendResume::SR_SUSPENDED) { 3610 // make sure that we consume the signal on the semaphore as well 3611 sr_semaphore.wait(); 3612 break; 3613 } else { 3614 ShouldNotReachHere(); 3615 return false; 3616 } 3617 } 3618 } 3619 3620 guarantee(osthread->sr.is_suspended(), "Must be suspended"); 3621 return true; 3622 } 3623 3624 static void do_resume(OSThread* osthread) { 3625 assert(osthread->sr.is_suspended(), "thread should be suspended"); 3626 assert(!sr_semaphore.trywait(), "invalid semaphore state"); 3627 3628 if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) { 3629 // failed to switch to WAKEUP_REQUEST 3630 ShouldNotReachHere(); 3631 return; 3632 } 3633 3634 while (true) { 3635 if (sr_notify(osthread) == 0) { 3636 if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) { 3637 if (osthread->sr.is_running()) { 3638 return; 3639 } 3640 } 3641 } else { 3642 ShouldNotReachHere(); 3643 } 3644 } 3645 3646 guarantee(osthread->sr.is_running(), "Must be running!"); 3647 } 3648 3649 void os::SuspendedThreadTask::internal_do_task() { 3650 if (do_suspend(_thread->osthread())) { 3651 SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext()); 3652 do_task(context); 3653 do_resume(_thread->osthread()); 3654 } 3655 } 3656 | 2045 2046 // sun.misc.Signal 2047 2048 extern "C" { 2049 static void UserHandler(int sig, void *siginfo, void *context) { 2050 // Ctrl-C is pressed during error reporting, likely because the error 2051 // handler fails to abort. Let VM die immediately. 2052 if (sig == SIGINT && VMError::is_error_reported()) { 2053 os::die(); 2054 } 2055 2056 os::signal_notify(sig); 2057 // We do not need to reinstate the signal handler each time... 2058 } 2059 } 2060 2061 void* os::user_handler() { 2062 return CAST_FROM_FN_PTR(void*, UserHandler); 2063 } 2064 2065 static struct timespec create_timespec(unsigned int sec, int nsec) { 2066 struct timespec ts; 2067 unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec); 2068 2069 return ts; 2070 } 2071 2072 extern "C" { 2073 typedef void (*sa_handler_t)(int); 2074 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); 2075 } 2076 2077 void* os::signal(int signal_number, void* handler) { 2078 struct sigaction sigAct, oldSigAct; 2079 sigfillset(&(sigAct.sa_mask)); 2080 sigAct.sa_flags = SA_RESTART & ~SA_RESETHAND; 2081 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler); 2082 2083 if (sigaction(signal_number, &sigAct, &oldSigAct)) { 2084 // -1 means registration failed 2085 return (void *)-1; 2086 } 2087 2088 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler); 2089 } 2090 2091 void os::signal_raise(int signal_number) { 2092 raise(signal_number); 2093 } 2094 2095 // The following code is moved from os.cpp for making this 2096 // code platform specific, which it is by its very nature. 2097 2098 // a counter for each possible signal value 2099 static int Sigexit = 0; 2100 static jint *pending_signals = NULL; 2101 static int *preinstalled_sigs = NULL; 2102 static struct sigaction *chainedsigactions = NULL; 2103 static Semaphore* sig_sem = NULL; 2104 typedef int (*version_getting_t)(); 2105 version_getting_t os::Solaris::get_libjsig_version = NULL; 2106 2107 int os::sigexitnum_pd() { 2108 assert(Sigexit > 0, "signal memory not yet initialized"); 2109 return Sigexit; 2110 } 2111 2112 void os::Solaris::init_signal_mem() { 2113 // Initialize signal structures 2114 Maxsignum = SIGRTMAX; 2115 Sigexit = Maxsignum+1; 2116 assert(Maxsignum >0, "Unable to obtain max signal number"); 2117 2118 // Initialize signal structures 2119 // pending_signals has one int per signal 2120 // The additional signal is for SIGEXIT - exit signal to signal_thread 2121 pending_signals = (jint *)os::malloc(sizeof(jint) * (Sigexit+1), mtInternal); 2122 memset(pending_signals, 0, (sizeof(jint) * (Sigexit+1))); 2123 2124 if (UseSignalChaining) { 2125 chainedsigactions = (struct sigaction *)malloc(sizeof(struct sigaction) 2126 * (Maxsignum + 1), mtInternal); 2127 memset(chainedsigactions, 0, (sizeof(struct sigaction) * (Maxsignum + 1))); 2128 preinstalled_sigs = (int *)os::malloc(sizeof(int) * (Maxsignum + 1), mtInternal); 2129 memset(preinstalled_sigs, 0, (sizeof(int) * (Maxsignum + 1))); 2130 } 2131 ourSigFlags = (int*)malloc(sizeof(int) * (Maxsignum + 1), mtInternal); 2132 memset(ourSigFlags, 0, sizeof(int) * (Maxsignum + 1)); 2133 } 2134 2135 void os::signal_init_pd() { 2136 // Initialize signal semaphore 2137 sig_sem = new Semaphore(); 2138 } 2139 2140 void os::signal_notify(int sig) { 2141 if (sig_sem != NULL) { 2142 Atomic::inc(&pending_signals[sig]); 2143 sig_sem->signal(); 2144 } else { 2145 // Signal thread is not created with ReduceSignalUsage and signal_init_pd 2146 // initialization isn't called. 2147 assert(ReduceSignalUsage, "signal semaphore should be created"); 2148 } 2149 } 2150 2151 static int check_pending_signals(bool wait_for_signal) { 2152 int ret; 2153 while (true) { 2154 for (int i = 0; i < Sigexit + 1; i++) { 2155 jint n = pending_signals[i]; 2156 if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) { 2157 return i; 2158 } 2159 } 2160 if (!wait_for_signal) { 2161 return -1; 2162 } 2163 JavaThread *thread = JavaThread::current(); 2164 ThreadBlockInVM tbivm(thread); 2165 2166 bool threadIsSuspended; 2167 do { 2168 thread->set_suspend_equivalent(); 2169 sig_sem->wait(); 2170 2171 // were we externally suspended while we were waiting? 2172 threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); 2173 if (threadIsSuspended) { 2174 // The semaphore has been incremented, but while we were waiting 2175 // another thread suspended us. We don't want to continue running 2176 // while suspended because that would surprise the thread that 2177 // suspended us. 2178 sig_sem->signal(); 2179 2180 thread->java_suspend_self(); 2181 } 2182 } while (threadIsSuspended); 2183 } 2184 } 2185 2186 int os::signal_wait() { 2187 return check_pending_signals(true); 2188 } 2189 2190 //////////////////////////////////////////////////////////////////////////////// 2191 // Virtual Memory 2192 2193 static int page_size = -1; 2194 2195 int os::vm_page_size() { 2196 assert(page_size != -1, "must call os::init"); 2197 return page_size; 2198 } 2199 2200 // Solaris allocates memory by pages. 2201 int os::vm_allocation_granularity() { 2202 assert(page_size != -1, "must call os::init"); 2203 return page_size; 2204 } 2205 3576 static const int RANDOMLY_LARGE_INTEGER = 1000000; 3577 static const int RANDOMLY_LARGE_INTEGER2 = 100; 3578 3579 static bool do_suspend(OSThread* osthread) { 3580 assert(osthread->sr.is_running(), "thread should be running"); 3581 assert(!sr_semaphore.trywait(), "semaphore has invalid state"); 3582 3583 // mark as suspended and send signal 3584 if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) { 3585 // failed to switch, state wasn't running? 3586 ShouldNotReachHere(); 3587 return false; 3588 } 3589 3590 if (sr_notify(osthread) != 0) { 3591 ShouldNotReachHere(); 3592 } 3593 3594 // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED 3595 while (true) { 3596 if (sr_semaphore.timedwait(create_timespec(0, 2000 * NANOSECS_PER_MILLISEC))) { 3597 break; 3598 } else { 3599 // timeout 3600 os::SuspendResume::State cancelled = osthread->sr.cancel_suspend(); 3601 if (cancelled == os::SuspendResume::SR_RUNNING) { 3602 return false; 3603 } else if (cancelled == os::SuspendResume::SR_SUSPENDED) { 3604 // make sure that we consume the signal on the semaphore as well 3605 sr_semaphore.wait(); 3606 break; 3607 } else { 3608 ShouldNotReachHere(); 3609 return false; 3610 } 3611 } 3612 } 3613 3614 guarantee(osthread->sr.is_suspended(), "Must be suspended"); 3615 return true; 3616 } 3617 3618 static void do_resume(OSThread* osthread) { 3619 assert(osthread->sr.is_suspended(), "thread should be suspended"); 3620 assert(!sr_semaphore.trywait(), "invalid semaphore state"); 3621 3622 if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) { 3623 // failed to switch to WAKEUP_REQUEST 3624 ShouldNotReachHere(); 3625 return; 3626 } 3627 3628 while (true) { 3629 if (sr_notify(osthread) == 0) { 3630 if (sr_semaphore.timedwait(create_timespec(0, 2 * NANOSECS_PER_MILLISEC))) { 3631 if (osthread->sr.is_running()) { 3632 return; 3633 } 3634 } 3635 } else { 3636 ShouldNotReachHere(); 3637 } 3638 } 3639 3640 guarantee(osthread->sr.is_running(), "Must be running!"); 3641 } 3642 3643 void os::SuspendedThreadTask::internal_do_task() { 3644 if (do_suspend(_thread->osthread())) { 3645 SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext()); 3646 do_task(context); 3647 do_resume(_thread->osthread()); 3648 } 3649 } 3650 |