os_solaris.inline.hpp revision 3465:d2a62e0f25eb
169408Sache/*
269408Sache * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
3100616Smp * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4231990Smp *
5195609Smp * This code is free software; you can redistribute it and/or modify it
6100616Smp * under the terms of the GNU General Public License version 2 only, as
7231990Smp * published by the Free Software Foundation.
8100616Smp *
969408Sache * This code is distributed in the hope that it will be useful, but WITHOUT
1069408Sache * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1169408Sache * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1269408Sache * version 2 for more details (a copy is included in the LICENSE file that
1369408Sache * accompanied this code).
1469408Sache *
1569408Sache * You should have received a copy of the GNU General Public License version
1669408Sache * 2 along with this work; if not, write to the Free Software Foundation,
1769408Sache * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1869408Sache *
1969408Sache * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2069408Sache * or visit www.oracle.com if you need additional information or have any
21195609Smp * questions.
22195609Smp *
2369408Sache */
2469408Sache
2569408Sache#ifndef OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP
2669408Sache#define OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP
2769408Sache
2869408Sache#include "runtime/atomic.hpp"
29195609Smp#include "runtime/os.hpp"
30231990Smp#ifdef TARGET_OS_ARCH_solaris_x86
31231990Smp# include "atomic_solaris_x86.inline.hpp"
32231990Smp# include "orderAccess_solaris_x86.inline.hpp"
3369408Sache#endif
3469408Sache#ifdef TARGET_OS_ARCH_solaris_sparc
3569408Sache# include "atomic_solaris_sparc.inline.hpp"
3669408Sache# include "orderAccess_solaris_sparc.inline.hpp"
3769408Sache#endif
38231990Smp
39231990Smp// System includes
4069408Sache#include <sys/param.h>
41100616Smp#include <dlfcn.h>
42100616Smp#include <sys/socket.h>
43100616Smp#include <sys/poll.h>
44100616Smp#include <sys/filio.h>
45100616Smp#include <unistd.h>
46100616Smp#include <netdb.h>
47100616Smp#include <setjmp.h>
48100616Smp
49100616Smpinline const char* os::file_separator() { return "/"; }
50100616Smpinline const char* os::line_separator() { return "\n"; }
51100616Smpinline const char* os::path_separator() { return ":"; }
52100616Smp
53100616Smpinline const char* os::jlong_format_specifier()   { return "%lld"; }
54100616Smpinline const char* os::julong_format_specifier()  { return "%llu"; }
55100616Smp
56100616Smp// File names are case-sensitive on windows only
57100616Smpinline int os::file_name_strcmp(const char* s1, const char* s2) {
58100616Smp  return strcmp(s1, s2);
59231990Smp}
60231990Smp
61231990Smpinline bool os::uses_stack_guard_pages() {
62100616Smp  return true;
63100616Smp}
64100616Smp
65100616Smpinline bool os::allocate_stack_guard_pages() {
66100616Smp  assert(uses_stack_guard_pages(), "sanity check");
67100616Smp  int r = thr_main() ;
68100616Smp  guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
69100616Smp  return r;
70100616Smp}
71100616Smp
72100616Smp
73195609Smp// On Solaris, reservations are made on a page by page basis, nothing to do.
74100616Smpinline void os::pd_split_reserved_memory(char *base, size_t size,
75195609Smp                                      size_t split, bool realloc) {
76100616Smp}
77195609Smp
78100616Smp
79100616Smp// Bang the shadow pages if they need to be touched to be mapped.
80100616Smpinline void os::bang_stack_shadow_pages() {
81100616Smp}
82100616Smpinline void os::dll_unload(void *lib) { ::dlclose(lib); }
83100616Smp
84100616Smpinline DIR* os::opendir(const char* dirname) {
85100616Smp  assert(dirname != NULL, "just checking");
86100616Smp  return ::opendir(dirname);
87100616Smp}
88100616Smp
89100616Smpinline int os::readdir_buf_size(const char *path) {
90100616Smp  int size = pathconf(path, _PC_NAME_MAX);
91100616Smp  return (size < 0 ? MAXPATHLEN : size) + sizeof(dirent) + 1;
92100616Smp}
9383098Smp
9483098Smpinline struct dirent* os::readdir(DIR* dirp, dirent* dbuf) {
95100616Smp  assert(dirp != NULL, "just checking");
9683098Smp#if defined(_LP64) || defined(_GNU_SOURCE)
97100616Smp  dirent* p;
98100616Smp  int status;
99100616Smp
100100616Smp  if((status = ::readdir_r(dirp, dbuf, &p)) != 0) {
101100616Smp    errno = status;
102100616Smp    return NULL;
103100616Smp  } else
104100616Smp    return p;
105195609Smp#else  // defined(_LP64) || defined(_GNU_SOURCE)
106100616Smp  return ::readdir_r(dirp, dbuf);
107195609Smp#endif // defined(_LP64) || defined(_GNU_SOURCE)
108195609Smp}
109195609Smp
110195609Smpinline int os::closedir(DIR *dirp) {
111195609Smp  assert(dirp != NULL, "argument is NULL");
112195609Smp  return ::closedir(dirp);
113195609Smp}
114195609Smp
115195609Smp//////////////////////////////////////////////////////////////////////////////
116195609Smp////////////////////////////////////////////////////////////////////////////////
117100616Smp
118100616Smp// macros for interruptible io and system calls and system call restarting
119100616Smp
120195609Smp#define _INTERRUPTIBLE(_setup, _cmd, _result, _thread, _clear, _before, _after, _int_enable) \
121100616Smpdo { \
122100616Smp  _setup; \
123100616Smp  _before; \
124100616Smp  OSThread* _osthread = _thread->osthread(); \
125100616Smp  if (_int_enable && _thread->has_last_Java_frame()) { \
126100616Smp    /* this is java interruptible io stuff */ \
127100616Smp    if (os::is_interrupted(_thread, _clear))  { \
128100616Smp      os::Solaris::bump_interrupted_before_count(); \
129100616Smp      _result = OS_INTRPT; \
130195609Smp    } else { \
131100616Smp      /* _cmd always expands to an assignment to _result */ \
13269408Sache      if ((_cmd) < 0 && errno == EINTR  \
133100616Smp       && os::is_interrupted(_thread, _clear)) { \
13469408Sache        os::Solaris::bump_interrupted_during_count(); \
13569408Sache        _result = OS_INTRPT; \
13669408Sache      } \
13769408Sache    } \
13869408Sache  } else { \
13969408Sache    /* this is normal blocking io stuff */ \
140100616Smp    _cmd; \
14169408Sache  } \
14269408Sache  _after; \
14369408Sache} while(false)
14469408Sache
14569408Sache// Interruptible io support + restarting of interrupted system calls
146100616Smp
147100616Smp#ifndef ASSERT
148100616Smp
149100616Smp#define INTERRUPTIBLE(_cmd, _result, _clear) do { \
150100616Smp  _INTERRUPTIBLE( JavaThread* _thread = (JavaThread*)ThreadLocalStorage::thread(),_result = _cmd, _result, _thread, _clear, , , UseVMInterruptibleIO); \
151100616Smp} while((_result == OS_ERR) && (errno == EINTR))
152100616Smp
153100616Smp#else
154100616Smp
155100616Smp// This adds an assertion that it is only called from thread_in_native
156100616Smp// The call overhead is skipped for performance in product mode
157100616Smp#define INTERRUPTIBLE(_cmd, _result, _clear) do { \
158100616Smp  _INTERRUPTIBLE(JavaThread* _thread = os::Solaris::setup_interruptible_native(), _result = _cmd, _result, _thread, _clear, , os::Solaris::cleanup_interruptible_native(_thread), UseVMInterruptibleIO ); \
159100616Smp} while((_result == OS_ERR) && (errno == EINTR))
160100616Smp
161100616Smp#endif
162100616Smp
163100616Smp// Used for calls from _thread_in_vm, not from _thread_in_native
164100616Smp#define INTERRUPTIBLE_VM(_cmd, _result, _clear) do { \
165195609Smp  _INTERRUPTIBLE(JavaThread* _thread = os::Solaris::setup_interruptible(), _result = _cmd, _result, _thread, _clear, , os::Solaris::cleanup_interruptible(_thread), UseVMInterruptibleIO ); \
166100616Smp} while((_result == OS_ERR) && (errno == EINTR))
167100616Smp
168100616Smp/* Use NORESTART when the system call cannot return EINTR, when something other
169100616Smp   than a system call is being invoked, or when the caller must do EINTR
170100616Smp   handling. */
171100616Smp
172100616Smp#ifndef ASSERT
173100616Smp
174195609Smp#define INTERRUPTIBLE_NORESTART(_cmd, _result, _clear) \
175100616Smp  _INTERRUPTIBLE( JavaThread* _thread = (JavaThread*)ThreadLocalStorage::thread(),_result = _cmd, _result, _thread, _clear, , , UseVMInterruptibleIO)
176100616Smp
177100616Smp#else
178100616Smp
179100616Smp// This adds an assertion that it is only called from thread_in_native
180100616Smp// The call overhead is skipped for performance in product mode
181100616Smp#define INTERRUPTIBLE_NORESTART(_cmd, _result, _clear) \
182100616Smp  _INTERRUPTIBLE(JavaThread* _thread = os::Solaris::setup_interruptible_native(), _result = _cmd, _result, _thread, _clear, , os::Solaris::cleanup_interruptible_native(_thread), UseVMInterruptibleIO )
183100616Smp
184100616Smp#endif
185100616Smp
186100616Smp// Don't attend to UseVMInterruptibleIO. Always allow interruption.
187100616Smp// Also assumes that it is called from the _thread_blocked state.
188195609Smp// Used by os_sleep().
189195609Smp
190195609Smp#define INTERRUPTIBLE_NORESTART_VM_ALWAYS(_cmd, _result, _thread, _clear) \
191195609Smp  _INTERRUPTIBLE(os::Solaris::setup_interruptible_already_blocked(_thread), _result = _cmd, _result, _thread, _clear, , , true )
192195609Smp
193195609Smp#define INTERRUPTIBLE_RETURN_INT(_cmd, _clear) do { \
194195609Smp  int _result; \
195195609Smp  do { \
196195609Smp    INTERRUPTIBLE(_cmd, _result, _clear); \
197195609Smp  } while((_result == OS_ERR) && (errno == EINTR)); \
198195609Smp  return _result; \
199195609Smp} while(false)
200100616Smp
201100616Smp#define INTERRUPTIBLE_RETURN_INT_VM(_cmd, _clear) do { \
202100616Smp  int _result; \
203100616Smp  do { \
204195609Smp    INTERRUPTIBLE_VM(_cmd, _result, _clear); \
205100616Smp  } while((_result == OS_ERR) && (errno == EINTR)); \
206195609Smp  return _result; \
207195609Smp} while(false)
208195609Smp
209195609Smp#define INTERRUPTIBLE_RETURN_INT_NORESTART(_cmd, _clear) do { \
210195609Smp  int _result; \
211195609Smp  INTERRUPTIBLE_NORESTART(_cmd, _result, _clear); \
212195609Smp  return _result; \
213195609Smp} while(false)
214195609Smp
215195609Smp/* Use the RESTARTABLE macros when interruptible io is not needed */
216195609Smp
217195609Smp#define RESTARTABLE(_cmd, _result) do { \
218195609Smp  do { \
219195609Smp    _result = _cmd; \
220195609Smp  } while((_result == OS_ERR) && (errno == EINTR)); \
22169408Sache} while(false)
222195609Smp
223195609Smp#define RESTARTABLE_RETURN_INT(_cmd) do { \
22469408Sache  int _result; \
225195609Smp  RESTARTABLE(_cmd, _result); \
226195609Smp  return _result; \
227195609Smp} while(false)
228195609Smp
229195609Smpinline bool os::numa_has_static_binding()   { return false; }
230195609Smpinline bool os::numa_has_group_homing()     { return true;  }
231195609Smp
232195609Smpinline int    os::socket(int domain, int type, int protocol) {
233195609Smp  return ::socket(domain, type, protocol);
234195609Smp}
235195609Smp
236195609Smpinline int    os::listen(int fd, int count) {
237195609Smp  if (fd < 0) return OS_ERR;
238195609Smp
239195609Smp  return ::listen(fd, count);
240195609Smp}
241195609Smp
242195609Smpinline int os::socket_shutdown(int fd, int howto){
243195609Smp  return ::shutdown(fd, howto);
244195609Smp}
245195609Smp
246195609Smpinline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len){
247195609Smp  return ::getsockname(fd, him, len);
248195609Smp}
249195609Smp
250195609Smpinline int os::get_host_name(char* name, int namelen){
251195609Smp  return ::gethostname(name, namelen);
252195609Smp}
253195609Smp
254195609Smpinline struct hostent* os::get_host_by_name(char* name) {
255195609Smp  return ::gethostbyname(name);
256195609Smp}
257195609Smp
258195609Smpinline int os::get_sock_opt(int fd, int level, int optname,
259195609Smp                            char* optval, socklen_t* optlen) {
260195609Smp  return ::getsockopt(fd, level, optname, optval, optlen);
261195609Smp}
262195609Smp
263195609Smpinline int os::set_sock_opt(int fd, int level, int optname,
264195609Smp                            const char *optval, socklen_t optlen) {
265195609Smp  return ::setsockopt(fd, level, optname, optval, optlen);
266195609Smp}
267195609Smp#endif // OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP
26869408Sache