309 |
309 |
310 struct tm* os::localtime_pd(const time_t* clock, struct tm* res) { |
310 struct tm* os::localtime_pd(const time_t* clock, struct tm* res) { |
311 return localtime_r(clock, res); |
311 return localtime_r(clock, res); |
312 } |
312 } |
313 |
313 |
314 // interruptible infrastructure |
|
315 |
|
316 // setup_interruptible saves the thread state before going into an |
|
317 // interruptible system call. |
|
318 // The saved state is used to restore the thread to |
|
319 // its former state whether or not an interrupt is received. |
|
320 // Used by classloader os::read |
|
321 // os::restartable_read calls skip this layer and stay in _thread_in_native |
|
322 |
|
323 void os::Solaris::setup_interruptible(JavaThread* thread) { |
|
324 |
|
325 JavaThreadState thread_state = thread->thread_state(); |
|
326 |
|
327 assert(thread_state != _thread_blocked, "Coming from the wrong thread"); |
|
328 assert(thread_state != _thread_in_native, "Native threads skip setup_interruptible"); |
|
329 OSThread* osthread = thread->osthread(); |
|
330 osthread->set_saved_interrupt_thread_state(thread_state); |
|
331 thread->frame_anchor()->make_walkable(thread); |
|
332 ThreadStateTransition::transition(thread, thread_state, _thread_blocked); |
|
333 } |
|
334 |
|
335 JavaThread* os::Solaris::setup_interruptible() { |
|
336 JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread(); |
|
337 setup_interruptible(thread); |
|
338 return thread; |
|
339 } |
|
340 |
|
341 void os::Solaris::try_enable_extended_io() { |
314 void os::Solaris::try_enable_extended_io() { |
342 typedef int (*enable_extended_FILE_stdio_t)(int, int); |
315 typedef int (*enable_extended_FILE_stdio_t)(int, int); |
343 |
316 |
344 if (!UseExtendedFileIO) { |
317 if (!UseExtendedFileIO) { |
345 return; |
318 return; |
349 (enable_extended_FILE_stdio_t) dlsym(RTLD_DEFAULT, |
322 (enable_extended_FILE_stdio_t) dlsym(RTLD_DEFAULT, |
350 "enable_extended_FILE_stdio"); |
323 "enable_extended_FILE_stdio"); |
351 if (enabler) { |
324 if (enabler) { |
352 enabler(-1, -1); |
325 enabler(-1, -1); |
353 } |
326 } |
354 } |
|
355 |
|
356 |
|
357 #ifdef ASSERT |
|
358 |
|
359 JavaThread* os::Solaris::setup_interruptible_native() { |
|
360 JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread(); |
|
361 JavaThreadState thread_state = thread->thread_state(); |
|
362 assert(thread_state == _thread_in_native, "Assumed thread_in_native"); |
|
363 return thread; |
|
364 } |
|
365 |
|
366 void os::Solaris::cleanup_interruptible_native(JavaThread* thread) { |
|
367 JavaThreadState thread_state = thread->thread_state(); |
|
368 assert(thread_state == _thread_in_native, "Assumed thread_in_native"); |
|
369 } |
|
370 #endif |
|
371 |
|
372 // cleanup_interruptible reverses the effects of setup_interruptible |
|
373 // setup_interruptible_already_blocked() does not need any cleanup. |
|
374 |
|
375 void os::Solaris::cleanup_interruptible(JavaThread* thread) { |
|
376 OSThread* osthread = thread->osthread(); |
|
377 |
|
378 ThreadStateTransition::transition(thread, _thread_blocked, osthread->saved_interrupt_thread_state()); |
|
379 } |
|
380 |
|
381 // I/O interruption related counters called in _INTERRUPTIBLE |
|
382 |
|
383 void os::Solaris::bump_interrupted_before_count() { |
|
384 RuntimeService::record_interrupted_before_count(); |
|
385 } |
|
386 |
|
387 void os::Solaris::bump_interrupted_during_count() { |
|
388 RuntimeService::record_interrupted_during_count(); |
|
389 } |
327 } |
390 |
328 |
391 static int _processors_online = 0; |
329 static int _processors_online = 0; |
392 |
330 |
393 jint os::Solaris::_os_thread_limit = 0; |
331 jint os::Solaris::_os_thread_limit = 0; |
3364 return true; |
3302 return true; |
3365 } |
3303 } |
3366 |
3304 |
3367 // Read calls from inside the vm need to perform state transitions |
3305 // Read calls from inside the vm need to perform state transitions |
3368 size_t os::read(int fd, void *buf, unsigned int nBytes) { |
3306 size_t os::read(int fd, void *buf, unsigned int nBytes) { |
3369 INTERRUPTIBLE_RETURN_INT_VM(::read(fd, buf, nBytes), os::Solaris::clear_interrupted); |
3307 size_t res; |
|
3308 JavaThread* thread = (JavaThread*)Thread::current(); |
|
3309 assert(thread->thread_state() == _thread_in_vm, "Assumed _thread_in_vm"); |
|
3310 ThreadBlockInVM tbiv(thread); |
|
3311 RESTARTABLE(::read(fd, buf, (size_t) nBytes), res); |
|
3312 return res; |
3370 } |
3313 } |
3371 |
3314 |
3372 size_t os::restartable_read(int fd, void *buf, unsigned int nBytes) { |
3315 size_t os::restartable_read(int fd, void *buf, unsigned int nBytes) { |
3373 INTERRUPTIBLE_RETURN_INT(::read(fd, buf, nBytes), os::Solaris::clear_interrupted); |
3316 size_t res; |
|
3317 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, |
|
3318 "Assumed _thread_in_native"); |
|
3319 RESTARTABLE(::read(fd, buf, (size_t) nBytes), res); |
|
3320 return res; |
3374 } |
3321 } |
3375 |
3322 |
3376 void os::naked_short_sleep(jlong ms) { |
3323 void os::naked_short_sleep(jlong ms) { |
3377 assert(ms < 1000, "Un-interruptable sleep, short time use only"); |
3324 assert(ms < 1000, "Un-interruptable sleep, short time use only"); |
3378 |
3325 |
5303 int os::fsync(int fd) { |
5250 int os::fsync(int fd) { |
5304 RESTARTABLE_RETURN_INT(::fsync(fd)); |
5251 RESTARTABLE_RETURN_INT(::fsync(fd)); |
5305 } |
5252 } |
5306 |
5253 |
5307 int os::available(int fd, jlong *bytes) { |
5254 int os::available(int fd, jlong *bytes) { |
|
5255 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, |
|
5256 "Assumed _thread_in_native"); |
5308 jlong cur, end; |
5257 jlong cur, end; |
5309 int mode; |
5258 int mode; |
5310 struct stat64 buf64; |
5259 struct stat64 buf64; |
5311 |
5260 |
5312 if (::fstat64(fd, &buf64) >= 0) { |
5261 if (::fstat64(fd, &buf64) >= 0) { |
5313 mode = buf64.st_mode; |
5262 mode = buf64.st_mode; |
5314 if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { |
5263 if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { |
5315 /* |
|
5316 * XXX: is the following call interruptible? If so, this might |
|
5317 * need to go through the INTERRUPT_IO() wrapper as for other |
|
5318 * blocking, interruptible calls in this file. |
|
5319 */ |
|
5320 int n,ioctl_return; |
5264 int n,ioctl_return; |
5321 |
5265 |
5322 INTERRUPTIBLE(::ioctl(fd, FIONREAD, &n),ioctl_return,os::Solaris::clear_interrupted); |
5266 RESTARTABLE(::ioctl(fd, FIONREAD, &n), ioctl_return); |
5323 if (ioctl_return>= 0) { |
5267 if (ioctl_return>= 0) { |
5324 *bytes = n; |
5268 *bytes = n; |
5325 return 1; |
5269 return 1; |
5326 } |
5270 } |
5327 } |
5271 } |
6248 |
6192 |
6249 return true; |
6193 return true; |
6250 } |
6194 } |
6251 |
6195 |
6252 size_t os::write(int fd, const void *buf, unsigned int nBytes) { |
6196 size_t os::write(int fd, const void *buf, unsigned int nBytes) { |
6253 INTERRUPTIBLE_RETURN_INT(::write(fd, buf, nBytes), os::Solaris::clear_interrupted); |
6197 size_t res; |
|
6198 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, |
|
6199 "Assumed _thread_in_native"); |
|
6200 RESTARTABLE((size_t) ::write(fd, buf, (size_t) nBytes), res); |
|
6201 return res; |
6254 } |
6202 } |
6255 |
6203 |
6256 int os::close(int fd) { |
6204 int os::close(int fd) { |
6257 return ::close(fd); |
6205 return ::close(fd); |
6258 } |
6206 } |
6260 int os::socket_close(int fd) { |
6208 int os::socket_close(int fd) { |
6261 return ::close(fd); |
6209 return ::close(fd); |
6262 } |
6210 } |
6263 |
6211 |
6264 int os::recv(int fd, char* buf, size_t nBytes, uint flags) { |
6212 int os::recv(int fd, char* buf, size_t nBytes, uint flags) { |
6265 INTERRUPTIBLE_RETURN_INT((int)::recv(fd, buf, nBytes, flags), os::Solaris::clear_interrupted); |
6213 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, |
|
6214 "Assumed _thread_in_native"); |
|
6215 RESTARTABLE_RETURN_INT((int)::recv(fd, buf, nBytes, flags)); |
6266 } |
6216 } |
6267 |
6217 |
6268 int os::send(int fd, char* buf, size_t nBytes, uint flags) { |
6218 int os::send(int fd, char* buf, size_t nBytes, uint flags) { |
6269 INTERRUPTIBLE_RETURN_INT((int)::send(fd, buf, nBytes, flags), os::Solaris::clear_interrupted); |
6219 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, |
|
6220 "Assumed _thread_in_native"); |
|
6221 RESTARTABLE_RETURN_INT((int)::send(fd, buf, nBytes, flags)); |
6270 } |
6222 } |
6271 |
6223 |
6272 int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) { |
6224 int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) { |
6273 RESTARTABLE_RETURN_INT((int)::send(fd, buf, nBytes, flags)); |
6225 RESTARTABLE_RETURN_INT((int)::send(fd, buf, nBytes, flags)); |
6274 } |
6226 } |
6285 static const char* aNull = 0; |
6237 static const char* aNull = 0; |
6286 struct pollfd pfd; |
6238 struct pollfd pfd; |
6287 pfd.fd = fd; |
6239 pfd.fd = fd; |
6288 pfd.events = POLLIN; |
6240 pfd.events = POLLIN; |
6289 |
6241 |
|
6242 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, |
|
6243 "Assumed _thread_in_native"); |
|
6244 |
6290 gettimeofday(&t, &aNull); |
6245 gettimeofday(&t, &aNull); |
6291 prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; |
6246 prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; |
6292 |
6247 |
6293 for(;;) { |
6248 for(;;) { |
6294 INTERRUPTIBLE_NORESTART(::poll(&pfd, 1, timeout), res, os::Solaris::clear_interrupted); |
6249 res = ::poll(&pfd, 1, timeout); |
6295 if(res == OS_ERR && errno == EINTR) { |
6250 if(res == OS_ERR && errno == EINTR) { |
6296 if(timeout != -1) { |
6251 if(timeout != -1) { |
6297 gettimeofday(&t, &aNull); |
6252 gettimeofday(&t, &aNull); |
6298 newtime = ((julong)t.tv_sec * 1000) + t.tv_usec /1000; |
6253 newtime = ((julong)t.tv_sec * 1000) + t.tv_usec /1000; |
6299 timeout -= newtime - prevtime; |
6254 timeout -= newtime - prevtime; |
6305 } |
6260 } |
6306 } |
6261 } |
6307 |
6262 |
6308 int os::connect(int fd, struct sockaddr *him, socklen_t len) { |
6263 int os::connect(int fd, struct sockaddr *him, socklen_t len) { |
6309 int _result; |
6264 int _result; |
6310 INTERRUPTIBLE_NORESTART(::connect(fd, him, len), _result,\ |
6265 _result = ::connect(fd, him, len); |
6311 os::Solaris::clear_interrupted); |
6266 |
6312 |
6267 // On Solaris, when a connect() call is interrupted, the connection |
6313 // Depending on when thread interruption is reset, _result could be |
6268 // can be established asynchronously (see 6343810). Subsequent calls |
6314 // one of two values when errno == EINTR |
6269 // to connect() must check the errno value which has the semantic |
6315 |
6270 // described below (copied from the connect() man page). Handling |
6316 if (((_result == OS_INTRPT) || (_result == OS_ERR)) |
6271 // of asynchronously established connections is required for both |
6317 && (errno == EINTR)) { |
6272 // blocking and non-blocking sockets. |
|
6273 // EINTR The connection attempt was interrupted |
|
6274 // before any data arrived by the delivery of |
|
6275 // a signal. The connection, however, will be |
|
6276 // established asynchronously. |
|
6277 // |
|
6278 // EINPROGRESS The socket is non-blocking, and the connec- |
|
6279 // tion cannot be completed immediately. |
|
6280 // |
|
6281 // EALREADY The socket is non-blocking, and a previous |
|
6282 // connection attempt has not yet been com- |
|
6283 // pleted. |
|
6284 // |
|
6285 // EISCONN The socket is already connected. |
|
6286 if (_result == OS_ERR && errno == EINTR) { |
6318 /* restarting a connect() changes its errno semantics */ |
6287 /* restarting a connect() changes its errno semantics */ |
6319 INTERRUPTIBLE(::connect(fd, him, len), _result,\ |
6288 RESTARTABLE(::connect(fd, him, len), _result); |
6320 os::Solaris::clear_interrupted); |
|
6321 /* undo these changes */ |
6289 /* undo these changes */ |
6322 if (_result == OS_ERR) { |
6290 if (_result == OS_ERR) { |
6323 if (errno == EALREADY) { |
6291 if (errno == EALREADY) { |
6324 errno = EINPROGRESS; /* fall through */ |
6292 errno = EINPROGRESS; /* fall through */ |
6325 } else if (errno == EISCONN) { |
6293 } else if (errno == EISCONN) { |
6333 |
6301 |
6334 int os::accept(int fd, struct sockaddr* him, socklen_t* len) { |
6302 int os::accept(int fd, struct sockaddr* him, socklen_t* len) { |
6335 if (fd < 0) { |
6303 if (fd < 0) { |
6336 return OS_ERR; |
6304 return OS_ERR; |
6337 } |
6305 } |
6338 INTERRUPTIBLE_RETURN_INT((int)::accept(fd, him, len),\ |
6306 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, |
6339 os::Solaris::clear_interrupted); |
6307 "Assumed _thread_in_native"); |
|
6308 RESTARTABLE_RETURN_INT((int)::accept(fd, him, len)); |
6340 } |
6309 } |
6341 |
6310 |
6342 int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags, |
6311 int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags, |
6343 sockaddr* from, socklen_t* fromlen) { |
6312 sockaddr* from, socklen_t* fromlen) { |
6344 INTERRUPTIBLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen),\ |
6313 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, |
6345 os::Solaris::clear_interrupted); |
6314 "Assumed _thread_in_native"); |
|
6315 RESTARTABLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen)); |
6346 } |
6316 } |
6347 |
6317 |
6348 int os::sendto(int fd, char* buf, size_t len, uint flags, |
6318 int os::sendto(int fd, char* buf, size_t len, uint flags, |
6349 struct sockaddr* to, socklen_t tolen) { |
6319 struct sockaddr* to, socklen_t tolen) { |
6350 INTERRUPTIBLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen),\ |
6320 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, |
6351 os::Solaris::clear_interrupted); |
6321 "Assumed _thread_in_native"); |
|
6322 RESTARTABLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen)); |
6352 } |
6323 } |
6353 |
6324 |
6354 int os::socket_available(int fd, jint *pbytes) { |
6325 int os::socket_available(int fd, jint *pbytes) { |
6355 if (fd < 0) { |
6326 if (fd < 0) { |
6356 return OS_OK; |
6327 return OS_OK; |
6361 // is expected to return 0 on failure and 1 on success to the jdk. |
6332 // is expected to return 0 on failure and 1 on success to the jdk. |
6362 return (ret == OS_ERR) ? 0 : 1; |
6333 return (ret == OS_ERR) ? 0 : 1; |
6363 } |
6334 } |
6364 |
6335 |
6365 int os::bind(int fd, struct sockaddr* him, socklen_t len) { |
6336 int os::bind(int fd, struct sockaddr* him, socklen_t len) { |
6366 INTERRUPTIBLE_RETURN_INT_NORESTART(::bind(fd, him, len),\ |
6337 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, |
6367 os::Solaris::clear_interrupted); |
6338 "Assumed _thread_in_native"); |
|
6339 return ::bind(fd, him, len); |
6368 } |
6340 } |
6369 |
6341 |
6370 // Get the default path to the core file |
6342 // Get the default path to the core file |
6371 // Returns the length of the string |
6343 // Returns the length of the string |
6372 int os::get_core_path(char* buffer, size_t bufferSize) { |
6344 int os::get_core_path(char* buffer, size_t bufferSize) { |