Mercurial > hg > graal-jvmci-8
comparison src/os/solaris/vm/os_solaris.cpp @ 14909:4ca6dc0799b6
Backout jdk9 merge
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Tue, 01 Apr 2014 13:57:07 +0200 |
parents | d8041d695d19 |
children | b1911c1e44c8 |
comparison
equal
deleted
inserted
replaced
14908:8db6e76cb658 | 14909:4ca6dc0799b6 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
330 osthread->set_saved_interrupt_thread_state(thread_state); | 330 osthread->set_saved_interrupt_thread_state(thread_state); |
331 thread->frame_anchor()->make_walkable(thread); | 331 thread->frame_anchor()->make_walkable(thread); |
332 ThreadStateTransition::transition(thread, thread_state, _thread_blocked); | 332 ThreadStateTransition::transition(thread, thread_state, _thread_blocked); |
333 } | 333 } |
334 | 334 |
335 // Version of setup_interruptible() for threads that are already in | |
336 // _thread_blocked. Used by os_sleep(). | |
337 void os::Solaris::setup_interruptible_already_blocked(JavaThread* thread) { | |
338 thread->frame_anchor()->make_walkable(thread); | |
339 } | |
340 | |
335 JavaThread* os::Solaris::setup_interruptible() { | 341 JavaThread* os::Solaris::setup_interruptible() { |
336 JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread(); | 342 JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread(); |
337 setup_interruptible(thread); | 343 setup_interruptible(thread); |
338 return thread; | 344 return thread; |
339 } | 345 } |
2138 | 2144 |
2139 void* os::dll_lookup(void* handle, const char* name) { | 2145 void* os::dll_lookup(void* handle, const char* name) { |
2140 return dlsym(handle, name); | 2146 return dlsym(handle, name); |
2141 } | 2147 } |
2142 | 2148 |
2143 void* os::get_default_process_handle() { | |
2144 return (void*)::dlopen(NULL, RTLD_LAZY); | |
2145 } | |
2146 | |
2147 int os::stat(const char *path, struct stat *sbuf) { | 2149 int os::stat(const char *path, struct stat *sbuf) { |
2148 char pathbuf[MAX_PATH]; | 2150 char pathbuf[MAX_PATH]; |
2149 if (strlen(path) > MAX_PATH - 1) { | 2151 if (strlen(path) > MAX_PATH - 1) { |
2150 errno = ENAMETOOLONG; | 2152 errno = ENAMETOOLONG; |
2151 return -1; | 2153 return -1; |
2224 st->print("%s",(p.pr_mflags & MA_WRITE) ? "w" : "-"); | 2226 st->print("%s",(p.pr_mflags & MA_WRITE) ? "w" : "-"); |
2225 st->print("%s",(p.pr_mflags & MA_EXEC) ? "x" : "-"); | 2227 st->print("%s",(p.pr_mflags & MA_EXEC) ? "x" : "-"); |
2226 st->cr(); | 2228 st->cr(); |
2227 status = true; | 2229 status = true; |
2228 } | 2230 } |
2229 } | 2231 ::close(fd); |
2230 ::close(fd); | 2232 } |
2231 } | 2233 } |
2232 return status; | 2234 return status; |
2233 } | 2235 } |
2234 | 2236 |
2235 void os::pd_print_cpu_info(outputStream* st) { | 2237 void os::pd_print_cpu_info(outputStream* st) { |
2243 st->print("(" UINT64_FORMAT "k free)", os::available_memory() >> 10); | 2245 st->print("(" UINT64_FORMAT "k free)", os::available_memory() >> 10); |
2244 st->cr(); | 2246 st->cr(); |
2245 (void) check_addr0(st); | 2247 (void) check_addr0(st); |
2246 } | 2248 } |
2247 | 2249 |
2250 // Taken from /usr/include/sys/machsig.h Supposed to be architecture specific | |
2251 // but they're the same for all the solaris architectures that we support. | |
2252 const char *ill_names[] = { "ILL0", "ILL_ILLOPC", "ILL_ILLOPN", "ILL_ILLADR", | |
2253 "ILL_ILLTRP", "ILL_PRVOPC", "ILL_PRVREG", | |
2254 "ILL_COPROC", "ILL_BADSTK" }; | |
2255 | |
2256 const char *fpe_names[] = { "FPE0", "FPE_INTDIV", "FPE_INTOVF", "FPE_FLTDIV", | |
2257 "FPE_FLTOVF", "FPE_FLTUND", "FPE_FLTRES", | |
2258 "FPE_FLTINV", "FPE_FLTSUB" }; | |
2259 | |
2260 const char *segv_names[] = { "SEGV0", "SEGV_MAPERR", "SEGV_ACCERR" }; | |
2261 | |
2262 const char *bus_names[] = { "BUS0", "BUS_ADRALN", "BUS_ADRERR", "BUS_OBJERR" }; | |
2263 | |
2248 void os::print_siginfo(outputStream* st, void* siginfo) { | 2264 void os::print_siginfo(outputStream* st, void* siginfo) { |
2249 const siginfo_t* si = (const siginfo_t*)siginfo; | 2265 st->print("siginfo:"); |
2250 | 2266 |
2251 os::Posix::print_siginfo_brief(st, si); | 2267 const int buflen = 100; |
2252 | 2268 char buf[buflen]; |
2253 if (si && (si->si_signo == SIGBUS || si->si_signo == SIGSEGV) && | 2269 siginfo_t *si = (siginfo_t*)siginfo; |
2270 st->print("si_signo=%s: ", os::exception_name(si->si_signo, buf, buflen)); | |
2271 char *err = strerror(si->si_errno); | |
2272 if (si->si_errno != 0 && err != NULL) { | |
2273 st->print("si_errno=%s", err); | |
2274 } else { | |
2275 st->print("si_errno=%d", si->si_errno); | |
2276 } | |
2277 const int c = si->si_code; | |
2278 assert(c > 0, "unexpected si_code"); | |
2279 switch (si->si_signo) { | |
2280 case SIGILL: | |
2281 st->print(", si_code=%d (%s)", c, c > 8 ? "" : ill_names[c]); | |
2282 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
2283 break; | |
2284 case SIGFPE: | |
2285 st->print(", si_code=%d (%s)", c, c > 9 ? "" : fpe_names[c]); | |
2286 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
2287 break; | |
2288 case SIGSEGV: | |
2289 st->print(", si_code=%d (%s)", c, c > 2 ? "" : segv_names[c]); | |
2290 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
2291 break; | |
2292 case SIGBUS: | |
2293 st->print(", si_code=%d (%s)", c, c > 3 ? "" : bus_names[c]); | |
2294 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
2295 break; | |
2296 default: | |
2297 st->print(", si_code=%d", si->si_code); | |
2298 // no si_addr | |
2299 } | |
2300 | |
2301 if ((si->si_signo == SIGBUS || si->si_signo == SIGSEGV) && | |
2254 UseSharedSpaces) { | 2302 UseSharedSpaces) { |
2255 FileMapInfo* mapinfo = FileMapInfo::current_info(); | 2303 FileMapInfo* mapinfo = FileMapInfo::current_info(); |
2256 if (mapinfo->is_in_shared_space(si->si_addr)) { | 2304 if (mapinfo->is_in_shared_space(si->si_addr)) { |
2257 st->print("\n\nError accessing class data sharing archive." \ | 2305 st->print("\n\nError accessing class data sharing archive." \ |
2258 " Mapped file inaccessible during execution, " \ | 2306 " Mapped file inaccessible during execution, " \ |
2318 st->print("SIG_IGN"); | 2366 st->print("SIG_IGN"); |
2319 } else { | 2367 } else { |
2320 st->print("[%s]", get_signal_handler_name(handler, buf, buflen)); | 2368 st->print("[%s]", get_signal_handler_name(handler, buf, buflen)); |
2321 } | 2369 } |
2322 | 2370 |
2323 st->print(", sa_mask[0]="); | 2371 st->print(", sa_mask[0]=" PTR32_FORMAT, *(uint32_t*)&sa.sa_mask); |
2324 os::Posix::print_signal_set_short(st, &sa.sa_mask); | |
2325 | 2372 |
2326 address rh = VMError::get_resetted_sighandler(sig); | 2373 address rh = VMError::get_resetted_sighandler(sig); |
2327 // May be, handler was resetted by VMError? | 2374 // May be, handler was resetted by VMError? |
2328 if(rh != NULL) { | 2375 if(rh != NULL) { |
2329 handler = rh; | 2376 handler = rh; |
2330 sa.sa_flags = VMError::get_resetted_sigflags(sig); | 2377 sa.sa_flags = VMError::get_resetted_sigflags(sig); |
2331 } | 2378 } |
2332 | 2379 |
2333 st->print(", sa_flags="); | 2380 st->print(", sa_flags=" PTR32_FORMAT, sa.sa_flags); |
2334 os::Posix::print_sa_flags(st, sa.sa_flags); | |
2335 | 2381 |
2336 // Check: is it our handler? | 2382 // Check: is it our handler? |
2337 if(handler == CAST_FROM_FN_PTR(address, signalHandler) || | 2383 if(handler == CAST_FROM_FN_PTR(address, signalHandler) || |
2338 handler == CAST_FROM_FN_PTR(address, sigINTRHandler)) { | 2384 handler == CAST_FROM_FN_PTR(address, sigINTRHandler)) { |
2339 // It is our signal handler | 2385 // It is our signal handler |
2389 } else { | 2435 } else { |
2390 buf[0] = '\0'; | 2436 buf[0] = '\0'; |
2391 return; | 2437 return; |
2392 } | 2438 } |
2393 | 2439 |
2394 if (Arguments::sun_java_launcher_is_altjvm()) { | 2440 if (Arguments::created_by_gamma_launcher()) { |
2395 // Support for the java launcher's '-XXaltjvm=<path>' option. Typical | 2441 // Support for the gamma launcher. Typical value for buf is |
2396 // value for buf is "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". | 2442 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at |
2397 // If "/jre/lib/" appears at the right place in the string, then | 2443 // the right place in the string, then assume we are installed in a JDK and |
2398 // assume we are installed in a JDK and we're done. Otherwise, check | 2444 // we're done. Otherwise, check for a JAVA_HOME environment variable and fix |
2399 // for a JAVA_HOME environment variable and fix up the path so it | 2445 // up the path so it looks like libjvm.so is installed there (append a |
2400 // looks like libjvm.so is installed there (append a fake suffix | 2446 // fake suffix hotspot/libjvm.so). |
2401 // hotspot/libjvm.so). | |
2402 const char *p = buf + strlen(buf) - 1; | 2447 const char *p = buf + strlen(buf) - 1; |
2403 for (int count = 0; p > buf && count < 5; ++count) { | 2448 for (int count = 0; p > buf && count < 5; ++count) { |
2404 for (--p; p > buf && *p != '/'; --p) | 2449 for (--p; p > buf && *p != '/'; --p) |
2405 /* empty */ ; | 2450 /* empty */ ; |
2406 } | 2451 } |
2960 // Scan the pages from start to end until a page different than | 3005 // Scan the pages from start to end until a page different than |
2961 // the one described in the info parameter is encountered. | 3006 // the one described in the info parameter is encountered. |
2962 char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) { | 3007 char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) { |
2963 const uint_t info_types[] = { MEMINFO_VLGRP, MEMINFO_VPAGESIZE }; | 3008 const uint_t info_types[] = { MEMINFO_VLGRP, MEMINFO_VPAGESIZE }; |
2964 const size_t types = sizeof(info_types) / sizeof(info_types[0]); | 3009 const size_t types = sizeof(info_types) / sizeof(info_types[0]); |
2965 uint64_t addrs[MAX_MEMINFO_CNT], outdata[types * MAX_MEMINFO_CNT + 1]; | 3010 uint64_t addrs[MAX_MEMINFO_CNT], outdata[types * MAX_MEMINFO_CNT]; |
2966 uint_t validity[MAX_MEMINFO_CNT]; | 3011 uint_t validity[MAX_MEMINFO_CNT]; |
2967 | 3012 |
2968 size_t page_size = MAX2((size_t)os::vm_page_size(), page_expected->size); | 3013 size_t page_size = MAX2((size_t)os::vm_page_size(), page_expected->size); |
2969 uint64_t p = (uint64_t)start; | 3014 uint64_t p = (uint64_t)start; |
2970 while (p < (uint64_t)end) { | 3015 while (p < (uint64_t)end) { |
2999 } else { | 3044 } else { |
3000 return NULL; | 3045 return NULL; |
3001 } | 3046 } |
3002 } | 3047 } |
3003 | 3048 |
3004 if (i < addrs_count) { | 3049 if (i != addrs_count) { |
3005 if ((validity[i] & 2) != 0) { | 3050 if ((validity[i] & 2) != 0) { |
3006 page_found->lgrp_id = outdata[types * i]; | 3051 page_found->lgrp_id = outdata[types * i]; |
3007 } else { | 3052 } else { |
3008 page_found->lgrp_id = -1; | 3053 page_found->lgrp_id = -1; |
3009 } | 3054 } |
3362 | 3407 |
3363 bool os::can_execute_large_page_memory() { | 3408 bool os::can_execute_large_page_memory() { |
3364 return true; | 3409 return true; |
3365 } | 3410 } |
3366 | 3411 |
3412 static int os_sleep(jlong millis, bool interruptible) { | |
3413 const jlong limit = INT_MAX; | |
3414 jlong prevtime; | |
3415 int res; | |
3416 | |
3417 while (millis > limit) { | |
3418 if ((res = os_sleep(limit, interruptible)) != OS_OK) | |
3419 return res; | |
3420 millis -= limit; | |
3421 } | |
3422 | |
3423 // Restart interrupted polls with new parameters until the proper delay | |
3424 // has been completed. | |
3425 | |
3426 prevtime = getTimeMillis(); | |
3427 | |
3428 while (millis > 0) { | |
3429 jlong newtime; | |
3430 | |
3431 if (!interruptible) { | |
3432 // Following assert fails for os::yield_all: | |
3433 // assert(!thread->is_Java_thread(), "must not be java thread"); | |
3434 res = poll(NULL, 0, millis); | |
3435 } else { | |
3436 JavaThread *jt = JavaThread::current(); | |
3437 | |
3438 INTERRUPTIBLE_NORESTART_VM_ALWAYS(poll(NULL, 0, millis), res, jt, | |
3439 os::Solaris::clear_interrupted); | |
3440 } | |
3441 | |
3442 // INTERRUPTIBLE_NORESTART_VM_ALWAYS returns res == OS_INTRPT for | |
3443 // thread.Interrupt. | |
3444 | |
3445 // See c/r 6751923. Poll can return 0 before time | |
3446 // has elapsed if time is set via clock_settime (as NTP does). | |
3447 // res == 0 if poll timed out (see man poll RETURN VALUES) | |
3448 // using the logic below checks that we really did | |
3449 // sleep at least "millis" if not we'll sleep again. | |
3450 if( ( res == 0 ) || ((res == OS_ERR) && (errno == EINTR))) { | |
3451 newtime = getTimeMillis(); | |
3452 assert(newtime >= prevtime, "time moving backwards"); | |
3453 /* Doing prevtime and newtime in microseconds doesn't help precision, | |
3454 and trying to round up to avoid lost milliseconds can result in a | |
3455 too-short delay. */ | |
3456 millis -= newtime - prevtime; | |
3457 if(millis <= 0) | |
3458 return OS_OK; | |
3459 prevtime = newtime; | |
3460 } else | |
3461 return res; | |
3462 } | |
3463 | |
3464 return OS_OK; | |
3465 } | |
3466 | |
3367 // Read calls from inside the vm need to perform state transitions | 3467 // Read calls from inside the vm need to perform state transitions |
3368 size_t os::read(int fd, void *buf, unsigned int nBytes) { | 3468 size_t os::read(int fd, void *buf, unsigned int nBytes) { |
3369 INTERRUPTIBLE_RETURN_INT_VM(::read(fd, buf, nBytes), os::Solaris::clear_interrupted); | 3469 INTERRUPTIBLE_RETURN_INT_VM(::read(fd, buf, nBytes), os::Solaris::clear_interrupted); |
3370 } | 3470 } |
3371 | 3471 |
3372 size_t os::restartable_read(int fd, void *buf, unsigned int nBytes) { | 3472 size_t os::restartable_read(int fd, void *buf, unsigned int nBytes) { |
3373 INTERRUPTIBLE_RETURN_INT(::read(fd, buf, nBytes), os::Solaris::clear_interrupted); | 3473 INTERRUPTIBLE_RETURN_INT(::read(fd, buf, nBytes), os::Solaris::clear_interrupted); |
3374 } | 3474 } |
3375 | 3475 |
3376 void os::naked_short_sleep(jlong ms) { | 3476 int os::sleep(Thread* thread, jlong millis, bool interruptible) { |
3377 assert(ms < 1000, "Un-interruptable sleep, short time use only"); | 3477 assert(thread == Thread::current(), "thread consistency check"); |
3378 | 3478 |
3379 // usleep is deprecated and removed from POSIX, in favour of nanosleep, but | 3479 // TODO-FIXME: this should be removed. |
3380 // Solaris requires -lrt for this. | 3480 // On Solaris machines (especially 2.5.1) we found that sometimes the VM gets into a live lock |
3381 usleep((ms * 1000)); | 3481 // situation with a JavaThread being starved out of a lwp. The kernel doesn't seem to generate |
3382 | 3482 // a SIGWAITING signal which would enable the threads library to create a new lwp for the starving |
3383 return; | 3483 // thread. We suspect that because the Watcher thread keeps waking up at periodic intervals the kernel |
3484 // is fooled into believing that the system is making progress. In the code below we block the | |
3485 // the watcher thread while safepoint is in progress so that it would not appear as though the | |
3486 // system is making progress. | |
3487 if (!Solaris::T2_libthread() && | |
3488 thread->is_Watcher_thread() && SafepointSynchronize::is_synchronizing() && !Arguments::has_profile()) { | |
3489 // We now try to acquire the threads lock. Since this lock is held by the VM thread during | |
3490 // the entire safepoint, the watcher thread will line up here during the safepoint. | |
3491 Threads_lock->lock_without_safepoint_check(); | |
3492 Threads_lock->unlock(); | |
3493 } | |
3494 | |
3495 if (thread->is_Java_thread()) { | |
3496 // This is a JavaThread so we honor the _thread_blocked protocol | |
3497 // even for sleeps of 0 milliseconds. This was originally done | |
3498 // as a workaround for bug 4338139. However, now we also do it | |
3499 // to honor the suspend-equivalent protocol. | |
3500 | |
3501 JavaThread *jt = (JavaThread *) thread; | |
3502 ThreadBlockInVM tbivm(jt); | |
3503 | |
3504 jt->set_suspend_equivalent(); | |
3505 // cleared by handle_special_suspend_equivalent_condition() or | |
3506 // java_suspend_self() via check_and_wait_while_suspended() | |
3507 | |
3508 int ret_code; | |
3509 if (millis <= 0) { | |
3510 thr_yield(); | |
3511 ret_code = 0; | |
3512 } else { | |
3513 // The original sleep() implementation did not create an | |
3514 // OSThreadWaitState helper for sleeps of 0 milliseconds. | |
3515 // I'm preserving that decision for now. | |
3516 OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */); | |
3517 | |
3518 ret_code = os_sleep(millis, interruptible); | |
3519 } | |
3520 | |
3521 // were we externally suspended while we were waiting? | |
3522 jt->check_and_wait_while_suspended(); | |
3523 | |
3524 return ret_code; | |
3525 } | |
3526 | |
3527 // non-JavaThread from this point on: | |
3528 | |
3529 if (millis <= 0) { | |
3530 thr_yield(); | |
3531 return 0; | |
3532 } | |
3533 | |
3534 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); | |
3535 | |
3536 return os_sleep(millis, interruptible); | |
3537 } | |
3538 | |
3539 int os::naked_sleep() { | |
3540 // %% make the sleep time an integer flag. for now use 1 millisec. | |
3541 return os_sleep(1, false); | |
3384 } | 3542 } |
3385 | 3543 |
3386 // Sleep forever; naked call to OS-specific sleep; use with CAUTION | 3544 // Sleep forever; naked call to OS-specific sleep; use with CAUTION |
3387 void os::infinite_sleep() { | 3545 void os::infinite_sleep() { |
3388 while (true) { // sleep forever ... | 3546 while (true) { // sleep forever ... |
4012 // ignore | 4170 // ignore |
4013 } | 4171 } |
4014 | 4172 |
4015 errno = old_errno; | 4173 errno = old_errno; |
4016 } | 4174 } |
4175 | |
4176 | |
4177 void os::interrupt(Thread* thread) { | |
4178 assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer"); | |
4179 | |
4180 OSThread* osthread = thread->osthread(); | |
4181 | |
4182 int isInterrupted = osthread->interrupted(); | |
4183 if (!isInterrupted) { | |
4184 osthread->set_interrupted(true); | |
4185 OrderAccess::fence(); | |
4186 // os::sleep() is implemented with either poll (NULL,0,timeout) or | |
4187 // by parking on _SleepEvent. If the former, thr_kill will unwedge | |
4188 // the sleeper by SIGINTR, otherwise the unpark() will wake the sleeper. | |
4189 ParkEvent * const slp = thread->_SleepEvent ; | |
4190 if (slp != NULL) slp->unpark() ; | |
4191 } | |
4192 | |
4193 // For JSR166: unpark after setting status but before thr_kill -dl | |
4194 if (thread->is_Java_thread()) { | |
4195 ((JavaThread*)thread)->parker()->unpark(); | |
4196 } | |
4197 | |
4198 // Handle interruptible wait() ... | |
4199 ParkEvent * const ev = thread->_ParkEvent ; | |
4200 if (ev != NULL) ev->unpark() ; | |
4201 | |
4202 // When events are used everywhere for os::sleep, then this thr_kill | |
4203 // will only be needed if UseVMInterruptibleIO is true. | |
4204 | |
4205 if (!isInterrupted) { | |
4206 int status = thr_kill(osthread->thread_id(), os::Solaris::SIGinterrupt()); | |
4207 assert_status(status == 0, status, "thr_kill"); | |
4208 | |
4209 // Bump thread interruption counter | |
4210 RuntimeService::record_thread_interrupt_signaled_count(); | |
4211 } | |
4212 } | |
4213 | |
4214 | |
4215 bool os::is_interrupted(Thread* thread, bool clear_interrupted) { | |
4216 assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer"); | |
4217 | |
4218 OSThread* osthread = thread->osthread(); | |
4219 | |
4220 bool res = osthread->interrupted(); | |
4221 | |
4222 // NOTE that since there is no "lock" around these two operations, | |
4223 // there is the possibility that the interrupted flag will be | |
4224 // "false" but that the interrupt event will be set. This is | |
4225 // intentional. The effect of this is that Object.wait() will appear | |
4226 // to have a spurious wakeup, which is not harmful, and the | |
4227 // possibility is so rare that it is not worth the added complexity | |
4228 // to add yet another lock. It has also been recommended not to put | |
4229 // the interrupted flag into the os::Solaris::Event structure, | |
4230 // because it hides the issue. | |
4231 if (res && clear_interrupted) { | |
4232 osthread->set_interrupted(false); | |
4233 } | |
4234 return res; | |
4235 } | |
4236 | |
4017 | 4237 |
4018 void os::print_statistics() { | 4238 void os::print_statistics() { |
4019 } | 4239 } |
4020 | 4240 |
4021 int os::message_box(const char* title, const char* message) { | 4241 int os::message_box(const char* title, const char* message) { |