annotate src/os/solaris/vm/os_solaris.cpp @ 4582:b24386206122

Made all vm builds go into subdirectories, even product builds to simplify building the various types of VMs (server, client and graal). Made HotSpot build jobs use the number of CPUs on the host machine.
author Doug Simon <doug.simon@oracle.com>
date Mon, 13 Feb 2012 23:13:37 +0100
parents 36b057451829
children e7dead7e90af 11c26bfcf8c7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2100
b1a2afa37ec4 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 2097
diff changeset
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1490
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1490
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1490
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
25 // no precompiled headers
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
26 #include "classfile/classLoader.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
27 #include "classfile/systemDictionary.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
28 #include "classfile/vmSymbols.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
29 #include "code/icBuffer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
30 #include "code/vtableStubs.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
31 #include "compiler/compileBroker.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
32 #include "interpreter/interpreter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
33 #include "jvm_solaris.h"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
34 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
35 #include "memory/filemap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
36 #include "mutex_solaris.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
37 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
38 #include "os_share_solaris.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
39 #include "prims/jniFastGetField.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
40 #include "prims/jvm.h"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
41 #include "prims/jvm_misc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
42 #include "runtime/arguments.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
43 #include "runtime/extendedPC.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
44 #include "runtime/globals.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
45 #include "runtime/interfaceSupport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
46 #include "runtime/java.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
47 #include "runtime/javaCalls.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
48 #include "runtime/mutexLocker.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
49 #include "runtime/objectMonitor.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
50 #include "runtime/osThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
51 #include "runtime/perfMemory.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
52 #include "runtime/sharedRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
53 #include "runtime/statSampler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
54 #include "runtime/stubRoutines.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
55 #include "runtime/threadCritical.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
56 #include "runtime/timer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
57 #include "services/attachListener.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
58 #include "services/runtimeService.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
59 #include "thread_solaris.inline.hpp"
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
60 #include "utilities/decoder.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
61 #include "utilities/defaultStream.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
62 #include "utilities/events.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
63 #include "utilities/growableArray.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
64 #include "utilities/vmError.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
65 #ifdef TARGET_ARCH_x86
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
66 # include "assembler_x86.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
67 # include "nativeInst_x86.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
68 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
69 #ifdef TARGET_ARCH_sparc
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
70 # include "assembler_sparc.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
71 # include "nativeInst_sparc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
72 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
73 #ifdef COMPILER1
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
74 #include "c1/c1_Runtime1.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
75 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
76 #ifdef COMPILER2
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
77 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
78 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // put OS-includes here
a61af66fc99e Initial load
duke
parents:
diff changeset
81 # include <dlfcn.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
82 # include <errno.h>
2068
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
83 # include <exception>
0
a61af66fc99e Initial load
duke
parents:
diff changeset
84 # include <link.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
85 # include <poll.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
86 # include <pthread.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
87 # include <pwd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
88 # include <schedctl.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
89 # include <setjmp.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
90 # include <signal.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
91 # include <stdio.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
92 # include <alloca.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
93 # include <sys/filio.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
94 # include <sys/ipc.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
95 # include <sys/lwp.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
96 # include <sys/machelf.h> // for elf Sym structure used by dladdr1
a61af66fc99e Initial load
duke
parents:
diff changeset
97 # include <sys/mman.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
98 # include <sys/processor.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
99 # include <sys/procset.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
100 # include <sys/pset.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
101 # include <sys/resource.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
102 # include <sys/shm.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
103 # include <sys/socket.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
104 # include <sys/stat.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
105 # include <sys/systeminfo.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
106 # include <sys/time.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
107 # include <sys/times.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
108 # include <sys/types.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
109 # include <sys/wait.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
110 # include <sys/utsname.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
111 # include <thread.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
112 # include <unistd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
113 # include <sys/priocntl.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
114 # include <sys/rtpriocntl.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
115 # include <sys/tspriocntl.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
116 # include <sys/iapriocntl.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
117 # include <sys/loadavg.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
118 # include <string.h>
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
119 # include <stdio.h>
0
a61af66fc99e Initial load
duke
parents:
diff changeset
120
a61af66fc99e Initial load
duke
parents:
diff changeset
121 # define _STRUCTURED_PROC 1 // this gets us the new structured proc interfaces of 5.6 & later
a61af66fc99e Initial load
duke
parents:
diff changeset
122 # include <sys/procfs.h> // see comment in <sys/procfs.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
123
a61af66fc99e Initial load
duke
parents:
diff changeset
124 #define MAX_PATH (2 * K)
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // for timer info max values which include all bits
a61af66fc99e Initial load
duke
parents:
diff changeset
127 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 #ifdef _GNU_SOURCE
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // See bug #6514594
a61af66fc99e Initial load
duke
parents:
diff changeset
131 extern "C" int madvise(caddr_t, size_t, int);
a61af66fc99e Initial load
duke
parents:
diff changeset
132 extern "C" int memcntl(caddr_t addr, size_t len, int cmd, caddr_t arg,
a61af66fc99e Initial load
duke
parents:
diff changeset
133 int attr, int mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
134 #endif //_GNU_SOURCE
a61af66fc99e Initial load
duke
parents:
diff changeset
135
a61af66fc99e Initial load
duke
parents:
diff changeset
136 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
137 MPSS Changes Start.
a61af66fc99e Initial load
duke
parents:
diff changeset
138 The JVM binary needs to be built and run on pre-Solaris 9
a61af66fc99e Initial load
duke
parents:
diff changeset
139 systems, but the constants needed by MPSS are only in Solaris 9
a61af66fc99e Initial load
duke
parents:
diff changeset
140 header files. They are textually replicated here to allow
a61af66fc99e Initial load
duke
parents:
diff changeset
141 building on earlier systems. Once building on Solaris 8 is
a61af66fc99e Initial load
duke
parents:
diff changeset
142 no longer a requirement, these #defines can be replaced by ordinary
a61af66fc99e Initial load
duke
parents:
diff changeset
143 system .h inclusion.
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 In earlier versions of the JDK and Solaris, we used ISM for large pages.
a61af66fc99e Initial load
duke
parents:
diff changeset
146 But ISM requires shared memory to achieve this and thus has many caveats.
a61af66fc99e Initial load
duke
parents:
diff changeset
147 MPSS is a fully transparent and is a cleaner way to get large pages.
a61af66fc99e Initial load
duke
parents:
diff changeset
148 Although we still require keeping ISM for backward compatiblitiy as well as
a61af66fc99e Initial load
duke
parents:
diff changeset
149 giving the opportunity to use large pages on older systems it is
a61af66fc99e Initial load
duke
parents:
diff changeset
150 recommended that MPSS be used for Solaris 9 and above.
a61af66fc99e Initial load
duke
parents:
diff changeset
151
a61af66fc99e Initial load
duke
parents:
diff changeset
152 */
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154 #ifndef MC_HAT_ADVISE
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 struct memcntl_mha {
a61af66fc99e Initial load
duke
parents:
diff changeset
157 uint_t mha_cmd; /* command(s) */
a61af66fc99e Initial load
duke
parents:
diff changeset
158 uint_t mha_flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
159 size_t mha_pagesize;
a61af66fc99e Initial load
duke
parents:
diff changeset
160 };
a61af66fc99e Initial load
duke
parents:
diff changeset
161 #define MC_HAT_ADVISE 7 /* advise hat map size */
a61af66fc99e Initial load
duke
parents:
diff changeset
162 #define MHA_MAPSIZE_VA 0x1 /* set preferred page size */
a61af66fc99e Initial load
duke
parents:
diff changeset
163 #define MAP_ALIGN 0x200 /* addr specifies alignment */
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // MPSS Changes End.
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // Here are some liblgrp types from sys/lgrp_user.h to be able to
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // compile on older systems without this header file.
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 #ifndef MADV_ACCESS_LWP
a61af66fc99e Initial load
duke
parents:
diff changeset
173 # define MADV_ACCESS_LWP 7 /* next LWP to access heavily */
a61af66fc99e Initial load
duke
parents:
diff changeset
174 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
175 #ifndef MADV_ACCESS_MANY
a61af66fc99e Initial load
duke
parents:
diff changeset
176 # define MADV_ACCESS_MANY 8 /* many processes to access heavily */
a61af66fc99e Initial load
duke
parents:
diff changeset
177 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
178
144
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
179 #ifndef LGRP_RSRC_CPU
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
180 # define LGRP_RSRC_CPU 0 /* CPU resources */
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
181 #endif
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
182 #ifndef LGRP_RSRC_MEM
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
183 # define LGRP_RSRC_MEM 1 /* memory resources */
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
184 #endif
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
185
0
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // Some more macros from sys/mman.h that are not present in Solaris 8.
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188 #ifndef MAX_MEMINFO_CNT
a61af66fc99e Initial load
duke
parents:
diff changeset
189 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
190 * info_req request type definitions for meminfo
a61af66fc99e Initial load
duke
parents:
diff changeset
191 * request types starting with MEMINFO_V are used for Virtual addresses
a61af66fc99e Initial load
duke
parents:
diff changeset
192 * and should not be mixed with MEMINFO_PLGRP which is targeted for Physical
a61af66fc99e Initial load
duke
parents:
diff changeset
193 * addresses
a61af66fc99e Initial load
duke
parents:
diff changeset
194 */
a61af66fc99e Initial load
duke
parents:
diff changeset
195 # define MEMINFO_SHIFT 16
a61af66fc99e Initial load
duke
parents:
diff changeset
196 # define MEMINFO_MASK (0xFF << MEMINFO_SHIFT)
a61af66fc99e Initial load
duke
parents:
diff changeset
197 # define MEMINFO_VPHYSICAL (0x01 << MEMINFO_SHIFT) /* get physical addr */
a61af66fc99e Initial load
duke
parents:
diff changeset
198 # define MEMINFO_VLGRP (0x02 << MEMINFO_SHIFT) /* get lgroup */
a61af66fc99e Initial load
duke
parents:
diff changeset
199 # define MEMINFO_VPAGESIZE (0x03 << MEMINFO_SHIFT) /* size of phys page */
a61af66fc99e Initial load
duke
parents:
diff changeset
200 # define MEMINFO_VREPLCNT (0x04 << MEMINFO_SHIFT) /* no. of replica */
a61af66fc99e Initial load
duke
parents:
diff changeset
201 # define MEMINFO_VREPL (0x05 << MEMINFO_SHIFT) /* physical replica */
a61af66fc99e Initial load
duke
parents:
diff changeset
202 # define MEMINFO_VREPL_LGRP (0x06 << MEMINFO_SHIFT) /* lgrp of replica */
a61af66fc99e Initial load
duke
parents:
diff changeset
203 # define MEMINFO_PLGRP (0x07 << MEMINFO_SHIFT) /* lgroup for paddr */
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 /* maximum number of addresses meminfo() can process at a time */
a61af66fc99e Initial load
duke
parents:
diff changeset
206 # define MAX_MEMINFO_CNT 256
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 /* maximum number of request types */
a61af66fc99e Initial load
duke
parents:
diff changeset
209 # define MAX_MEMINFO_REQ 31
a61af66fc99e Initial load
duke
parents:
diff changeset
210 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 // see thr_setprio(3T) for the basis of these numbers
a61af66fc99e Initial load
duke
parents:
diff changeset
213 #define MinimumPriority 0
a61af66fc99e Initial load
duke
parents:
diff changeset
214 #define NormalPriority 64
a61af66fc99e Initial load
duke
parents:
diff changeset
215 #define MaximumPriority 127
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // Values for ThreadPriorityPolicy == 1
a61af66fc99e Initial load
duke
parents:
diff changeset
218 int prio_policy1[MaxPriority+1] = { -99999, 0, 16, 32, 48, 64,
a61af66fc99e Initial load
duke
parents:
diff changeset
219 80, 96, 112, 124, 127 };
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221 // System parameters used internally
a61af66fc99e Initial load
duke
parents:
diff changeset
222 static clock_t clock_tics_per_sec = 100;
a61af66fc99e Initial load
duke
parents:
diff changeset
223
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
224 // Track if we have called enable_extended_FILE_stdio (on Solaris 10u4+)
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
225 static bool enabled_extended_FILE_stdio = false;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
226
0
a61af66fc99e Initial load
duke
parents:
diff changeset
227 // For diagnostics to print a message once. see run_periodic_checks
a61af66fc99e Initial load
duke
parents:
diff changeset
228 static bool check_addr0_done = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
229 static sigset_t check_signal_done;
a61af66fc99e Initial load
duke
parents:
diff changeset
230 static bool check_signals = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232 address os::Solaris::handler_start; // start pc of thr_sighndlrinfo
a61af66fc99e Initial load
duke
parents:
diff changeset
233 address os::Solaris::handler_end; // end pc of thr_sighndlrinfo
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 address os::Solaris::_main_stack_base = NULL; // 4352906 workaround
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // "default" initializers for missing libc APIs
a61af66fc99e Initial load
duke
parents:
diff changeset
239 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 static int lwp_mutex_init(mutex_t *mx, int scope, void *arg) { memset(mx, 0, sizeof(mutex_t)); return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
241 static int lwp_mutex_destroy(mutex_t *mx) { return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243 static int lwp_cond_init(cond_t *cv, int scope, void *arg){ memset(cv, 0, sizeof(cond_t)); return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
244 static int lwp_cond_destroy(cond_t *cv) { return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // "default" initializers for pthread-based synchronization
a61af66fc99e Initial load
duke
parents:
diff changeset
248 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 static int pthread_mutex_default_init(mutex_t *mx, int scope, void *arg) { memset(mx, 0, sizeof(mutex_t)); return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
250 static int pthread_cond_default_init(cond_t *cv, int scope, void *arg){ memset(cv, 0, sizeof(cond_t)); return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // Thread Local Storage
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // This is common to all Solaris platforms so it is defined here,
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // in this common file.
a61af66fc99e Initial load
duke
parents:
diff changeset
256 // The declarations are in the os_cpu threadLS*.hpp files.
a61af66fc99e Initial load
duke
parents:
diff changeset
257 //
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // Static member initialization for TLS
a61af66fc99e Initial load
duke
parents:
diff changeset
259 Thread* ThreadLocalStorage::_get_thread_cache[ThreadLocalStorage::_pd_cache_size] = {NULL};
a61af66fc99e Initial load
duke
parents:
diff changeset
260
a61af66fc99e Initial load
duke
parents:
diff changeset
261 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
262 #define _PCT(n,d) ((100.0*(double)(n))/(double)(d))
a61af66fc99e Initial load
duke
parents:
diff changeset
263
a61af66fc99e Initial load
duke
parents:
diff changeset
264 int ThreadLocalStorage::_tcacheHit = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
265 int ThreadLocalStorage::_tcacheMiss = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
266
a61af66fc99e Initial load
duke
parents:
diff changeset
267 void ThreadLocalStorage::print_statistics() {
a61af66fc99e Initial load
duke
parents:
diff changeset
268 int total = _tcacheMiss+_tcacheHit;
a61af66fc99e Initial load
duke
parents:
diff changeset
269 tty->print_cr("Thread cache hits %d misses %d total %d percent %f\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
270 _tcacheHit, _tcacheMiss, total, _PCT(_tcacheHit, total));
a61af66fc99e Initial load
duke
parents:
diff changeset
271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
272 #undef _PCT
a61af66fc99e Initial load
duke
parents:
diff changeset
273 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
274
a61af66fc99e Initial load
duke
parents:
diff changeset
275 Thread* ThreadLocalStorage::get_thread_via_cache_slowly(uintptr_t raw_id,
a61af66fc99e Initial load
duke
parents:
diff changeset
276 int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
277 Thread *thread = get_thread_slow();
a61af66fc99e Initial load
duke
parents:
diff changeset
278 if (thread != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
279 address sp = os::current_stack_pointer();
a61af66fc99e Initial load
duke
parents:
diff changeset
280 guarantee(thread->_stack_base == NULL ||
a61af66fc99e Initial load
duke
parents:
diff changeset
281 (sp <= thread->_stack_base &&
a61af66fc99e Initial load
duke
parents:
diff changeset
282 sp >= thread->_stack_base - thread->_stack_size) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
283 is_error_reported(),
a61af66fc99e Initial load
duke
parents:
diff changeset
284 "sp must be inside of selected thread stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
285
2100
b1a2afa37ec4 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 2097
diff changeset
286 thread->set_self_raw_id(raw_id); // mark for quick retrieval
0
a61af66fc99e Initial load
duke
parents:
diff changeset
287 _get_thread_cache[ index ] = thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
289 return thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
290 }
a61af66fc99e Initial load
duke
parents:
diff changeset
291
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 static const double all_zero[ sizeof(Thread) / sizeof(double) + 1 ] = {0};
a61af66fc99e Initial load
duke
parents:
diff changeset
294 #define NO_CACHED_THREAD ((Thread*)all_zero)
a61af66fc99e Initial load
duke
parents:
diff changeset
295
a61af66fc99e Initial load
duke
parents:
diff changeset
296 void ThreadLocalStorage::pd_set_thread(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // Store the new value before updating the cache to prevent a race
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // between get_thread_via_cache_slowly() and this store operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
300 os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
301
a61af66fc99e Initial load
duke
parents:
diff changeset
302 // Update thread cache with new thread if setting on thread create,
a61af66fc99e Initial load
duke
parents:
diff changeset
303 // or NO_CACHED_THREAD (zeroed) thread if resetting thread on exit.
a61af66fc99e Initial load
duke
parents:
diff changeset
304 uintptr_t raw = pd_raw_thread_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
305 int ix = pd_cache_index(raw);
a61af66fc99e Initial load
duke
parents:
diff changeset
306 _get_thread_cache[ix] = thread == NULL ? NO_CACHED_THREAD : thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
308
a61af66fc99e Initial load
duke
parents:
diff changeset
309 void ThreadLocalStorage::pd_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
310 for (int i = 0; i < _pd_cache_size; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
311 _get_thread_cache[i] = NO_CACHED_THREAD;
a61af66fc99e Initial load
duke
parents:
diff changeset
312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
314
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // Invalidate all the caches (happens to be the same as pd_init).
a61af66fc99e Initial load
duke
parents:
diff changeset
316 void ThreadLocalStorage::pd_invalidate_all() { pd_init(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
317
a61af66fc99e Initial load
duke
parents:
diff changeset
318 #undef NO_CACHED_THREAD
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320 // END Thread Local Storage
a61af66fc99e Initial load
duke
parents:
diff changeset
321
a61af66fc99e Initial load
duke
parents:
diff changeset
322 static inline size_t adjust_stack_size(address base, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
323 if ((ssize_t)size < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // 4759953: Compensate for ridiculous stack size.
a61af66fc99e Initial load
duke
parents:
diff changeset
325 size = max_intx;
a61af66fc99e Initial load
duke
parents:
diff changeset
326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
327 if (size > (size_t)base) {
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // 4812466: Make sure size doesn't allow the stack to wrap the address space.
a61af66fc99e Initial load
duke
parents:
diff changeset
329 size = (size_t)base;
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
333
a61af66fc99e Initial load
duke
parents:
diff changeset
334 static inline stack_t get_stack_info() {
a61af66fc99e Initial load
duke
parents:
diff changeset
335 stack_t st;
a61af66fc99e Initial load
duke
parents:
diff changeset
336 int retval = thr_stksegment(&st);
a61af66fc99e Initial load
duke
parents:
diff changeset
337 st.ss_size = adjust_stack_size((address)st.ss_sp, st.ss_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
338 assert(retval == 0, "incorrect return value from thr_stksegment");
a61af66fc99e Initial load
duke
parents:
diff changeset
339 assert((address)&st < (address)st.ss_sp, "Invalid stack base returned");
a61af66fc99e Initial load
duke
parents:
diff changeset
340 assert((address)&st > (address)st.ss_sp-st.ss_size, "Invalid stack size returned");
a61af66fc99e Initial load
duke
parents:
diff changeset
341 return st;
a61af66fc99e Initial load
duke
parents:
diff changeset
342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344 address os::current_stack_base() {
a61af66fc99e Initial load
duke
parents:
diff changeset
345 int r = thr_main() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
346 guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
347 bool is_primordial_thread = r;
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // Workaround 4352906, avoid calls to thr_stksegment by
a61af66fc99e Initial load
duke
parents:
diff changeset
350 // thr_main after the first one (it looks like we trash
a61af66fc99e Initial load
duke
parents:
diff changeset
351 // some data, causing the value for ss_sp to be incorrect).
a61af66fc99e Initial load
duke
parents:
diff changeset
352 if (!is_primordial_thread || os::Solaris::_main_stack_base == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
353 stack_t st = get_stack_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
354 if (is_primordial_thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // cache initial value of stack base
a61af66fc99e Initial load
duke
parents:
diff changeset
356 os::Solaris::_main_stack_base = (address)st.ss_sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
357 }
a61af66fc99e Initial load
duke
parents:
diff changeset
358 return (address)st.ss_sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
359 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 guarantee(os::Solaris::_main_stack_base != NULL, "Attempt to use null cached stack base");
a61af66fc99e Initial load
duke
parents:
diff changeset
361 return os::Solaris::_main_stack_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
364
a61af66fc99e Initial load
duke
parents:
diff changeset
365 size_t os::current_stack_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
366 size_t size;
a61af66fc99e Initial load
duke
parents:
diff changeset
367
a61af66fc99e Initial load
duke
parents:
diff changeset
368 int r = thr_main() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
369 guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
370 if(!r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
371 size = get_stack_info().ss_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
372 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
373 struct rlimit limits;
a61af66fc99e Initial load
duke
parents:
diff changeset
374 getrlimit(RLIMIT_STACK, &limits);
a61af66fc99e Initial load
duke
parents:
diff changeset
375 size = adjust_stack_size(os::Solaris::_main_stack_base, (size_t)limits.rlim_cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
377 // base may not be page aligned
a61af66fc99e Initial load
duke
parents:
diff changeset
378 address base = current_stack_base();
a61af66fc99e Initial load
duke
parents:
diff changeset
379 address bottom = (address)align_size_up((intptr_t)(base - size), os::vm_page_size());;
a61af66fc99e Initial load
duke
parents:
diff changeset
380 return (size_t)(base - bottom);
a61af66fc99e Initial load
duke
parents:
diff changeset
381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
382
548
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 499
diff changeset
383 struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 499
diff changeset
384 return localtime_r(clock, res);
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 499
diff changeset
385 }
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 499
diff changeset
386
0
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // interruptible infrastructure
a61af66fc99e Initial load
duke
parents:
diff changeset
388
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // setup_interruptible saves the thread state before going into an
a61af66fc99e Initial load
duke
parents:
diff changeset
390 // interruptible system call.
a61af66fc99e Initial load
duke
parents:
diff changeset
391 // The saved state is used to restore the thread to
a61af66fc99e Initial load
duke
parents:
diff changeset
392 // its former state whether or not an interrupt is received.
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // Used by classloader os::read
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
394 // os::restartable_read calls skip this layer and stay in _thread_in_native
0
a61af66fc99e Initial load
duke
parents:
diff changeset
395
a61af66fc99e Initial load
duke
parents:
diff changeset
396 void os::Solaris::setup_interruptible(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 JavaThreadState thread_state = thread->thread_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 assert(thread_state != _thread_blocked, "Coming from the wrong thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
401 assert(thread_state != _thread_in_native, "Native threads skip setup_interruptible");
a61af66fc99e Initial load
duke
parents:
diff changeset
402 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
403 osthread->set_saved_interrupt_thread_state(thread_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
404 thread->frame_anchor()->make_walkable(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
405 ThreadStateTransition::transition(thread, thread_state, _thread_blocked);
a61af66fc99e Initial load
duke
parents:
diff changeset
406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
407
a61af66fc99e Initial load
duke
parents:
diff changeset
408 // Version of setup_interruptible() for threads that are already in
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // _thread_blocked. Used by os_sleep().
a61af66fc99e Initial load
duke
parents:
diff changeset
410 void os::Solaris::setup_interruptible_already_blocked(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
411 thread->frame_anchor()->make_walkable(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
413
a61af66fc99e Initial load
duke
parents:
diff changeset
414 JavaThread* os::Solaris::setup_interruptible() {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
416 setup_interruptible(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
417 return thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
419
a61af66fc99e Initial load
duke
parents:
diff changeset
420 void os::Solaris::try_enable_extended_io() {
a61af66fc99e Initial load
duke
parents:
diff changeset
421 typedef int (*enable_extended_FILE_stdio_t)(int, int);
a61af66fc99e Initial load
duke
parents:
diff changeset
422
a61af66fc99e Initial load
duke
parents:
diff changeset
423 if (!UseExtendedFileIO) {
a61af66fc99e Initial load
duke
parents:
diff changeset
424 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
426
a61af66fc99e Initial load
duke
parents:
diff changeset
427 enable_extended_FILE_stdio_t enabler =
a61af66fc99e Initial load
duke
parents:
diff changeset
428 (enable_extended_FILE_stdio_t) dlsym(RTLD_DEFAULT,
a61af66fc99e Initial load
duke
parents:
diff changeset
429 "enable_extended_FILE_stdio");
a61af66fc99e Initial load
duke
parents:
diff changeset
430 if (enabler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
431 enabler(-1, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
434
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
437
a61af66fc99e Initial load
duke
parents:
diff changeset
438 JavaThread* os::Solaris::setup_interruptible_native() {
a61af66fc99e Initial load
duke
parents:
diff changeset
439 JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
440 JavaThreadState thread_state = thread->thread_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
441 assert(thread_state == _thread_in_native, "Assumed thread_in_native");
a61af66fc99e Initial load
duke
parents:
diff changeset
442 return thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
444
a61af66fc99e Initial load
duke
parents:
diff changeset
445 void os::Solaris::cleanup_interruptible_native(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
446 JavaThreadState thread_state = thread->thread_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
447 assert(thread_state == _thread_in_native, "Assumed thread_in_native");
a61af66fc99e Initial load
duke
parents:
diff changeset
448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
449 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // cleanup_interruptible reverses the effects of setup_interruptible
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // setup_interruptible_already_blocked() does not need any cleanup.
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 void os::Solaris::cleanup_interruptible(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
455 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
456
a61af66fc99e Initial load
duke
parents:
diff changeset
457 ThreadStateTransition::transition(thread, _thread_blocked, osthread->saved_interrupt_thread_state());
a61af66fc99e Initial load
duke
parents:
diff changeset
458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
459
a61af66fc99e Initial load
duke
parents:
diff changeset
460 // I/O interruption related counters called in _INTERRUPTIBLE
a61af66fc99e Initial load
duke
parents:
diff changeset
461
a61af66fc99e Initial load
duke
parents:
diff changeset
462 void os::Solaris::bump_interrupted_before_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
463 RuntimeService::record_interrupted_before_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
464 }
a61af66fc99e Initial load
duke
parents:
diff changeset
465
a61af66fc99e Initial load
duke
parents:
diff changeset
466 void os::Solaris::bump_interrupted_during_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
467 RuntimeService::record_interrupted_during_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
468 }
a61af66fc99e Initial load
duke
parents:
diff changeset
469
a61af66fc99e Initial load
duke
parents:
diff changeset
470 static int _processors_online = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
471
a61af66fc99e Initial load
duke
parents:
diff changeset
472 jint os::Solaris::_os_thread_limit = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
473 volatile jint os::Solaris::_os_thread_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
474
a61af66fc99e Initial load
duke
parents:
diff changeset
475 julong os::available_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
476 return Solaris::available_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
478
a61af66fc99e Initial load
duke
parents:
diff changeset
479 julong os::Solaris::available_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
480 return (julong)sysconf(_SC_AVPHYS_PAGES) * os::vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
482
a61af66fc99e Initial load
duke
parents:
diff changeset
483 julong os::Solaris::_physical_memory = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
484
a61af66fc99e Initial load
duke
parents:
diff changeset
485 julong os::physical_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
486 return Solaris::physical_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
488
a61af66fc99e Initial load
duke
parents:
diff changeset
489 julong os::allocatable_physical_memory(julong size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
490 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
491 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
492 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
493 julong result = MIN2(size, (julong)3835*M);
a61af66fc99e Initial load
duke
parents:
diff changeset
494 if (!is_allocatable(result)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
495 // Memory allocations will be aligned but the alignment
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // is not known at this point. Alignments will
a61af66fc99e Initial load
duke
parents:
diff changeset
497 // be at most to LargePageSizeInBytes. Protect
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // allocations from alignments up to illegal
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // values. If at this point 2G is illegal.
a61af66fc99e Initial load
duke
parents:
diff changeset
500 julong reasonable_size = (julong)2*G - 2 * LargePageSizeInBytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
501 result = MIN2(size, reasonable_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
503 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
504 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 static hrtime_t first_hrtime = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
508 static const hrtime_t hrtime_hz = 1000*1000*1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
509 const int LOCK_BUSY = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
510 const int LOCK_FREE = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
511 const int LOCK_INVALID = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
512 static volatile hrtime_t max_hrtime = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
513 static volatile int max_hrtime_lock = LOCK_FREE; // Update counter with LSB as lock-in-progress
a61af66fc99e Initial load
duke
parents:
diff changeset
514
a61af66fc99e Initial load
duke
parents:
diff changeset
515
a61af66fc99e Initial load
duke
parents:
diff changeset
516 void os::Solaris::initialize_system_info() {
1123
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 1117
diff changeset
517 set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
518 _processors_online = sysconf (_SC_NPROCESSORS_ONLN);
a61af66fc99e Initial load
duke
parents:
diff changeset
519 _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
a61af66fc99e Initial load
duke
parents:
diff changeset
520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
521
a61af66fc99e Initial load
duke
parents:
diff changeset
522 int os::active_processor_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
523 int online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
a61af66fc99e Initial load
duke
parents:
diff changeset
524 pid_t pid = getpid();
a61af66fc99e Initial load
duke
parents:
diff changeset
525 psetid_t pset = PS_NONE;
387
fad66fdcb7fc 6673124: Runtime.availableProcessors / os::active_processor_count wrong if unused processor sets exist
xlu
parents: 356
diff changeset
526 // Are we running in a processor set or is there any processor set around?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
527 if (pset_bind(PS_QUERY, P_PID, pid, &pset) == 0) {
387
fad66fdcb7fc 6673124: Runtime.availableProcessors / os::active_processor_count wrong if unused processor sets exist
xlu
parents: 356
diff changeset
528 uint_t pset_cpus;
fad66fdcb7fc 6673124: Runtime.availableProcessors / os::active_processor_count wrong if unused processor sets exist
xlu
parents: 356
diff changeset
529 // Query the number of cpus available to us.
fad66fdcb7fc 6673124: Runtime.availableProcessors / os::active_processor_count wrong if unused processor sets exist
xlu
parents: 356
diff changeset
530 if (pset_info(pset, NULL, &pset_cpus, NULL) == 0) {
fad66fdcb7fc 6673124: Runtime.availableProcessors / os::active_processor_count wrong if unused processor sets exist
xlu
parents: 356
diff changeset
531 assert(pset_cpus > 0 && pset_cpus <= online_cpus, "sanity check");
fad66fdcb7fc 6673124: Runtime.availableProcessors / os::active_processor_count wrong if unused processor sets exist
xlu
parents: 356
diff changeset
532 _processors_online = pset_cpus;
fad66fdcb7fc 6673124: Runtime.availableProcessors / os::active_processor_count wrong if unused processor sets exist
xlu
parents: 356
diff changeset
533 return pset_cpus;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
536 // Otherwise return number of online cpus
a61af66fc99e Initial load
duke
parents:
diff changeset
537 return online_cpus;
a61af66fc99e Initial load
duke
parents:
diff changeset
538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
539
a61af66fc99e Initial load
duke
parents:
diff changeset
540 static bool find_processors_in_pset(psetid_t pset,
a61af66fc99e Initial load
duke
parents:
diff changeset
541 processorid_t** id_array,
a61af66fc99e Initial load
duke
parents:
diff changeset
542 uint_t* id_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
543 bool result = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
544 // Find the number of processors in the processor set.
a61af66fc99e Initial load
duke
parents:
diff changeset
545 if (pset_info(pset, NULL, id_length, NULL) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
546 // Make up an array to hold their ids.
a61af66fc99e Initial load
duke
parents:
diff changeset
547 *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
548 // Fill in the array with their processor ids.
a61af66fc99e Initial load
duke
parents:
diff changeset
549 if (pset_info(pset, NULL, id_length, *id_array) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
550 result = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
552 }
a61af66fc99e Initial load
duke
parents:
diff changeset
553 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
554 }
a61af66fc99e Initial load
duke
parents:
diff changeset
555
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // Callers of find_processors_online() must tolerate imprecise results --
a61af66fc99e Initial load
duke
parents:
diff changeset
557 // the system configuration can change asynchronously because of DR
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // or explicit psradm operations.
a61af66fc99e Initial load
duke
parents:
diff changeset
559 //
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // We also need to take care that the loop (below) terminates as the
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // number of processors online can change between the _SC_NPROCESSORS_ONLN
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // request and the loop that builds the list of processor ids. Unfortunately
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // there's no reliable way to determine the maximum valid processor id,
a61af66fc99e Initial load
duke
parents:
diff changeset
564 // so we use a manifest constant, MAX_PROCESSOR_ID, instead. See p_online
a61af66fc99e Initial load
duke
parents:
diff changeset
565 // man pages, which claim the processor id set is "sparse, but
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // not too sparse". MAX_PROCESSOR_ID is used to ensure that we eventually
a61af66fc99e Initial load
duke
parents:
diff changeset
567 // exit the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
568 //
a61af66fc99e Initial load
duke
parents:
diff changeset
569 // In the future we'll be able to use sysconf(_SC_CPUID_MAX), but that's
a61af66fc99e Initial load
duke
parents:
diff changeset
570 // not available on S8.0.
a61af66fc99e Initial load
duke
parents:
diff changeset
571
a61af66fc99e Initial load
duke
parents:
diff changeset
572 static bool find_processors_online(processorid_t** id_array,
a61af66fc99e Initial load
duke
parents:
diff changeset
573 uint* id_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
574 const processorid_t MAX_PROCESSOR_ID = 100000 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
575 // Find the number of processors online.
a61af66fc99e Initial load
duke
parents:
diff changeset
576 *id_length = sysconf(_SC_NPROCESSORS_ONLN);
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // Make up an array to hold their ids.
a61af66fc99e Initial load
duke
parents:
diff changeset
578 *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
579 // Processors need not be numbered consecutively.
a61af66fc99e Initial load
duke
parents:
diff changeset
580 long found = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
581 processorid_t next = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
582 while (found < *id_length && next < MAX_PROCESSOR_ID) {
a61af66fc99e Initial load
duke
parents:
diff changeset
583 processor_info_t info;
a61af66fc99e Initial load
duke
parents:
diff changeset
584 if (processor_info(next, &info) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // NB, PI_NOINTR processors are effectively online ...
a61af66fc99e Initial load
duke
parents:
diff changeset
586 if (info.pi_state == P_ONLINE || info.pi_state == P_NOINTR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
587 (*id_array)[found] = next;
a61af66fc99e Initial load
duke
parents:
diff changeset
588 found += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
589 }
a61af66fc99e Initial load
duke
parents:
diff changeset
590 }
a61af66fc99e Initial load
duke
parents:
diff changeset
591 next += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
592 }
a61af66fc99e Initial load
duke
parents:
diff changeset
593 if (found < *id_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
594 // The loop above didn't identify the expected number of processors.
a61af66fc99e Initial load
duke
parents:
diff changeset
595 // We could always retry the operation, calling sysconf(_SC_NPROCESSORS_ONLN)
a61af66fc99e Initial load
duke
parents:
diff changeset
596 // and re-running the loop, above, but there's no guarantee of progress
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // if the system configuration is in flux. Instead, we just return what
a61af66fc99e Initial load
duke
parents:
diff changeset
598 // we've got. Note that in the worst case find_processors_online() could
a61af66fc99e Initial load
duke
parents:
diff changeset
599 // return an empty set. (As a fall-back in the case of the empty set we
a61af66fc99e Initial load
duke
parents:
diff changeset
600 // could just return the ID of the current processor).
a61af66fc99e Initial load
duke
parents:
diff changeset
601 *id_length = found ;
a61af66fc99e Initial load
duke
parents:
diff changeset
602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
603
a61af66fc99e Initial load
duke
parents:
diff changeset
604 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
606
a61af66fc99e Initial load
duke
parents:
diff changeset
607 static bool assign_distribution(processorid_t* id_array,
a61af66fc99e Initial load
duke
parents:
diff changeset
608 uint id_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
609 uint* distribution,
a61af66fc99e Initial load
duke
parents:
diff changeset
610 uint distribution_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 // We assume we can assign processorid_t's to uint's.
a61af66fc99e Initial load
duke
parents:
diff changeset
612 assert(sizeof(processorid_t) == sizeof(uint),
a61af66fc99e Initial load
duke
parents:
diff changeset
613 "can't convert processorid_t to uint");
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // Quick check to see if we won't succeed.
a61af66fc99e Initial load
duke
parents:
diff changeset
615 if (id_length < distribution_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
616 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
617 }
a61af66fc99e Initial load
duke
parents:
diff changeset
618 // Assign processor ids to the distribution.
a61af66fc99e Initial load
duke
parents:
diff changeset
619 // Try to shuffle processors to distribute work across boards,
a61af66fc99e Initial load
duke
parents:
diff changeset
620 // assuming 4 processors per board.
a61af66fc99e Initial load
duke
parents:
diff changeset
621 const uint processors_per_board = ProcessDistributionStride;
a61af66fc99e Initial load
duke
parents:
diff changeset
622 // Find the maximum processor id.
a61af66fc99e Initial load
duke
parents:
diff changeset
623 processorid_t max_id = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
624 for (uint m = 0; m < id_length; m += 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
625 max_id = MAX2(max_id, id_array[m]);
a61af66fc99e Initial load
duke
parents:
diff changeset
626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
627 // The next id, to limit loops.
a61af66fc99e Initial load
duke
parents:
diff changeset
628 const processorid_t limit_id = max_id + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // Make up markers for available processors.
a61af66fc99e Initial load
duke
parents:
diff changeset
630 bool* available_id = NEW_C_HEAP_ARRAY(bool, limit_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
631 for (uint c = 0; c < limit_id; c += 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
632 available_id[c] = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
634 for (uint a = 0; a < id_length; a += 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
635 available_id[id_array[a]] = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
637 // Step by "boards", then by "slot", copying to "assigned".
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // NEEDS_CLEANUP: The assignment of processors should be stateful,
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // remembering which processors have been assigned by
a61af66fc99e Initial load
duke
parents:
diff changeset
640 // previous calls, etc., so as to distribute several
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // independent calls of this method. What we'd like is
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // It would be nice to have an API that let us ask
a61af66fc99e Initial load
duke
parents:
diff changeset
643 // how many processes are bound to a processor,
a61af66fc99e Initial load
duke
parents:
diff changeset
644 // but we don't have that, either.
a61af66fc99e Initial load
duke
parents:
diff changeset
645 // In the short term, "board" is static so that
a61af66fc99e Initial load
duke
parents:
diff changeset
646 // subsequent distributions don't all start at board 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
647 static uint board = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
648 uint assigned = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
649 // Until we've found enough processors ....
a61af66fc99e Initial load
duke
parents:
diff changeset
650 while (assigned < distribution_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // ... find the next available processor in the board.
a61af66fc99e Initial load
duke
parents:
diff changeset
652 for (uint slot = 0; slot < processors_per_board; slot += 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
653 uint try_id = board * processors_per_board + slot;
a61af66fc99e Initial load
duke
parents:
diff changeset
654 if ((try_id < limit_id) && (available_id[try_id] == true)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
655 distribution[assigned] = try_id;
a61af66fc99e Initial load
duke
parents:
diff changeset
656 available_id[try_id] = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
657 assigned += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
658 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
659 }
a61af66fc99e Initial load
duke
parents:
diff changeset
660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
661 board += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
662 if (board * processors_per_board + 0 >= limit_id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
663 board = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
666 if (available_id != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
667 FREE_C_HEAP_ARRAY(bool, available_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
668 }
a61af66fc99e Initial load
duke
parents:
diff changeset
669 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
670 }
a61af66fc99e Initial load
duke
parents:
diff changeset
671
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3956
diff changeset
672 void os::set_native_thread_name(const char *name) {
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3956
diff changeset
673 // Not yet implemented.
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3956
diff changeset
674 return;
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3956
diff changeset
675 }
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3956
diff changeset
676
0
a61af66fc99e Initial load
duke
parents:
diff changeset
677 bool os::distribute_processes(uint length, uint* distribution) {
a61af66fc99e Initial load
duke
parents:
diff changeset
678 bool result = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
679 // Find the processor id's of all the available CPUs.
a61af66fc99e Initial load
duke
parents:
diff changeset
680 processorid_t* id_array = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
681 uint id_length = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
682 // There are some races between querying information and using it,
a61af66fc99e Initial load
duke
parents:
diff changeset
683 // since processor sets can change dynamically.
a61af66fc99e Initial load
duke
parents:
diff changeset
684 psetid_t pset = PS_NONE;
a61af66fc99e Initial load
duke
parents:
diff changeset
685 // Are we running in a processor set?
a61af66fc99e Initial load
duke
parents:
diff changeset
686 if ((pset_bind(PS_QUERY, P_PID, P_MYID, &pset) == 0) && pset != PS_NONE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
687 result = find_processors_in_pset(pset, &id_array, &id_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
688 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
689 result = find_processors_online(&id_array, &id_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
690 }
a61af66fc99e Initial load
duke
parents:
diff changeset
691 if (result == true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
692 if (id_length >= length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
693 result = assign_distribution(id_array, id_length, distribution, length);
a61af66fc99e Initial load
duke
parents:
diff changeset
694 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
695 result = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
698 if (id_array != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
699 FREE_C_HEAP_ARRAY(processorid_t, id_array);
a61af66fc99e Initial load
duke
parents:
diff changeset
700 }
a61af66fc99e Initial load
duke
parents:
diff changeset
701 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
703
a61af66fc99e Initial load
duke
parents:
diff changeset
704 bool os::bind_to_processor(uint processor_id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
705 // We assume that a processorid_t can be stored in a uint.
a61af66fc99e Initial load
duke
parents:
diff changeset
706 assert(sizeof(uint) == sizeof(processorid_t),
a61af66fc99e Initial load
duke
parents:
diff changeset
707 "can't convert uint to processorid_t");
a61af66fc99e Initial load
duke
parents:
diff changeset
708 int bind_result =
a61af66fc99e Initial load
duke
parents:
diff changeset
709 processor_bind(P_LWPID, // bind LWP.
a61af66fc99e Initial load
duke
parents:
diff changeset
710 P_MYID, // bind current LWP.
a61af66fc99e Initial load
duke
parents:
diff changeset
711 (processorid_t) processor_id, // id.
a61af66fc99e Initial load
duke
parents:
diff changeset
712 NULL); // don't return old binding.
a61af66fc99e Initial load
duke
parents:
diff changeset
713 return (bind_result == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
714 }
a61af66fc99e Initial load
duke
parents:
diff changeset
715
a61af66fc99e Initial load
duke
parents:
diff changeset
716 bool os::getenv(const char* name, char* buffer, int len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
717 char* val = ::getenv( name );
a61af66fc99e Initial load
duke
parents:
diff changeset
718 if ( val == NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
719 || strlen(val) + 1 > len ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
720 if (len > 0) buffer[0] = 0; // return a null string
a61af66fc99e Initial load
duke
parents:
diff changeset
721 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
722 }
a61af66fc99e Initial load
duke
parents:
diff changeset
723 strcpy( buffer, val );
a61af66fc99e Initial load
duke
parents:
diff changeset
724 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
725 }
a61af66fc99e Initial load
duke
parents:
diff changeset
726
a61af66fc99e Initial load
duke
parents:
diff changeset
727
a61af66fc99e Initial load
duke
parents:
diff changeset
728 // Return true if user is running as root.
a61af66fc99e Initial load
duke
parents:
diff changeset
729
a61af66fc99e Initial load
duke
parents:
diff changeset
730 bool os::have_special_privileges() {
a61af66fc99e Initial load
duke
parents:
diff changeset
731 static bool init = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
732 static bool privileges = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
733 if (!init) {
a61af66fc99e Initial load
duke
parents:
diff changeset
734 privileges = (getuid() != geteuid()) || (getgid() != getegid());
a61af66fc99e Initial load
duke
parents:
diff changeset
735 init = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
736 }
a61af66fc99e Initial load
duke
parents:
diff changeset
737 return privileges;
a61af66fc99e Initial load
duke
parents:
diff changeset
738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
739
a61af66fc99e Initial load
duke
parents:
diff changeset
740
a61af66fc99e Initial load
duke
parents:
diff changeset
741 void os::init_system_properties_values() {
a61af66fc99e Initial load
duke
parents:
diff changeset
742 char arch[12];
a61af66fc99e Initial load
duke
parents:
diff changeset
743 sysinfo(SI_ARCHITECTURE, arch, sizeof(arch));
a61af66fc99e Initial load
duke
parents:
diff changeset
744
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // The next steps are taken in the product version:
a61af66fc99e Initial load
duke
parents:
diff changeset
746 //
a61af66fc99e Initial load
duke
parents:
diff changeset
747 // Obtain the JAVA_HOME value from the location of libjvm[_g].so.
a61af66fc99e Initial load
duke
parents:
diff changeset
748 // This library should be located at:
a61af66fc99e Initial load
duke
parents:
diff changeset
749 // <JAVA_HOME>/jre/lib/<arch>/{client|server}/libjvm[_g].so.
a61af66fc99e Initial load
duke
parents:
diff changeset
750 //
a61af66fc99e Initial load
duke
parents:
diff changeset
751 // If "/jre/lib/" appears at the right place in the path, then we
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // assume libjvm[_g].so is installed in a JDK and we use this path.
a61af66fc99e Initial load
duke
parents:
diff changeset
753 //
a61af66fc99e Initial load
duke
parents:
diff changeset
754 // Otherwise exit with message: "Could not create the Java virtual machine."
a61af66fc99e Initial load
duke
parents:
diff changeset
755 //
a61af66fc99e Initial load
duke
parents:
diff changeset
756 // The following extra steps are taken in the debugging version:
a61af66fc99e Initial load
duke
parents:
diff changeset
757 //
a61af66fc99e Initial load
duke
parents:
diff changeset
758 // If "/jre/lib/" does NOT appear at the right place in the path
a61af66fc99e Initial load
duke
parents:
diff changeset
759 // instead of exit check for $JAVA_HOME environment variable.
a61af66fc99e Initial load
duke
parents:
diff changeset
760 //
a61af66fc99e Initial load
duke
parents:
diff changeset
761 // If it is defined and we are able to locate $JAVA_HOME/jre/lib/<arch>,
a61af66fc99e Initial load
duke
parents:
diff changeset
762 // then we append a fake suffix "hotspot/libjvm[_g].so" to this path so
a61af66fc99e Initial load
duke
parents:
diff changeset
763 // it looks like libjvm[_g].so is installed there
a61af66fc99e Initial load
duke
parents:
diff changeset
764 // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm[_g].so.
a61af66fc99e Initial load
duke
parents:
diff changeset
765 //
a61af66fc99e Initial load
duke
parents:
diff changeset
766 // Otherwise exit.
a61af66fc99e Initial load
duke
parents:
diff changeset
767 //
a61af66fc99e Initial load
duke
parents:
diff changeset
768 // Important note: if the location of libjvm.so changes this
a61af66fc99e Initial load
duke
parents:
diff changeset
769 // code needs to be changed accordingly.
a61af66fc99e Initial load
duke
parents:
diff changeset
770
a61af66fc99e Initial load
duke
parents:
diff changeset
771 // The next few definitions allow the code to be verbatim:
a61af66fc99e Initial load
duke
parents:
diff changeset
772 #define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n))
a61af66fc99e Initial load
duke
parents:
diff changeset
773 #define free(p) FREE_C_HEAP_ARRAY(char, p)
a61af66fc99e Initial load
duke
parents:
diff changeset
774 #define getenv(n) ::getenv(n)
a61af66fc99e Initial load
duke
parents:
diff changeset
775
a61af66fc99e Initial load
duke
parents:
diff changeset
776 #define EXTENSIONS_DIR "/lib/ext"
a61af66fc99e Initial load
duke
parents:
diff changeset
777 #define ENDORSED_DIR "/lib/endorsed"
a61af66fc99e Initial load
duke
parents:
diff changeset
778 #define COMMON_DIR "/usr/jdk/packages"
a61af66fc99e Initial load
duke
parents:
diff changeset
779
a61af66fc99e Initial load
duke
parents:
diff changeset
780 {
a61af66fc99e Initial load
duke
parents:
diff changeset
781 /* sysclasspath, java_home, dll_dir */
a61af66fc99e Initial load
duke
parents:
diff changeset
782 {
a61af66fc99e Initial load
duke
parents:
diff changeset
783 char *home_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
784 char *dll_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
785 char *pslash;
a61af66fc99e Initial load
duke
parents:
diff changeset
786 char buf[MAXPATHLEN];
a61af66fc99e Initial load
duke
parents:
diff changeset
787 os::jvm_path(buf, sizeof(buf));
a61af66fc99e Initial load
duke
parents:
diff changeset
788
a61af66fc99e Initial load
duke
parents:
diff changeset
789 // Found the full path to libjvm.so.
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // Now cut the path to <java_home>/jre if we can.
a61af66fc99e Initial load
duke
parents:
diff changeset
791 *(strrchr(buf, '/')) = '\0'; /* get rid of /libjvm.so */
a61af66fc99e Initial load
duke
parents:
diff changeset
792 pslash = strrchr(buf, '/');
a61af66fc99e Initial load
duke
parents:
diff changeset
793 if (pslash != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
794 *pslash = '\0'; /* get rid of /{client|server|hotspot} */
a61af66fc99e Initial load
duke
parents:
diff changeset
795 dll_path = malloc(strlen(buf) + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
796 if (dll_path == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
797 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
798 strcpy(dll_path, buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
799 Arguments::set_dll_dir(dll_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
800
a61af66fc99e Initial load
duke
parents:
diff changeset
801 if (pslash != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
802 pslash = strrchr(buf, '/');
a61af66fc99e Initial load
duke
parents:
diff changeset
803 if (pslash != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
804 *pslash = '\0'; /* get rid of /<arch> */
a61af66fc99e Initial load
duke
parents:
diff changeset
805 pslash = strrchr(buf, '/');
a61af66fc99e Initial load
duke
parents:
diff changeset
806 if (pslash != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
807 *pslash = '\0'; /* get rid of /lib */
a61af66fc99e Initial load
duke
parents:
diff changeset
808 }
a61af66fc99e Initial load
duke
parents:
diff changeset
809 }
a61af66fc99e Initial load
duke
parents:
diff changeset
810
a61af66fc99e Initial load
duke
parents:
diff changeset
811 home_path = malloc(strlen(buf) + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
812 if (home_path == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
813 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
814 strcpy(home_path, buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
815 Arguments::set_java_home(home_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
816
a61af66fc99e Initial load
duke
parents:
diff changeset
817 if (!set_boot_path('/', ':'))
a61af66fc99e Initial load
duke
parents:
diff changeset
818 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
819 }
a61af66fc99e Initial load
duke
parents:
diff changeset
820
a61af66fc99e Initial load
duke
parents:
diff changeset
821 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
822 * Where to look for native libraries
a61af66fc99e Initial load
duke
parents:
diff changeset
823 */
a61af66fc99e Initial load
duke
parents:
diff changeset
824 {
a61af66fc99e Initial load
duke
parents:
diff changeset
825 // Use dlinfo() to determine the correct java.library.path.
a61af66fc99e Initial load
duke
parents:
diff changeset
826 //
a61af66fc99e Initial load
duke
parents:
diff changeset
827 // If we're launched by the Java launcher, and the user
a61af66fc99e Initial load
duke
parents:
diff changeset
828 // does not set java.library.path explicitly on the commandline,
a61af66fc99e Initial load
duke
parents:
diff changeset
829 // the Java launcher sets LD_LIBRARY_PATH for us and unsets
a61af66fc99e Initial load
duke
parents:
diff changeset
830 // LD_LIBRARY_PATH_32 and LD_LIBRARY_PATH_64. In this case
a61af66fc99e Initial load
duke
parents:
diff changeset
831 // dlinfo returns LD_LIBRARY_PATH + crle settings (including
a61af66fc99e Initial load
duke
parents:
diff changeset
832 // /usr/lib), which is exactly what we want.
a61af66fc99e Initial load
duke
parents:
diff changeset
833 //
a61af66fc99e Initial load
duke
parents:
diff changeset
834 // If the user does set java.library.path, it completely
a61af66fc99e Initial load
duke
parents:
diff changeset
835 // overwrites this setting, and always has.
a61af66fc99e Initial load
duke
parents:
diff changeset
836 //
a61af66fc99e Initial load
duke
parents:
diff changeset
837 // If we're not launched by the Java launcher, we may
a61af66fc99e Initial load
duke
parents:
diff changeset
838 // get here with any/all of the LD_LIBRARY_PATH[_32|64]
a61af66fc99e Initial load
duke
parents:
diff changeset
839 // settings. Again, dlinfo does exactly what we want.
a61af66fc99e Initial load
duke
parents:
diff changeset
840
a61af66fc99e Initial load
duke
parents:
diff changeset
841 Dl_serinfo _info, *info = &_info;
a61af66fc99e Initial load
duke
parents:
diff changeset
842 Dl_serpath *path;
a61af66fc99e Initial load
duke
parents:
diff changeset
843 char* library_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
844 char *common_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
845 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
846
a61af66fc99e Initial load
duke
parents:
diff changeset
847 // determine search path count and required buffer size
a61af66fc99e Initial load
duke
parents:
diff changeset
848 if (dlinfo(RTLD_SELF, RTLD_DI_SERINFOSIZE, (void *)info) == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
849 vm_exit_during_initialization("dlinfo SERINFOSIZE request", dlerror());
a61af66fc99e Initial load
duke
parents:
diff changeset
850 }
a61af66fc99e Initial load
duke
parents:
diff changeset
851
a61af66fc99e Initial load
duke
parents:
diff changeset
852 // allocate new buffer and initialize
a61af66fc99e Initial load
duke
parents:
diff changeset
853 info = (Dl_serinfo*)malloc(_info.dls_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
854 if (info == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
855 vm_exit_out_of_memory(_info.dls_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
856 "init_system_properties_values info");
a61af66fc99e Initial load
duke
parents:
diff changeset
857 }
a61af66fc99e Initial load
duke
parents:
diff changeset
858 info->dls_size = _info.dls_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
859 info->dls_cnt = _info.dls_cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
860
a61af66fc99e Initial load
duke
parents:
diff changeset
861 // obtain search path information
a61af66fc99e Initial load
duke
parents:
diff changeset
862 if (dlinfo(RTLD_SELF, RTLD_DI_SERINFO, (void *)info) == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
863 free(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
864 vm_exit_during_initialization("dlinfo SERINFO request", dlerror());
a61af66fc99e Initial load
duke
parents:
diff changeset
865 }
a61af66fc99e Initial load
duke
parents:
diff changeset
866
a61af66fc99e Initial load
duke
parents:
diff changeset
867 path = &info->dls_serpath[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
868
a61af66fc99e Initial load
duke
parents:
diff changeset
869 // Note: Due to a legacy implementation, most of the library path
a61af66fc99e Initial load
duke
parents:
diff changeset
870 // is set in the launcher. This was to accomodate linking restrictions
a61af66fc99e Initial load
duke
parents:
diff changeset
871 // on legacy Solaris implementations (which are no longer supported).
a61af66fc99e Initial load
duke
parents:
diff changeset
872 // Eventually, all the library path setting will be done here.
a61af66fc99e Initial load
duke
parents:
diff changeset
873 //
a61af66fc99e Initial load
duke
parents:
diff changeset
874 // However, to prevent the proliferation of improperly built native
a61af66fc99e Initial load
duke
parents:
diff changeset
875 // libraries, the new path component /usr/jdk/packages is added here.
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 // Determine the actual CPU architecture.
a61af66fc99e Initial load
duke
parents:
diff changeset
878 char cpu_arch[12];
a61af66fc99e Initial load
duke
parents:
diff changeset
879 sysinfo(SI_ARCHITECTURE, cpu_arch, sizeof(cpu_arch));
a61af66fc99e Initial load
duke
parents:
diff changeset
880 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
881 // If we are a 64-bit vm, perform the following translations:
a61af66fc99e Initial load
duke
parents:
diff changeset
882 // sparc -> sparcv9
a61af66fc99e Initial load
duke
parents:
diff changeset
883 // i386 -> amd64
a61af66fc99e Initial load
duke
parents:
diff changeset
884 if (strcmp(cpu_arch, "sparc") == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
885 strcat(cpu_arch, "v9");
a61af66fc99e Initial load
duke
parents:
diff changeset
886 else if (strcmp(cpu_arch, "i386") == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
887 strcpy(cpu_arch, "amd64");
a61af66fc99e Initial load
duke
parents:
diff changeset
888 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
889
a61af66fc99e Initial load
duke
parents:
diff changeset
890 // Construct the invariant part of ld_library_path. Note that the
a61af66fc99e Initial load
duke
parents:
diff changeset
891 // space for the colon and the trailing null are provided by the
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // nulls included by the sizeof operator.
a61af66fc99e Initial load
duke
parents:
diff changeset
893 size_t bufsize = sizeof(COMMON_DIR) + sizeof("/lib/") + strlen(cpu_arch);
a61af66fc99e Initial load
duke
parents:
diff changeset
894 common_path = malloc(bufsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
895 if (common_path == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
896 free(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
897 vm_exit_out_of_memory(bufsize,
a61af66fc99e Initial load
duke
parents:
diff changeset
898 "init_system_properties_values common_path");
a61af66fc99e Initial load
duke
parents:
diff changeset
899 }
a61af66fc99e Initial load
duke
parents:
diff changeset
900 sprintf(common_path, COMMON_DIR "/lib/%s", cpu_arch);
a61af66fc99e Initial load
duke
parents:
diff changeset
901
a61af66fc99e Initial load
duke
parents:
diff changeset
902 // struct size is more than sufficient for the path components obtained
a61af66fc99e Initial load
duke
parents:
diff changeset
903 // through the dlinfo() call, so only add additional space for the path
a61af66fc99e Initial load
duke
parents:
diff changeset
904 // components explicitly added here.
a61af66fc99e Initial load
duke
parents:
diff changeset
905 bufsize = info->dls_size + strlen(common_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
906 library_path = malloc(bufsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
907 if (library_path == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
908 free(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
909 free(common_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
910 vm_exit_out_of_memory(bufsize,
a61af66fc99e Initial load
duke
parents:
diff changeset
911 "init_system_properties_values library_path");
a61af66fc99e Initial load
duke
parents:
diff changeset
912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
913 library_path[0] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
914
a61af66fc99e Initial load
duke
parents:
diff changeset
915 // Construct the desired Java library path from the linker's library
a61af66fc99e Initial load
duke
parents:
diff changeset
916 // search path.
a61af66fc99e Initial load
duke
parents:
diff changeset
917 //
a61af66fc99e Initial load
duke
parents:
diff changeset
918 // For compatibility, it is optimal that we insert the additional path
a61af66fc99e Initial load
duke
parents:
diff changeset
919 // components specific to the Java VM after those components specified
a61af66fc99e Initial load
duke
parents:
diff changeset
920 // in LD_LIBRARY_PATH (if any) but before those added by the ld.so
a61af66fc99e Initial load
duke
parents:
diff changeset
921 // infrastructure.
a61af66fc99e Initial load
duke
parents:
diff changeset
922 if (info->dls_cnt == 0) { // Not sure this can happen, but allow for it
a61af66fc99e Initial load
duke
parents:
diff changeset
923 strcpy(library_path, common_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
924 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
925 int inserted = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
926 for (i = 0; i < info->dls_cnt; i++, path++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
927 uint_t flags = path->dls_flags & LA_SER_MASK;
a61af66fc99e Initial load
duke
parents:
diff changeset
928 if (((flags & LA_SER_LIBPATH) == 0) && !inserted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
929 strcat(library_path, common_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
930 strcat(library_path, os::path_separator());
a61af66fc99e Initial load
duke
parents:
diff changeset
931 inserted = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
933 strcat(library_path, path->dls_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
934 strcat(library_path, os::path_separator());
a61af66fc99e Initial load
duke
parents:
diff changeset
935 }
a61af66fc99e Initial load
duke
parents:
diff changeset
936 // eliminate trailing path separator
a61af66fc99e Initial load
duke
parents:
diff changeset
937 library_path[strlen(library_path)-1] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
939
a61af66fc99e Initial load
duke
parents:
diff changeset
940 // happens before argument parsing - can't use a trace flag
a61af66fc99e Initial load
duke
parents:
diff changeset
941 // tty->print_raw("init_system_properties_values: native lib path: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
942 // tty->print_raw_cr(library_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
943
a61af66fc99e Initial load
duke
parents:
diff changeset
944 // callee copies into its own buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
945 Arguments::set_library_path(library_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
946
a61af66fc99e Initial load
duke
parents:
diff changeset
947 free(common_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
948 free(library_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
949 free(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
950 }
a61af66fc99e Initial load
duke
parents:
diff changeset
951
a61af66fc99e Initial load
duke
parents:
diff changeset
952 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
953 * Extensions directories.
a61af66fc99e Initial load
duke
parents:
diff changeset
954 *
a61af66fc99e Initial load
duke
parents:
diff changeset
955 * Note that the space for the colon and the trailing null are provided
a61af66fc99e Initial load
duke
parents:
diff changeset
956 * by the nulls included by the sizeof operator (so actually one byte more
a61af66fc99e Initial load
duke
parents:
diff changeset
957 * than necessary is allocated).
a61af66fc99e Initial load
duke
parents:
diff changeset
958 */
a61af66fc99e Initial load
duke
parents:
diff changeset
959 {
a61af66fc99e Initial load
duke
parents:
diff changeset
960 char *buf = (char *) malloc(strlen(Arguments::get_java_home()) +
a61af66fc99e Initial load
duke
parents:
diff changeset
961 sizeof(EXTENSIONS_DIR) + sizeof(COMMON_DIR) +
a61af66fc99e Initial load
duke
parents:
diff changeset
962 sizeof(EXTENSIONS_DIR));
a61af66fc99e Initial load
duke
parents:
diff changeset
963 sprintf(buf, "%s" EXTENSIONS_DIR ":" COMMON_DIR EXTENSIONS_DIR,
a61af66fc99e Initial load
duke
parents:
diff changeset
964 Arguments::get_java_home());
a61af66fc99e Initial load
duke
parents:
diff changeset
965 Arguments::set_ext_dirs(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
967
a61af66fc99e Initial load
duke
parents:
diff changeset
968 /* Endorsed standards default directory. */
a61af66fc99e Initial load
duke
parents:
diff changeset
969 {
a61af66fc99e Initial load
duke
parents:
diff changeset
970 char * buf = malloc(strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR));
a61af66fc99e Initial load
duke
parents:
diff changeset
971 sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home());
a61af66fc99e Initial load
duke
parents:
diff changeset
972 Arguments::set_endorsed_dirs(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
973 }
a61af66fc99e Initial load
duke
parents:
diff changeset
974 }
a61af66fc99e Initial load
duke
parents:
diff changeset
975
a61af66fc99e Initial load
duke
parents:
diff changeset
976 #undef malloc
a61af66fc99e Initial load
duke
parents:
diff changeset
977 #undef free
a61af66fc99e Initial load
duke
parents:
diff changeset
978 #undef getenv
a61af66fc99e Initial load
duke
parents:
diff changeset
979 #undef EXTENSIONS_DIR
a61af66fc99e Initial load
duke
parents:
diff changeset
980 #undef ENDORSED_DIR
a61af66fc99e Initial load
duke
parents:
diff changeset
981 #undef COMMON_DIR
a61af66fc99e Initial load
duke
parents:
diff changeset
982
a61af66fc99e Initial load
duke
parents:
diff changeset
983 }
a61af66fc99e Initial load
duke
parents:
diff changeset
984
a61af66fc99e Initial load
duke
parents:
diff changeset
985 void os::breakpoint() {
a61af66fc99e Initial load
duke
parents:
diff changeset
986 BREAKPOINT;
a61af66fc99e Initial load
duke
parents:
diff changeset
987 }
a61af66fc99e Initial load
duke
parents:
diff changeset
988
a61af66fc99e Initial load
duke
parents:
diff changeset
989 bool os::obsolete_option(const JavaVMOption *option)
a61af66fc99e Initial load
duke
parents:
diff changeset
990 {
a61af66fc99e Initial load
duke
parents:
diff changeset
991 if (!strncmp(option->optionString, "-Xt", 3)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
992 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
993 } else if (!strncmp(option->optionString, "-Xtm", 4)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
994 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
995 } else if (!strncmp(option->optionString, "-Xverifyheap", 12)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
996 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
997 } else if (!strncmp(option->optionString, "-Xmaxjitcodesize", 16)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
998 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1002
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 bool os::Solaris::valid_stack_address(Thread* thread, address sp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 address stackStart = (address)thread->stack_base();
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 address stackEnd = (address)(stackStart - (address)thread->stack_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 if (sp < stackStart && sp >= stackEnd ) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1009
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 extern "C" void breakpoint() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 // use debugger to set breakpoint here
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1013
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 // Returns an estimate of the current stack pointer. Result must be guaranteed to
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 // point into the calling threads stack, and be no lower than the current stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 // pointer.
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 address os::current_stack_pointer() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 volatile int dummy;
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 address sp = (address)&dummy + 8; // %%%% need to confirm if this is right
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 return sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1022
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 static thread_t main_thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1024
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 // Thread start routine for all new Java threads
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 extern "C" void* java_start(void* thread_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 // Try to randomize the cache line index of hot stack frames.
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 // This helps when threads of the same stack traces evict each other's
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 // cache lines. The threads can be either from the same JVM instance, or
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 // from different JVM instances. The benefit is especially true for
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 // processors with hyperthreading technology.
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 static int counter = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 int pid = os::current_process_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 alloca(((pid ^ counter++) & 7) * 128);
a61af66fc99e Initial load
duke
parents:
diff changeset
1035
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 int prio;
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 Thread* thread = (Thread*)thread_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 OSThread* osthr = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
1039
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 osthr->set_lwp_id( _lwp_self() ); // Store lwp in case we are bound
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 thread->_schedctl = (void *) schedctl_init () ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1042
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 if (UseNUMA) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 int lgrp_id = os::numa_get_group_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 if (lgrp_id != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 thread->set_lgrp_id(lgrp_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1049
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 // If the creator called set priority before we started,
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 // we need to call set priority now that we have an lwp.
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 // Get the priority from libthread and set the priority
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 // for the new Solaris lwp.
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 if ( osthr->thread_id() != -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 if ( UseThreadPriorities ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 thr_getprio(osthr->thread_id(), &prio);
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 if (ThreadPriorityVerbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 tty->print_cr("Starting Thread " INTPTR_FORMAT ", LWP is " INTPTR_FORMAT ", setting priority: %d\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 osthr->thread_id(), osthr->lwp_id(), prio );
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 os::set_native_priority(thread, prio);
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 } else if (ThreadPriorityVerbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 warning("Can't set priority in _start routine, thread id hasn't been set\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1066
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 assert(osthr->get_state() == RUNNABLE, "invalid os thread state");
a61af66fc99e Initial load
duke
parents:
diff changeset
1068
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 // initialize signal mask for this thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 os::Solaris::hotspot_sigmask(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1071
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 thread->run();
a61af66fc99e Initial load
duke
parents:
diff changeset
1073
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 // One less thread is executing
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 // When the VMThread gets here, the main thread may have already exited
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 // which frees the CodeHeap containing the Atomic::dec code
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 Atomic::dec(&os::Solaris::_os_thread_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1080
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 if (UseDetachedThreads) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 thr_exit(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1087
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 static OSThread* create_os_thread(Thread* thread, thread_t thread_id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 // Allocate the OSThread object
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 OSThread* osthread = new OSThread(NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 if (osthread == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1092
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 // Store info on the Solaris thread into the OSThread
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 osthread->set_thread_id(thread_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 osthread->set_lwp_id(_lwp_self());
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 thread->_schedctl = (void *) schedctl_init () ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1097
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 if (UseNUMA) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 int lgrp_id = os::numa_get_group_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 if (lgrp_id != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 thread->set_lgrp_id(lgrp_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1104
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 if ( ThreadPriorityVerbose ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 tty->print_cr("In create_os_thread, Thread " INTPTR_FORMAT ", LWP is " INTPTR_FORMAT "\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 osthread->thread_id(), osthread->lwp_id() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1109
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 // Initial thread state is INITIALIZED, not SUSPENDED
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 osthread->set_state(INITIALIZED);
a61af66fc99e Initial load
duke
parents:
diff changeset
1112
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 return osthread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1115
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 void os::Solaris::hotspot_sigmask(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1117
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 //Save caller's signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 sigset_t sigmask;
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 thr_sigsetmask(SIG_SETMASK, NULL, &sigmask);
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 OSThread *osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 osthread->set_caller_sigmask(sigmask);
a61af66fc99e Initial load
duke
parents:
diff changeset
1123
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 thr_sigsetmask(SIG_UNBLOCK, os::Solaris::unblocked_signals(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 if (!ReduceSignalUsage) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 if (thread->is_VM_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 // Only the VM thread handles BREAK_SIGNAL ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 thr_sigsetmask(SIG_UNBLOCK, vm_signals(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 // ... all other threads block BREAK_SIGNAL
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 assert(!sigismember(vm_signals(), SIGINT), "SIGINT should not be blocked");
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 thr_sigsetmask(SIG_BLOCK, vm_signals(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1136
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 bool os::create_attached_thread(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 thread->verify_not_published();
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 OSThread* osthread = create_os_thread(thread, thr_self());
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 if (osthread == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1145
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 // Initial thread state is RUNNABLE
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 osthread->set_state(RUNNABLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 thread->set_osthread(osthread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1149
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 // initialize signal mask for this thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 // and save the caller's signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 os::Solaris::hotspot_sigmask(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1153
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1156
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 bool os::create_main_thread(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 thread->verify_not_published();
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 if (_starting_thread == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 _starting_thread = create_os_thread(thread, main_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 if (_starting_thread == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1167
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 // The primodial thread is runnable from the start
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 _starting_thread->set_state(RUNNABLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1170
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 thread->set_osthread(_starting_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1172
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // initialize signal mask for this thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 // and save the caller's signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 os::Solaris::hotspot_sigmask(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1176
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1179
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 // _T2_libthread is true if we believe we are running with the newer
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 // SunSoft lwp/libthread.so (2.8 patch, 2.9 default)
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 bool os::Solaris::_T2_libthread = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1183
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 // Allocate the OSThread object
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 OSThread* osthread = new OSThread(NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 if (osthread == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1190
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 if ( ThreadPriorityVerbose ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 char *thrtyp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 switch ( thr_type ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 case vm_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 thrtyp = (char *)"vm";
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 case cgc_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 thrtyp = (char *)"cgc";
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 case pgc_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 thrtyp = (char *)"pgc";
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 case java_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 thrtyp = (char *)"java";
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 case compiler_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 thrtyp = (char *)"compiler";
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 case watcher_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 thrtyp = (char *)"watcher";
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 thrtyp = (char *)"unknown";
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 tty->print_cr("In create_thread, creating a %s thread\n", thrtyp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1218
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 // Calculate stack size if it's not specified by caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 if (stack_size == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 // The default stack size 1M (2M for LP64).
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 stack_size = (BytesPerWord >> 2) * K * K;
a61af66fc99e Initial load
duke
parents:
diff changeset
1223
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 switch (thr_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 case os::java_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 // Java threads use ThreadStackSize which default value can be changed with the flag -Xss
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 if (JavaThread::stack_size_at_create() > 0) stack_size = JavaThread::stack_size_at_create();
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 case os::compiler_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 if (CompilerThreadStackSize > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 stack_size = (size_t)(CompilerThreadStackSize * K);
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 } // else fall through:
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 // use VMThreadStackSize if CompilerThreadStackSize is not defined
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 case os::vm_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 case os::pgc_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 case os::cgc_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 case os::watcher_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 stack_size = MAX2(stack_size, os::Solaris::min_stack_allowed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1244
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 // Initial state is ALLOCATED but not INITIALIZED
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 osthread->set_state(ALLOCATED);
a61af66fc99e Initial load
duke
parents:
diff changeset
1247
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 if (os::Solaris::_os_thread_count > os::Solaris::_os_thread_limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 // We got lots of threads. Check if we still have some address space left.
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 // Need to be at least 5Mb of unreserved address space. We do check by
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 // trying to reserve some.
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 const size_t VirtualMemoryBangSize = 20*K*K;
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 char* mem = os::reserve_memory(VirtualMemoryBangSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 if (mem == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 delete osthread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 // Release the memory again
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 os::release_memory(mem, VirtualMemoryBangSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1262
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 // Setup osthread because the child thread may need it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 thread->set_osthread(osthread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1265
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 // Create the Solaris thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 // explicit THR_BOUND for T2_libthread case in case
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 // that assumption is not accurate, but our alternate signal stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 // handling is based on it which must have bound threads
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 thread_t tid = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 long flags = (UseDetachedThreads ? THR_DETACHED : 0) | THR_SUSPENDED
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 | ((UseBoundThreads || os::Solaris::T2_libthread() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 (thr_type == vm_thread) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 (thr_type == cgc_thread) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 (thr_type == pgc_thread) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 (thr_type == compiler_thread && BackgroundCompilation)) ?
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 THR_BOUND : 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 int status;
a61af66fc99e Initial load
duke
parents:
diff changeset
1279
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 // 4376845 -- libthread/kernel don't provide enough LWPs to utilize all CPUs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // On multiprocessors systems, libthread sometimes under-provisions our
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 // process with LWPs. On a 30-way systems, for instance, we could have
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 // 50 user-level threads in ready state and only 2 or 3 LWPs assigned
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // to our process. This can result in under utilization of PEs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 // I suspect the problem is related to libthread's LWP
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 // pool management and to the kernel's SIGBLOCKING "last LWP parked"
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // upcall policy.
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 // The following code is palliative -- it attempts to ensure that our
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 // process has sufficient LWPs to take advantage of multiple PEs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 // Proper long-term cures include using user-level threads bound to LWPs
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 // (THR_BOUND) or using LWP-based synchronization. Note that there is a
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 // slight timing window with respect to sampling _os_thread_count, but
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // the race is benign. Also, we should periodically recompute
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 // _processors_online as the min of SC_NPROCESSORS_ONLN and the
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 // the number of PEs in our partition. You might be tempted to use
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 // THR_NEW_LWP here, but I'd recommend against it as that could
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 // result in undesirable growth of the libthread's LWP pool.
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 // The fix below isn't sufficient; for instance, it doesn't take into count
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 // LWPs parked on IO. It does, however, help certain CPU-bound benchmarks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 // Some pathologies this scheme doesn't handle:
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 // * Threads can block, releasing the LWPs. The LWPs can age out.
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 // When a large number of threads become ready again there aren't
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 // enough LWPs available to service them. This can occur when the
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 // number of ready threads oscillates.
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 // * LWPs/Threads park on IO, thus taking the LWP out of circulation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 // Finally, we should call thr_setconcurrency() periodically to refresh
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 // the LWP pool and thwart the LWP age-out mechanism.
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 // The "+3" term provides a little slop -- we want to slightly overprovision.
a61af66fc99e Initial load
duke
parents:
diff changeset
1313
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 if (AdjustConcurrency && os::Solaris::_os_thread_count < (_processors_online+3)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 if (!(flags & THR_BOUND)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 thr_setconcurrency (os::Solaris::_os_thread_count); // avoid starvation
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 // Although this doesn't hurt, we should warn of undefined behavior
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 // when using unbound T1 threads with schedctl(). This should never
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 // happen, as the compiler and VM threads are always created bound
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 DEBUG_ONLY(
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 if ((VMThreadHintNoPreempt || CompilerThreadHintNoPreempt) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 (!os::Solaris::T2_libthread() && (!(flags & THR_BOUND))) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 ((thr_type == vm_thread) || (thr_type == cgc_thread) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 (thr_type == pgc_thread) || (thr_type == compiler_thread && BackgroundCompilation))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 warning("schedctl behavior undefined when Compiler/VM/GC Threads are Unbound");
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1330
a61af66fc99e Initial load
duke
parents:
diff changeset
1331
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 // Mark that we don't have an lwp or thread id yet.
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 // In case we attempt to set the priority before the thread starts.
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 osthread->set_lwp_id(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 osthread->set_thread_id(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1336
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 status = thr_create(NULL, stack_size, java_start, thread, flags, &tid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 if (status != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 if (PrintMiscellaneous && (Verbose || WizardMode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 perror("os::create_thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 thread->set_osthread(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 // Need to clean up stuff we've allocated so far
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 delete osthread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1347
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 Atomic::inc(&os::Solaris::_os_thread_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1349
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 // Store info on the Solaris thread into the OSThread
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 osthread->set_thread_id(tid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1352
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 // Remember that we created this thread so we can set priority on it
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 osthread->set_vm_created();
a61af66fc99e Initial load
duke
parents:
diff changeset
1355
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 // Set the default thread priority otherwise use NormalPriority
a61af66fc99e Initial load
duke
parents:
diff changeset
1357
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 if ( UseThreadPriorities ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 thr_setprio(tid, (DefaultThreadPriority == -1) ?
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 java_to_os_priority[NormPriority] :
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 DefaultThreadPriority);
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1363
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 // Initial thread state is INITIALIZED, not SUSPENDED
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 osthread->set_state(INITIALIZED);
a61af66fc99e Initial load
duke
parents:
diff changeset
1366
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1370
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 /* defined for >= Solaris 10. This allows builds on earlier versions
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 * of Solaris to take advantage of the newly reserved Solaris JVM signals
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 * With SIGJVM1, SIGJVM2, INTERRUPT_SIGNAL is SIGJVM1, ASYNC_SIGNAL is SIGJVM2
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 * and -XX:+UseAltSigs does nothing since these should have no conflict
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 */
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 #if !defined(SIGJVM1)
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 #define SIGJVM1 39
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 #define SIGJVM2 40
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1380
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 debug_only(static bool signal_sets_initialized = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 int os::Solaris::_SIGinterrupt = INTERRUPT_SIGNAL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 int os::Solaris::_SIGasync = ASYNC_SIGNAL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1385
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 bool os::Solaris::is_sig_ignored(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 struct sigaction oact;
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 sigaction(sig, (struct sigaction*)NULL, &oact);
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 : CAST_FROM_FN_PTR(void*, oact.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN))
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1396
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 // Note: SIGRTMIN is a macro that calls sysconf() so it will
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 // dynamically detect SIGRTMIN value for the system at runtime, not buildtime
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 static bool isJVM1available() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 return SIGJVM1 < SIGRTMIN;
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1402
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 void os::Solaris::signal_sets_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 // Should also have an assertion stating we are still single-threaded.
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 assert(!signal_sets_initialized, "Already initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 // Fill in signals that are necessarily unblocked for all threads in
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 // the VM. Currently, we unblock the following signals:
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 // by -Xrs (=ReduceSignalUsage));
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 // other threads. The "ReduceSignalUsage" boolean tells us not to alter
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 // the dispositions or masks wrt these signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 // Programs embedding the VM that want to use the above signals for their
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 // own purposes must, at this time, use the "-Xrs" option to prevent
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 // interference with shutdown hooks and BREAK_SIGNAL thread dumping.
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 // (See bug 4345157, and other related bugs).
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 // In reality, though, unblocking these signals is really a nop, since
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 // these signals are not blocked by default.
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 sigemptyset(&unblocked_sigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 sigemptyset(&allowdebug_blocked_sigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 sigaddset(&unblocked_sigs, SIGILL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 sigaddset(&unblocked_sigs, SIGSEGV);
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 sigaddset(&unblocked_sigs, SIGBUS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 sigaddset(&unblocked_sigs, SIGFPE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1425
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 if (isJVM1available) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 os::Solaris::set_SIGinterrupt(SIGJVM1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 os::Solaris::set_SIGasync(SIGJVM2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 } else if (UseAltSigs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 os::Solaris::set_SIGinterrupt(ALT_INTERRUPT_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 os::Solaris::set_SIGasync(ALT_ASYNC_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 os::Solaris::set_SIGinterrupt(INTERRUPT_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 os::Solaris::set_SIGasync(ASYNC_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1436
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 sigaddset(&unblocked_sigs, os::Solaris::SIGinterrupt());
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 sigaddset(&unblocked_sigs, os::Solaris::SIGasync());
a61af66fc99e Initial load
duke
parents:
diff changeset
1439
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 if (!ReduceSignalUsage) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 if (!os::Solaris::is_sig_ignored(SHUTDOWN1_SIGNAL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN1_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 if (!os::Solaris::is_sig_ignored(SHUTDOWN2_SIGNAL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN2_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 if (!os::Solaris::is_sig_ignored(SHUTDOWN3_SIGNAL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN3_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 // Fill in signals that are blocked by all but the VM thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 sigemptyset(&vm_sigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 if (!ReduceSignalUsage)
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 sigaddset(&vm_sigs, BREAK_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 debug_only(signal_sets_initialized = true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1459
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 // For diagnostics only used in run_periodic_checks
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 sigemptyset(&check_signal_done);
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1463
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 // These are signals that are unblocked while a thread is running Java.
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 // (For some reason, they get blocked by default.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 sigset_t* os::Solaris::unblocked_signals() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 assert(signal_sets_initialized, "Not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 return &unblocked_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1470
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 // These are the signals that are blocked while a (non-VM) thread is
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 // running Java. Only the VM thread handles these signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 sigset_t* os::Solaris::vm_signals() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 assert(signal_sets_initialized, "Not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 return &vm_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1477
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 // These are signals that are blocked during cond_wait to allow debugger in
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 sigset_t* os::Solaris::allowdebug_blocked_signals() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 assert(signal_sets_initialized, "Not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 return &allowdebug_blocked_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1483
2068
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1484
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1485 void _handle_uncaught_cxx_exception() {
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1486 VMError err("An uncaught C++ exception");
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1487 err.report_and_die();
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1488 }
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1489
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1490
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 // First crack at OS-specific initialization, from inside the new thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 void os::initialize_thread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 int r = thr_main() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 if (r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 JavaThread* jt = (JavaThread *)Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 assert(jt != NULL,"Sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 size_t stack_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 address base = jt->stack_base();
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 if (Arguments::created_by_java_launcher()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 // Use 2MB to allow for Solaris 7 64 bit mode.
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 stack_size = JavaThread::stack_size_at_create() == 0
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 ? 2048*K : JavaThread::stack_size_at_create();
a61af66fc99e Initial load
duke
parents:
diff changeset
1504
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 // There are rare cases when we may have already used more than
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 // the basic stack size allotment before this method is invoked.
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 // Attempt to allow for a normally sized java_stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 size_t current_stack_offset = (size_t)(base - (address)&stack_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 stack_size += ReservedSpace::page_align_size_down(current_stack_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 // 6269555: If we were not created by a Java launcher, i.e. if we are
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 // running embedded in a native application, treat the primordial thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 // as much like a native attached thread as possible. This means using
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 // the current stack size from thr_stksegment(), unless it is too large
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 // to reliably setup guard pages. A reasonable max size is 8MB.
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 size_t current_size = current_stack_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 // This should never happen, but just in case....
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 if (current_size == 0) current_size = 2 * K * K;
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 stack_size = current_size > (8 * K * K) ? (8 * K * K) : current_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 address bottom = (address)align_size_up((intptr_t)(base - stack_size), os::vm_page_size());;
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 stack_size = (size_t)(base - bottom);
a61af66fc99e Initial load
duke
parents:
diff changeset
1523
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 assert(stack_size > 0, "Stack size calculation problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
1525
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 if (stack_size > jt->stack_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 struct rlimit limits;
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 getrlimit(RLIMIT_STACK, &limits);
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 size_t size = adjust_stack_size(base, (size_t)limits.rlim_cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 assert(size >= jt->stack_size(), "Stack size problem in main thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 tty->print_cr(
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 "Stack size of %d Kb exceeds current limit of %d Kb.\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 "(Stack sizes are rounded up to a multiple of the system page size.)\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 "See limit(1) to increase the stack size limit.",
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 stack_size / K, jt->stack_size() / K);
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 vm_exit(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 assert(jt->stack_size() >= stack_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 "Attempt to map more stack than was allocated");
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 jt->set_stack_size(stack_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1544
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 // 5/22/01: Right now alternate signal stacks do not handle
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 // throwing stack overflow exceptions, see bug 4463178
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 // Until a fix is found for this, T2 will NOT imply alternate signal
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 // stacks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 // If using T2 libthread threads, install an alternate signal stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 // Because alternate stacks associate with LWPs on Solaris,
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 // see sigaltstack(2), if using UNBOUND threads, or if UseBoundThreads
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 // we prefer to explicitly stack bang.
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 // If not using T2 libthread, but using UseBoundThreads any threads
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 // (primordial thread, jni_attachCurrentThread) we do not create,
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 // probably are not bound, therefore they can not have an alternate
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 // signal stack. Since our stack banging code is generated and
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 // is shared across threads, all threads must be bound to allow
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 // using alternate signal stacks. The alternative is to interpose
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 // on _lwp_create to associate an alt sig stack with each LWP,
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 // and this could be a problem when the JVM is embedded.
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 // We would prefer to use alternate signal stacks with T2
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 // Since there is currently no accurate way to detect T2
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 // we do not. Assuming T2 when running T1 causes sig 11s or assertions
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 // on installing alternate signal stacks
a61af66fc99e Initial load
duke
parents:
diff changeset
1565
a61af66fc99e Initial load
duke
parents:
diff changeset
1566
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 // 05/09/03: removed alternate signal stack support for Solaris
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 // The alternate signal stack mechanism is no longer needed to
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 // handle stack overflow. This is now handled by allocating
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 // guard pages (red zone) and stackbanging.
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 // Initially the alternate signal stack mechanism was removed because
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 // it did not work with T1 llibthread. Alternate
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 // signal stacks MUST have all threads bound to lwps. Applications
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 // can create their own threads and attach them without their being
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 // bound under T1. This is frequently the case for the primordial thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 // If we were ever to reenable this mechanism we would need to
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 // use the dynamic check for T2 libthread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1578
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 os::Solaris::init_thread_fpu_state();
2068
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1580 std::set_terminate(_handle_uncaught_cxx_exception);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1582
a61af66fc99e Initial load
duke
parents:
diff changeset
1583
a61af66fc99e Initial load
duke
parents:
diff changeset
1584
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 // Free Solaris resources related to the OSThread
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 void os::free_thread(OSThread* osthread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 assert(osthread != NULL, "os::free_thread but osthread not set");
a61af66fc99e Initial load
duke
parents:
diff changeset
1588
a61af66fc99e Initial load
duke
parents:
diff changeset
1589
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 // We are told to free resources of the argument thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 // but we can only really operate on the current thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 // The main thread must take the VMThread down synchronously
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 // before the main thread exits and frees up CodeHeap
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 guarantee((Thread::current()->osthread() == osthread
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 || (osthread == VMThread::vm_thread()->osthread())), "os::free_thread but not current thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 if (Thread::current()->osthread() == osthread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 // Restore caller's signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 sigset_t sigmask = osthread->caller_sigmask();
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 thr_sigsetmask(SIG_SETMASK, &sigmask, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 delete osthread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1603
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 void os::pd_start_thread(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 int status = thr_continue(thread->osthread()->thread_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 assert_status(status == 0, status, "thr_continue failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1608
a61af66fc99e Initial load
duke
parents:
diff changeset
1609
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 intx os::current_thread_id() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 return (intx)thr_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1613
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 static pid_t _initial_pid = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1615
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 int os::current_process_id() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 return (int)(_initial_pid ? _initial_pid : getpid());
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1619
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 int os::allocate_thread_local_storage() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 // %%% in Win32 this allocates a memory segment pointed to by a
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 // register. Dan Stein can implement a similar feature in
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 // Solaris. Alternatively, the VM can do the same thing
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 // explicitly: malloc some storage and keep the pointer in a
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 // register (which is part of the thread's context) (or keep it
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 // in TLS).
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 // %%% In current versions of Solaris, thr_self and TSD can
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 // be accessed via short sequences of displaced indirections.
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 // The value of thr_self is available as %g7(36).
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 // The value of thr_getspecific(k) is stored in %g7(12)(4)(k*4-4),
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 // assuming that the current thread already has a value bound to k.
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 // It may be worth experimenting with such access patterns,
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 // and later having the parameters formally exported from a Solaris
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 // interface. I think, however, that it will be faster to
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 // maintain the invariant that %g2 always contains the
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 // JavaThread in Java code, and have stubs simply
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 // treat %g2 as a caller-save register, preserving it in a %lN.
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 thread_key_t tk;
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 if (thr_keycreate( &tk, NULL ) )
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
1640 fatal(err_msg("os::allocate_thread_local_storage: thr_keycreate failed "
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
1641 "(%s)", strerror(errno)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 return int(tk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1644
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 void os::free_thread_local_storage(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 // %%% don't think we need anything here
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 // if ( pthread_key_delete((pthread_key_t) tk) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // fatal("os::free_thread_local_storage: pthread_key_delete failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1650
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 #define SMALLINT 32 // libthread allocate for tsd_common is a version specific
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 // small number - point is NO swap space available
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 void os::thread_local_storage_at_put(int index, void* value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 // %%% this is used only in threadLocalStorage.cpp
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 if (thr_setspecific((thread_key_t)index, value)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 if (errno == ENOMEM) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 vm_exit_out_of_memory(SMALLINT, "thr_setspecific: out of swap space");
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 } else {
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
1659 fatal(err_msg("os::thread_local_storage_at_put: thr_setspecific failed "
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
1660 "(%s)", strerror(errno)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 ThreadLocalStorage::set_thread_in_slot ((Thread *) value) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1666
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 // This function could be called before TLS is initialized, for example, when
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 // VM receives an async signal or when VM causes a fatal error during
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 // initialization. Return NULL if thr_getspecific() fails.
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 void* os::thread_local_storage_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 // %%% this is used only in threadLocalStorage.cpp
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 void* r = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 return thr_getspecific((thread_key_t)index, &r) != 0 ? NULL : r;
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1675
a61af66fc99e Initial load
duke
parents:
diff changeset
1676
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 const int NANOSECS_PER_MILLISECS = 1000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 // gethrtime can move backwards if read from one cpu and then a different cpu
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 // getTimeNanos is guaranteed to not move backward on Solaris
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 // local spinloop created as faster for a CAS on an int than
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 // a CAS on a 64bit jlong. Also Atomic::cmpxchg for jlong is not
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 // supported on sparc v8 or pre supports_cx8 intel boxes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 // oldgetTimeNanos for systems which do not support CAS on 64bit jlong
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 // i.e. sparc v8 and pre supports_cx8 (i486) intel boxes
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 inline hrtime_t oldgetTimeNanos() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 int gotlock = LOCK_INVALID;
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 hrtime_t newtime = gethrtime();
a61af66fc99e Initial load
duke
parents:
diff changeset
1688
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 // grab lock for max_hrtime
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 int curlock = max_hrtime_lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 if (curlock & LOCK_BUSY) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 if (gotlock = Atomic::cmpxchg(LOCK_BUSY, &max_hrtime_lock, LOCK_FREE) != LOCK_FREE) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 if (newtime > max_hrtime) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 max_hrtime = newtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 newtime = max_hrtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 // release lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 max_hrtime_lock = LOCK_FREE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 return newtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 // gethrtime can move backwards if read from one cpu and then a different cpu
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 // getTimeNanos is guaranteed to not move backward on Solaris
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 inline hrtime_t getTimeNanos() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 if (VM_Version::supports_cx8()) {
499
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1708 const hrtime_t now = gethrtime();
894
665be97e8704 6863420: os::javaTimeNanos() go backward on Solaris x86
kvn
parents: 691
diff changeset
1709 // Use atomic long load since 32-bit x86 uses 2 registers to keep long.
665be97e8704 6863420: os::javaTimeNanos() go backward on Solaris x86
kvn
parents: 691
diff changeset
1710 const hrtime_t prev = Atomic::load((volatile jlong*)&max_hrtime);
499
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1711 if (now <= prev) return prev; // same or retrograde time;
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1712 const hrtime_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&max_hrtime, prev);
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1713 assert(obsv >= prev, "invariant"); // Monotonicity
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1714 // If the CAS succeeded then we're done and return "now".
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1715 // If the CAS failed and the observed value "obs" is >= now then
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1716 // we should return "obs". If the CAS failed and now > obs > prv then
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1717 // some other thread raced this thread and installed a new value, in which case
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1718 // we could either (a) retry the entire operation, (b) retry trying to install now
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1719 // or (c) just return obs. We use (c). No loop is required although in some cases
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1720 // we might discard a higher "now" value in deference to a slightly lower but freshly
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1721 // installed obs value. That's entirely benign -- it admits no new orderings compared
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1722 // to (a) or (b) -- and greatly reduces coherence traffic.
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1723 // We might also condition (c) on the magnitude of the delta between obs and now.
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1724 // Avoiding excessive CAS operations to hot RW locations is critical.
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1725 // See http://blogs.sun.com/dave/entry/cas_and_cache_trivia_invalidate
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1726 return (prev == obsv) ? now : obsv ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 return oldgetTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1731
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 // Time since start-up in seconds to a fine granularity.
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 // Used by VMSelfDestructTimer and the MemProfiler.
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 double os::elapsedTime() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 return (double)(getTimeNanos() - first_hrtime) / (double)hrtime_hz;
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1737
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 jlong os::elapsed_counter() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 return (jlong)(getTimeNanos() - first_hrtime);
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1741
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 jlong os::elapsed_frequency() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 return hrtime_hz;
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1745
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 // Return the real, user, and system times in seconds from an
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 // arbitrary fixed point in the past.
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 bool os::getTimesSecs(double* process_real_time,
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 double* process_user_time,
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 double* process_system_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 struct tms ticks;
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 clock_t real_ticks = times(&ticks);
a61af66fc99e Initial load
duke
parents:
diff changeset
1753
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 if (real_ticks == (clock_t) (-1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 double ticks_per_second = (double) clock_tics_per_sec;
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 *process_user_time = ((double) ticks.tms_utime) / ticks_per_second;
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 *process_system_time = ((double) ticks.tms_stime) / ticks_per_second;
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 // For consistency return the real time from getTimeNanos()
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 // converted to seconds.
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 *process_real_time = ((double) getTimeNanos()) / ((double) NANOUNITS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1763
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1767
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1768 bool os::supports_vtime() { return true; }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1769
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1770 bool os::enable_vtime() {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1771 int fd = ::open("/proc/self/ctl", O_WRONLY);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1772 if (fd == -1)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1773 return false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1774
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1775 long cmd[] = { PCSET, PR_MSACCT };
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1776 int res = ::write(fd, cmd, sizeof(long) * 2);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1777 ::close(fd);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1778 if (res != sizeof(long) * 2)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1779 return false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1780
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1781 return true;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1782 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1783
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1784 bool os::vtime_enabled() {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1785 int fd = ::open("/proc/self/status", O_RDONLY);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1786 if (fd == -1)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1787 return false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1788
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1789 pstatus_t status;
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1790 int res = os::read(fd, (void*) &status, sizeof(pstatus_t));
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1791 ::close(fd);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1792 if (res != sizeof(pstatus_t))
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1793 return false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1794
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1795 return status.pr_flags & PR_MSACCT;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1796 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1797
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1798 double os::elapsedVTime() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1799 return (double)gethrvtime() / (double)hrtime_hz;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1800 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1801
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 // Used internally for comparisons only
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 // getTimeMillis guaranteed to not move backwards on Solaris
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 jlong getTimeMillis() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 jlong nanotime = getTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 return (jlong)(nanotime / NANOSECS_PER_MILLISECS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1808
61
5a76ab815e34 6667833: Remove CacheTimeMillis
sbohne
parents: 60
diff changeset
1809 // Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
5a76ab815e34 6667833: Remove CacheTimeMillis
sbohne
parents: 60
diff changeset
1810 jlong os::javaTimeMillis() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 timeval t;
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 if (gettimeofday( &t, NULL) == -1)
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
1813 fatal(err_msg("os::javaTimeMillis: gettimeofday (%s)", strerror(errno)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 return jlong(t.tv_sec) * 1000 + jlong(t.tv_usec) / 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1816
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 jlong os::javaTimeNanos() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 return (jlong)getTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1820
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 info_ptr->max_value = ALL_64_BITS; // gethrtime() uses all 64 bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 info_ptr->may_skip_backward = false; // not subject to resetting or drifting
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 info_ptr->may_skip_forward = false; // not subject to resetting or drifting
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1827
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 char * os::local_time_string(char *buf, size_t buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 struct tm t;
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 time_t long_time;
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 time(&long_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 localtime_r(&long_time, &t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 t.tm_hour, t.tm_min, t.tm_sec);
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 return buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1838
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 // Note: os::shutdown() might be called very early during initialization, or
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 // called from signal handler. Before adding something to os::shutdown(), make
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 // sure it is async-safe and can handle partially initialized VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 void os::shutdown() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1843
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 // allow PerfMemory to attempt cleanup of any persistent resources
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 perfMemory_exit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1846
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 // needs to remove object in file system
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 AttachListener::abort();
a61af66fc99e Initial load
duke
parents:
diff changeset
1849
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 // flush buffered output, finish log files
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 ostream_abort();
a61af66fc99e Initial load
duke
parents:
diff changeset
1852
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 // Check for abort hook
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 abort_hook_t abort_hook = Arguments::abort_hook();
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 if (abort_hook != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 abort_hook();
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1859
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 // Note: os::abort() might be called very early during initialization, or
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 // called from signal handler. Before adding something to os::abort(), make
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 // sure it is async-safe and can handle partially initialized VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 void os::abort(bool dump_core) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 os::shutdown();
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 if (dump_core) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 fdStream out(defaultStream::output_fd());
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 out.print_raw("Current thread is ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 char buf[16];
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 out.print_raw_cr(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 out.print_raw_cr("Dumping core ...");
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 ::abort(); // dump core (for debugging)
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1876
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 ::exit(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1879
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 // Die immediately, no exit hook, no abort hook, no cleanup.
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 void os::die() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 _exit(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1884
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 // unused
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 void os::set_error_file(const char *logfile) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
1887
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 // DLL functions
a61af66fc99e Initial load
duke
parents:
diff changeset
1889
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 const char* os::dll_file_extension() { return ".so"; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1891
2130
34d64ad817f4 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 2102
diff changeset
1892 // This must be hard coded because it's the system's temporary
34d64ad817f4 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 2102
diff changeset
1893 // directory not the java application's temp directory, ala java.io.tmpdir.
34d64ad817f4 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 2102
diff changeset
1894 const char* os::get_temp_directory() { return "/tmp"; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1895
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1896 static bool file_exists(const char* filename) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1897 struct stat statbuf;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1898 if (filename == NULL || strlen(filename) == 0) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1899 return false;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1900 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1901 return os::stat(filename, &statbuf) == 0;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1902 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1903
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1904 void os::dll_build_name(char* buffer, size_t buflen,
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1905 const char* pname, const char* fname) {
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1906 const size_t pnamelen = pname ? strlen(pname) : 0;
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1907
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1908 // Quietly truncate on buffer overflow. Should be an error.
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1909 if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1910 *buffer = '\0';
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1911 return;
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1912 }
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1913
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1914 if (pnamelen == 0) {
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1915 snprintf(buffer, buflen, "lib%s.so", fname);
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1916 } else if (strchr(pname, *os::path_separator()) != NULL) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1917 int n;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1918 char** pelements = split_path(pname, &n);
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1919 for (int i = 0 ; i < n ; i++) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1920 // really shouldn't be NULL but what the heck, check can't hurt
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1921 if (pelements[i] == NULL || strlen(pelements[i]) == 0) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1922 continue; // skip the empty path values
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1923 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1924 snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname);
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1925 if (file_exists(buffer)) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1926 break;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1927 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1928 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1929 // release the storage
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1930 for (int i = 0 ; i < n ; i++) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1931 if (pelements[i] != NULL) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1932 FREE_C_HEAP_ARRAY(char, pelements[i]);
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1933 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1934 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1935 if (pelements != NULL) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1936 FREE_C_HEAP_ARRAY(char*, pelements);
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1937 }
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1938 } else {
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1939 snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1940 }
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1941 }
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1942
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 const char* os::get_current_directory(char *buf, int buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 return getcwd(buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1946
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 // check if addr is inside libjvm[_g].so
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 bool os::address_is_in_vm(address addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 static address libjvm_base_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1951
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 if (libjvm_base_addr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 libjvm_base_addr = (address)dlinfo.dli_fbase;
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1957
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 if (dladdr((void *)addr, &dlinfo)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1961
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1964
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 typedef int (*dladdr1_func_type) (void *, Dl_info *, void **, int);
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 static dladdr1_func_type dladdr1_func = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1967
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 bool os::dll_address_to_function_name(address addr, char *buf,
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 int buflen, int * offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1971
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 // dladdr1_func was initialized in os::init()
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 if (dladdr1_func){
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 // yes, we have dladdr1
a61af66fc99e Initial load
duke
parents:
diff changeset
1975
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 // Support for dladdr1 is checked at runtime; it may be
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 // available even if the vm is built on a machine that does
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 // not have dladdr1 support. Make sure there is a value for
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 // RTLD_DL_SYMENT.
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 #ifndef RTLD_DL_SYMENT
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 #define RTLD_DL_SYMENT 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 #endif
2259
2a57c59eb548 7018101: os::dll_address_to_function_name returning wrong answers in 64 bit
never
parents: 2130
diff changeset
1983 #ifdef _LP64
2a57c59eb548 7018101: os::dll_address_to_function_name returning wrong answers in 64 bit
never
parents: 2130
diff changeset
1984 Elf64_Sym * info;
2a57c59eb548 7018101: os::dll_address_to_function_name returning wrong answers in 64 bit
never
parents: 2130
diff changeset
1985 #else
2a57c59eb548 7018101: os::dll_address_to_function_name returning wrong answers in 64 bit
never
parents: 2130
diff changeset
1986 Elf32_Sym * info;
2a57c59eb548 7018101: os::dll_address_to_function_name returning wrong answers in 64 bit
never
parents: 2130
diff changeset
1987 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 if (dladdr1_func((void *)addr, &dlinfo, (void **)&info,
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 RTLD_DL_SYMENT)) {
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1990 if ((char *)dlinfo.dli_saddr + info->st_size > (char *)addr) {
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1991 if (buf != NULL) {
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1992 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen))
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1993 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1994 }
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1995 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1996 return true;
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1997 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 }
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1999 if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2000 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2001 dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2002 return true;
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2003 }
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2004 }
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2005 if (buf != NULL) buf[0] = '\0';
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2006 if (offset != NULL) *offset = -1;
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2007 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 // no, only dladdr is available
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2010 if (dladdr((void *)addr, &dlinfo)) {
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2011 if (buf != NULL) {
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2012 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen))
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2013 jio_snprintf(buf, buflen, dlinfo.dli_sname);
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2014 }
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2015 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2016 return true;
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2017 } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2018 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2019 dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 return true;
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2021 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 }
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2023 if (buf != NULL) buf[0] = '\0';
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2024 if (offset != NULL) *offset = -1;
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
2025 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2028
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 bool os::dll_address_to_library_name(address addr, char* buf,
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 int buflen, int* offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
2032
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 if (dladdr((void*)addr, &dlinfo)){
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 if (offset) *offset = addr - (address)dlinfo.dli_fbase;
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 if (buf) buf[0] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 if (offset) *offset = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2043
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 // Prints the names and full paths of all opened dynamic libraries
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 // for current process
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 void os::print_dll_info(outputStream * st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 Dl_info dli;
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 void *handle;
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 Link_map *map;
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 Link_map *p;
a61af66fc99e Initial load
duke
parents:
diff changeset
2051
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 st->print_cr("Dynamic libraries:"); st->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
2053
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 if (!dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 st->print_cr("Error: Cannot print dynamic libraries.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 handle = dlopen(dli.dli_fname, RTLD_LAZY);
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 if (handle == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 st->print_cr("Error: Cannot print dynamic libraries.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 dlinfo(handle, RTLD_DI_LINKMAP, &map);
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 if (map == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 st->print_cr("Error: Cannot print dynamic libraries.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2068
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 while (map->l_prev != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 map = map->l_prev;
a61af66fc99e Initial load
duke
parents:
diff changeset
2071
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 while (map != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 map = map->l_next;
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2076
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 dlclose(handle);
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2079
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 // Loads .dll/.so and
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 // in case of error it checks if .dll/.so was built for the
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 // same architecture as Hotspot is running on
a61af66fc99e Initial load
duke
parents:
diff changeset
2083
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 void * result= ::dlopen(filename, RTLD_LAZY);
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 if (result != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 // Successful loading
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2091
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 Elf32_Ehdr elf_head;
a61af66fc99e Initial load
duke
parents:
diff changeset
2093
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 // Read system error message into ebuf
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 // It may or may not be overwritten below
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 ::strncpy(ebuf, ::dlerror(), ebuflen-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 ebuf[ebuflen-1]='\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 int diag_msg_max_length=ebuflen-strlen(ebuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 char* diag_msg_buf=ebuf+strlen(ebuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2100
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 if (diag_msg_max_length==0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 // No more space in ebuf for additional diagnostics message
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2105
a61af66fc99e Initial load
duke
parents:
diff changeset
2106
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK);
a61af66fc99e Initial load
duke
parents:
diff changeset
2108
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 if (file_descriptor < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 // Can't open library, report dlerror() message
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2113
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 bool failed_to_read_elf_head=
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 (sizeof(elf_head)!=
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 (::read(file_descriptor, &elf_head,sizeof(elf_head)))) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
2117
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 ::close(file_descriptor);
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 if (failed_to_read_elf_head) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 // file i/o error - report dlerror() msg
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2123
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 typedef struct {
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 Elf32_Half code; // Actual value as defined in elf.h
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 Elf32_Half compat_class; // Compatibility of archs at VM's sense
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 char elf_class; // 32 or 64 bit
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 char endianess; // MSB or LSB
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 char* name; // String representation
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 } arch_t;
a61af66fc99e Initial load
duke
parents:
diff changeset
2131
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 static const arch_t arch_array[]={
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 {EM_386, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 {EM_486, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 {EM_IA_64, EM_IA_64, ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"},
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 {EM_X86_64, EM_X86_64, ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"},
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 {EM_SPARC, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 {EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 {EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"},
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 {EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2141 {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2142 {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM 32"}
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2144
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 #if (defined IA32)
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 static Elf32_Half running_arch_code=EM_386;
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 #elif (defined AMD64)
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 static Elf32_Half running_arch_code=EM_X86_64;
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 #elif (defined IA64)
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 static Elf32_Half running_arch_code=EM_IA_64;
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 #elif (defined __sparc) && (defined _LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 static Elf32_Half running_arch_code=EM_SPARCV9;
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 #elif (defined __sparc) && (!defined _LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 static Elf32_Half running_arch_code=EM_SPARC;
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 #elif (defined __powerpc64__)
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 static Elf32_Half running_arch_code=EM_PPC64;
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 #elif (defined __powerpc__)
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 static Elf32_Half running_arch_code=EM_PPC;
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2159 #elif (defined ARM)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2160 static Elf32_Half running_arch_code=EM_ARM;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 #error Method os::dll_load requires that one of following is defined:\
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2163 IA32, AMD64, IA64, __sparc, __powerpc__, ARM, ARM
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2165
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 // Identify compatability class for VM's architecture and library's architecture
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 // Obtain string descriptions for architectures
a61af66fc99e Initial load
duke
parents:
diff changeset
2168
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL};
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 int running_arch_index=-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2171
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 for (unsigned int i=0 ; i < ARRAY_SIZE(arch_array) ; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 if (running_arch_code == arch_array[i].code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 running_arch_index = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 if (lib_arch.code == arch_array[i].code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 lib_arch.compat_class = arch_array[i].compat_class;
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 lib_arch.name = arch_array[i].name;
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2181
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 assert(running_arch_index != -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 "Didn't find running architecture code (running_arch_code) in arch_array");
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 if (running_arch_index == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 // Even though running architecture detection failed
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 // we may still continue with reporting dlerror() message
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2189
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 if (lib_arch.endianess != arch_array[running_arch_index].endianess) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)");
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2194
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2199
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 if ( lib_arch.name!=NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 ::snprintf(diag_msg_buf, diag_msg_max_length-1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 " (Possible cause: can't load %s-bit .so on a %s-bit platform)",
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 lib_arch.name, arch_array[running_arch_index].name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 ::snprintf(diag_msg_buf, diag_msg_max_length-1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 " (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)",
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 lib_arch.code,
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 arch_array[running_arch_index].name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2212
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2215
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
2216 void* os::dll_lookup(void* handle, const char* name) {
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
2217 return dlsym(handle, name);
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
2218 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2219
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2220 int os::stat(const char *path, struct stat *sbuf) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2221 char pathbuf[MAX_PATH];
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2222 if (strlen(path) > MAX_PATH - 1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2223 errno = ENAMETOOLONG;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2224 return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2225 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2226 os::native_path(strcpy(pathbuf, path));
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2227 return ::stat(pathbuf, sbuf);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2228 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2229
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2230 static bool _print_ascii_file(const char* filename, outputStream* st) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2231 int fd = ::open(filename, O_RDONLY);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 if (fd == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2235
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 char buf[32];
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 int bytes;
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2238 while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 st->print_raw(buf, bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2241
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2242 ::close(fd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2243
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2246
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 void os::print_os_info(outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 st->print("OS:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2249
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 if (!_print_ascii_file("/etc/release", st)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 st->print("Solaris");
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2254
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 // kernel
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 st->print("uname:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 struct utsname name;
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 uname(&name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 st->print(name.sysname); st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 st->print(name.release); st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 st->print(name.version); st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 st->print(name.machine);
a61af66fc99e Initial load
duke
parents:
diff changeset
2263
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 // libthread
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 if (os::Solaris::T2_libthread()) st->print(" (T2 libthread)");
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 else st->print(" (T1 libthread)");
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2268
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 // rlimit
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 st->print("rlimit:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 struct rlimit rlim;
a61af66fc99e Initial load
duke
parents:
diff changeset
2272
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 st->print(" STACK ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 getrlimit(RLIMIT_STACK, &rlim);
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 else st->print("%uk", rlim.rlim_cur >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2277
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 st->print(", CORE ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 getrlimit(RLIMIT_CORE, &rlim);
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 else st->print("%uk", rlim.rlim_cur >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2282
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 st->print(", NOFILE ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 getrlimit(RLIMIT_NOFILE, &rlim);
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 else st->print("%d", rlim.rlim_cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
2287
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 st->print(", AS ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 getrlimit(RLIMIT_AS, &rlim);
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 else st->print("%uk", rlim.rlim_cur >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2293
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 // load average
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 st->print("load average:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 double loadavg[3];
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 os::loadavg(loadavg, 3);
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2301
a61af66fc99e Initial load
duke
parents:
diff changeset
2302
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 static bool check_addr0(outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 jboolean status = false;
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2305 int fd = ::open("/proc/self/map",O_RDONLY);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 if (fd >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 prmap_t p;
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2308 while(::read(fd, &p, sizeof(p)) > 0) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 if (p.pr_vaddr == 0x0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 st->print("Warning: Address: 0x%x, Size: %dK, ",p.pr_vaddr, p.pr_size/1024, p.pr_mapname);
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 st->print("Mapped file: %s, ", p.pr_mapname[0] == '\0' ? "None" : p.pr_mapname);
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 st->print("Access:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 st->print("%s",(p.pr_mflags & MA_READ) ? "r" : "-");
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 st->print("%s",(p.pr_mflags & MA_WRITE) ? "w" : "-");
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 st->print("%s",(p.pr_mflags & MA_EXEC) ? "x" : "-");
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 status = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 }
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2319 ::close(fd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 return status;
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2324
3800
bf6481e5f96d 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 3318
diff changeset
2325 void os::pd_print_cpu_info(outputStream* st) {
bf6481e5f96d 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 3318
diff changeset
2326 // Nothing to do for now.
bf6481e5f96d 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 3318
diff changeset
2327 }
bf6481e5f96d 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 3318
diff changeset
2328
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 void os::print_memory_info(outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 st->print("Memory:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 st->print(" %dk page", os::vm_page_size()>>10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 st->print(", physical " UINT64_FORMAT "k", os::physical_memory()>>10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 st->print("(" UINT64_FORMAT "k free)", os::available_memory() >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 (void) check_addr0(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2337
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 // Taken from /usr/include/sys/machsig.h Supposed to be architecture specific
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 // but they're the same for all the solaris architectures that we support.
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 const char *ill_names[] = { "ILL0", "ILL_ILLOPC", "ILL_ILLOPN", "ILL_ILLADR",
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 "ILL_ILLTRP", "ILL_PRVOPC", "ILL_PRVREG",
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 "ILL_COPROC", "ILL_BADSTK" };
a61af66fc99e Initial load
duke
parents:
diff changeset
2343
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 const char *fpe_names[] = { "FPE0", "FPE_INTDIV", "FPE_INTOVF", "FPE_FLTDIV",
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 "FPE_FLTOVF", "FPE_FLTUND", "FPE_FLTRES",
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 "FPE_FLTINV", "FPE_FLTSUB" };
a61af66fc99e Initial load
duke
parents:
diff changeset
2347
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 const char *segv_names[] = { "SEGV0", "SEGV_MAPERR", "SEGV_ACCERR" };
a61af66fc99e Initial load
duke
parents:
diff changeset
2349
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 const char *bus_names[] = { "BUS0", "BUS_ADRALN", "BUS_ADRERR", "BUS_OBJERR" };
a61af66fc99e Initial load
duke
parents:
diff changeset
2351
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 void os::print_siginfo(outputStream* st, void* siginfo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 st->print("siginfo:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2354
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 const int buflen = 100;
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 char buf[buflen];
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 siginfo_t *si = (siginfo_t*)siginfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 st->print("si_signo=%s: ", os::exception_name(si->si_signo, buf, buflen));
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 char *err = strerror(si->si_errno);
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 if (si->si_errno != 0 && err != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 st->print("si_errno=%s", err);
a61af66fc99e Initial load
duke
parents:
diff changeset
2362 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 st->print("si_errno=%d", si->si_errno);
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 const int c = si->si_code;
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 assert(c > 0, "unexpected si_code");
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 switch (si->si_signo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 case SIGILL:
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 st->print(", si_code=%d (%s)", c, c > 8 ? "" : ill_names[c]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 st->print(", si_addr=" PTR_FORMAT, si->si_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 case SIGFPE:
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 st->print(", si_code=%d (%s)", c, c > 9 ? "" : fpe_names[c]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 st->print(", si_addr=" PTR_FORMAT, si->si_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 case SIGSEGV:
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 st->print(", si_code=%d (%s)", c, c > 2 ? "" : segv_names[c]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 st->print(", si_addr=" PTR_FORMAT, si->si_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 case SIGBUS:
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 st->print(", si_code=%d (%s)", c, c > 3 ? "" : bus_names[c]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 st->print(", si_addr=" PTR_FORMAT, si->si_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 st->print(", si_code=%d", si->si_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 // no si_addr
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2388
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 if ((si->si_signo == SIGBUS || si->si_signo == SIGSEGV) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 UseSharedSpaces) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 FileMapInfo* mapinfo = FileMapInfo::current_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 if (mapinfo->is_in_shared_space(si->si_addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 st->print("\n\nError accessing class data sharing archive." \
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 " Mapped file inaccessible during execution, " \
a61af66fc99e Initial load
duke
parents:
diff changeset
2395 " possible disk/network problem.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2400
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 // Moved from whole group, because we need them here for diagnostic
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 // prints.
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 #define OLDMAXSIGNUM 32
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 static int Maxsignum = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 static int *ourSigFlags = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2406
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 extern "C" void sigINTRHandler(int, siginfo_t*, void*);
a61af66fc99e Initial load
duke
parents:
diff changeset
2408
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 int os::Solaris::get_our_sigflags(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 assert(ourSigFlags!=NULL, "signal data structure not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 assert(sig > 0 && sig < Maxsignum, "vm signal out of expected range");
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 return ourSigFlags[sig];
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2414
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 void os::Solaris::set_our_sigflags(int sig, int flags) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 assert(ourSigFlags!=NULL, "signal data structure not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 assert(sig > 0 && sig < Maxsignum, "vm signal out of expected range");
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 ourSigFlags[sig] = flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2420
a61af66fc99e Initial load
duke
parents:
diff changeset
2421
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 static const char* get_signal_handler_name(address handler,
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 char* buf, int buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 int offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 bool found = os::dll_address_to_library_name(handler, buf, buflen, &offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 if (found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 // skip directory names
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 const char *p1, *p2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 p1 = buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 size_t len = strlen(os::file_separator());
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len;
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 jio_snprintf(buf, buflen, "%s+0x%x", p1, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 jio_snprintf(buf, buflen, PTR_FORMAT, handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 return buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2438
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 static void print_signal_handler(outputStream* st, int sig,
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 char* buf, size_t buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2441 struct sigaction sa;
a61af66fc99e Initial load
duke
parents:
diff changeset
2442
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 sigaction(sig, NULL, &sa);
a61af66fc99e Initial load
duke
parents:
diff changeset
2444
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 st->print("%s: ", os::exception_name(sig, buf, buflen));
a61af66fc99e Initial load
duke
parents:
diff changeset
2446
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 address handler = (sa.sa_flags & SA_SIGINFO)
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 : CAST_FROM_FN_PTR(address, sa.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2450
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 if (handler == CAST_FROM_FN_PTR(address, SIG_DFL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 st->print("SIG_DFL");
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 } else if (handler == CAST_FROM_FN_PTR(address, SIG_IGN)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 st->print("SIG_IGN");
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 st->print("[%s]", get_signal_handler_name(handler, buf, buflen));
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2458
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 st->print(", sa_mask[0]=" PTR32_FORMAT, *(uint32_t*)&sa.sa_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
2460
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 address rh = VMError::get_resetted_sighandler(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
2462 // May be, handler was resetted by VMError?
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 if(rh != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 handler = rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 sa.sa_flags = VMError::get_resetted_sigflags(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2467
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 st->print(", sa_flags=" PTR32_FORMAT, sa.sa_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
2469
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 // Check: is it our handler?
a61af66fc99e Initial load
duke
parents:
diff changeset
2471 if(handler == CAST_FROM_FN_PTR(address, signalHandler) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 handler == CAST_FROM_FN_PTR(address, sigINTRHandler)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 // It is our signal handler
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 // check for flags
a61af66fc99e Initial load
duke
parents:
diff changeset
2475 if(sa.sa_flags != os::Solaris::get_our_sigflags(sig)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 st->print(
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 ", flags was changed from " PTR32_FORMAT ", consider using jsig library",
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 os::Solaris::get_our_sigflags(sig));
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2483
a61af66fc99e Initial load
duke
parents:
diff changeset
2484 void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 st->print_cr("Signal Handlers:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2486 print_signal_handler(st, SIGSEGV, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 print_signal_handler(st, SIGBUS , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 print_signal_handler(st, SIGFPE , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 print_signal_handler(st, SIGPIPE, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 print_signal_handler(st, SIGXFSZ, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2491 print_signal_handler(st, SIGILL , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 print_signal_handler(st, ASYNC_SIGNAL, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 print_signal_handler(st, BREAK_SIGNAL, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 print_signal_handler(st, SHUTDOWN1_SIGNAL , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2496 print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2497 print_signal_handler(st, SHUTDOWN3_SIGNAL, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 print_signal_handler(st, os::Solaris::SIGinterrupt(), buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 print_signal_handler(st, os::Solaris::SIGasync(), buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2501
a61af66fc99e Initial load
duke
parents:
diff changeset
2502 static char saved_jvm_path[MAXPATHLEN] = { 0 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2503
a61af66fc99e Initial load
duke
parents:
diff changeset
2504 // Find the full path to the current module, libjvm.so or libjvm_g.so
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 void os::jvm_path(char *buf, jint buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 // Error checking.
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 if (buflen < MAXPATHLEN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2508 assert(false, "must use a large-enough buffer");
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 buf[0] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2512 // Lazy resolve the path to current module.
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 if (saved_jvm_path[0] != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2514 strcpy(buf, saved_jvm_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2516 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2517
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 assert(ret != 0, "cannot locate libjvm");
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 realpath((char *)dlinfo.dli_fname, buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2522
2302
da091bb67459 7022037: Pause when exiting if debugger is attached on windows
sla
parents: 2191
diff changeset
2523 if (Arguments::created_by_gamma_launcher()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 // Support for the gamma launcher. Typical value for buf is
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at
a61af66fc99e Initial load
duke
parents:
diff changeset
2526 // the right place in the string, then assume we are installed in a JDK and
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 // we're done. Otherwise, check for a JAVA_HOME environment variable and fix
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 // up the path so it looks like libjvm.so is installed there (append a
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 // fake suffix hotspot/libjvm.so).
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 const char *p = buf + strlen(buf) - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 for (int count = 0; p > buf && count < 5; ++count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 for (--p; p > buf && *p != '/'; --p)
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 /* empty */ ;
a61af66fc99e Initial load
duke
parents:
diff changeset
2534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2535
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 if (strncmp(p, "/jre/lib/", 9) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 // Look for JAVA_HOME in the environment.
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 char* java_home_var = ::getenv("JAVA_HOME");
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 if (java_home_var != NULL && java_home_var[0] != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 char cpu_arch[12];
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2541 char* jrelib_p;
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2542 int len;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 sysinfo(SI_ARCHITECTURE, cpu_arch, sizeof(cpu_arch));
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 // If we are on sparc running a 64-bit vm, look in jre/lib/sparcv9.
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 if (strcmp(cpu_arch, "sparc") == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 strcat(cpu_arch, "v9");
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 } else if (strcmp(cpu_arch, "i386") == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2549 strcpy(cpu_arch, "amd64");
a61af66fc99e Initial load
duke
parents:
diff changeset
2550 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 // Check the current module name "libjvm.so" or "libjvm_g.so".
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 p = strrchr(buf, '/');
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 assert(strstr(p, "/libjvm") == p, "invalid library name");
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 p = strstr(p, "_g") ? "_g" : "";
a61af66fc99e Initial load
duke
parents:
diff changeset
2556
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 realpath(java_home_var, buf);
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2558 // determine if this is a legacy image or modules image
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2559 // modules image doesn't have "jre" subdirectory
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2560 len = strlen(buf);
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2561 jrelib_p = buf + len;
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2562 snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch);
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2563 if (0 != access(buf, F_OK)) {
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2564 snprintf(jrelib_p, buflen-len, "/lib/%s", cpu_arch);
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2565 }
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2566
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 if (0 == access(buf, F_OK)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 // Use current module name "libjvm[_g].so" instead of
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 // "libjvm"debug_only("_g")".so" since for fastdebug version
a61af66fc99e Initial load
duke
parents:
diff changeset
2570 // we should have "libjvm.so" but debug_only("_g") adds "_g"!
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2571 len = strlen(buf);
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2572 snprintf(buf + len, buflen-len, "/hotspot/libjvm%s.so", p);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2574 // Go back to path of .so
a61af66fc99e Initial load
duke
parents:
diff changeset
2575 realpath((char *)dlinfo.dli_fname, buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2576 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2580
a61af66fc99e Initial load
duke
parents:
diff changeset
2581 strcpy(saved_jvm_path, buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2583
a61af66fc99e Initial load
duke
parents:
diff changeset
2584
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 // no prefix required, not even "_"
a61af66fc99e Initial load
duke
parents:
diff changeset
2587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2588
a61af66fc99e Initial load
duke
parents:
diff changeset
2589
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 void os::print_jni_name_suffix_on(outputStream* st, int args_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2591 // no suffix required
a61af66fc99e Initial load
duke
parents:
diff changeset
2592 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2593
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2594 // This method is a copy of JDK's sysGetLastErrorString
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2595 // from src/solaris/hpi/src/system_md.c
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2596
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2597 size_t os::lasterror(char *buf, size_t len) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2598
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2599 if (errno == 0) return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2600
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2601 const char *s = ::strerror(errno);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2602 size_t n = ::strlen(s);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2603 if (n >= len) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2604 n = len - 1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2605 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2606 ::strncpy(buf, s, n);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2607 buf[n] = '\0';
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2608 return n;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2609 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2610
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2611
a61af66fc99e Initial load
duke
parents:
diff changeset
2612 // sun.misc.Signal
a61af66fc99e Initial load
duke
parents:
diff changeset
2613
a61af66fc99e Initial load
duke
parents:
diff changeset
2614 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
2615 static void UserHandler(int sig, void *siginfo, void *context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2616 // Ctrl-C is pressed during error reporting, likely because the error
a61af66fc99e Initial load
duke
parents:
diff changeset
2617 // handler fails to abort. Let VM die immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 if (sig == SIGINT && is_error_reported()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 os::die();
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2621
a61af66fc99e Initial load
duke
parents:
diff changeset
2622 os::signal_notify(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 // We do not need to reinstate the signal handler each time...
a61af66fc99e Initial load
duke
parents:
diff changeset
2624 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2626
a61af66fc99e Initial load
duke
parents:
diff changeset
2627 void* os::user_handler() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 return CAST_FROM_FN_PTR(void*, UserHandler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2630
a61af66fc99e Initial load
duke
parents:
diff changeset
2631 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 typedef void (*sa_handler_t)(int);
a61af66fc99e Initial load
duke
parents:
diff changeset
2633 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
a61af66fc99e Initial load
duke
parents:
diff changeset
2634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2635
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 void* os::signal(int signal_number, void* handler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 struct sigaction sigAct, oldSigAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
2638 sigfillset(&(sigAct.sa_mask));
a61af66fc99e Initial load
duke
parents:
diff changeset
2639 sigAct.sa_flags = SA_RESTART & ~SA_RESETHAND;
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2641
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 if (sigaction(signal_number, &sigAct, &oldSigAct))
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 // -1 means registration failed
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 return (void *)-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2645
a61af66fc99e Initial load
duke
parents:
diff changeset
2646 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2648
a61af66fc99e Initial load
duke
parents:
diff changeset
2649 void os::signal_raise(int signal_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 raise(signal_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2652
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 * The following code is moved from os.cpp for making this
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 * code platform specific, which it is by its very nature.
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 */
a61af66fc99e Initial load
duke
parents:
diff changeset
2657
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 // a counter for each possible signal value
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 static int Sigexit = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 static int Maxlibjsigsigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 static jint *pending_signals = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2662 static int *preinstalled_sigs = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2663 static struct sigaction *chainedsigactions = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2664 static sema_t sig_sem;
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 typedef int (*version_getting_t)();
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 version_getting_t os::Solaris::get_libjsig_version = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2667 static int libjsigversion = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2668
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 int os::sigexitnum_pd() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2670 assert(Sigexit > 0, "signal memory not yet initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 return Sigexit;
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2673
a61af66fc99e Initial load
duke
parents:
diff changeset
2674 void os::Solaris::init_signal_mem() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 // Initialize signal structures
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 Maxsignum = SIGRTMAX;
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 Sigexit = Maxsignum+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 assert(Maxsignum >0, "Unable to obtain max signal number");
a61af66fc99e Initial load
duke
parents:
diff changeset
2679
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 Maxlibjsigsigs = Maxsignum;
a61af66fc99e Initial load
duke
parents:
diff changeset
2681
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 // pending_signals has one int per signal
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 // The additional signal is for SIGEXIT - exit signal to signal_thread
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 pending_signals = (jint *)os::malloc(sizeof(jint) * (Sigexit+1));
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 memset(pending_signals, 0, (sizeof(jint) * (Sigexit+1)));
a61af66fc99e Initial load
duke
parents:
diff changeset
2686
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 if (UseSignalChaining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 chainedsigactions = (struct sigaction *)malloc(sizeof(struct sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 * (Maxsignum + 1));
a61af66fc99e Initial load
duke
parents:
diff changeset
2690 memset(chainedsigactions, 0, (sizeof(struct sigaction) * (Maxsignum + 1)));
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 preinstalled_sigs = (int *)os::malloc(sizeof(int) * (Maxsignum + 1));
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 memset(preinstalled_sigs, 0, (sizeof(int) * (Maxsignum + 1)));
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 ourSigFlags = (int*)malloc(sizeof(int) * (Maxsignum + 1 ));
a61af66fc99e Initial load
duke
parents:
diff changeset
2695 memset(ourSigFlags, 0, sizeof(int) * (Maxsignum + 1));
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2697
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 void os::signal_init_pd() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 int ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
2700
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 ret = ::sema_init(&sig_sem, 0, NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 assert(ret == 0, "sema_init() failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2704
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 void os::signal_notify(int signal_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2706 int ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
2707
a61af66fc99e Initial load
duke
parents:
diff changeset
2708 Atomic::inc(&pending_signals[signal_number]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 ret = ::sema_post(&sig_sem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 assert(ret == 0, "sema_post() failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2711 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2712
a61af66fc99e Initial load
duke
parents:
diff changeset
2713 static int check_pending_signals(bool wait_for_signal) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 int ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
2715 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 for (int i = 0; i < Sigexit + 1; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 jint n = pending_signals[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 return i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2721 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 if (!wait_for_signal) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2725 JavaThread *thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 ThreadBlockInVM tbivm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
2727
a61af66fc99e Initial load
duke
parents:
diff changeset
2728 bool threadIsSuspended;
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
2730 thread->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 while((ret = ::sema_wait(&sig_sem)) == EINTR)
a61af66fc99e Initial load
duke
parents:
diff changeset
2733 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 assert(ret == 0, "sema_wait() failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2735
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 // were we externally suspended while we were waiting?
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
a61af66fc99e Initial load
duke
parents:
diff changeset
2738 if (threadIsSuspended) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2739 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 // The semaphore has been incremented, but while we were waiting
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 // another thread suspended us. We don't want to continue running
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 // while suspended because that would surprise the thread that
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 // suspended us.
a61af66fc99e Initial load
duke
parents:
diff changeset
2744 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 ret = ::sema_post(&sig_sem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 assert(ret == 0, "sema_post() failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2747
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 thread->java_suspend_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 } while (threadIsSuspended);
a61af66fc99e Initial load
duke
parents:
diff changeset
2751 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2753
a61af66fc99e Initial load
duke
parents:
diff changeset
2754 int os::signal_lookup() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2755 return check_pending_signals(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2757
a61af66fc99e Initial load
duke
parents:
diff changeset
2758 int os::signal_wait() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 return check_pending_signals(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2761
a61af66fc99e Initial load
duke
parents:
diff changeset
2762 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 // Virtual Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2764
a61af66fc99e Initial load
duke
parents:
diff changeset
2765 static int page_size = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2766
a61af66fc99e Initial load
duke
parents:
diff changeset
2767 // The mmap MAP_ALIGN flag is supported on Solaris 9 and later. init_2() will
a61af66fc99e Initial load
duke
parents:
diff changeset
2768 // clear this var if support is not available.
a61af66fc99e Initial load
duke
parents:
diff changeset
2769 static bool has_map_align = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2770
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 int os::vm_page_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2772 assert(page_size != -1, "must call os::init");
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 return page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2775
a61af66fc99e Initial load
duke
parents:
diff changeset
2776 // Solaris allocates memory by pages.
a61af66fc99e Initial load
duke
parents:
diff changeset
2777 int os::vm_allocation_granularity() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 assert(page_size != -1, "must call os::init");
a61af66fc99e Initial load
duke
parents:
diff changeset
2779 return page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
2780 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2781
656
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2782 bool os::commit_memory(char* addr, size_t bytes, bool exec) {
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2783 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2784 size_t size = bytes;
3885
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
2785 char *res = Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot);
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
2786 if (res != NULL) {
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
2787 if (UseNUMAInterleaving) {
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
2788 numa_make_global(addr, bytes);
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
2789 }
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
2790 return true;
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
2791 }
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
2792 return false;
656
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2793 }
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2794
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2795 bool os::commit_memory(char* addr, size_t bytes, size_t alignment_hint,
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2796 bool exec) {
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2797 if (commit_memory(addr, bytes, exec)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2798 if (UseMPSS && alignment_hint > (size_t)vm_page_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2799 // If the large page size has been set and the VM
a61af66fc99e Initial load
duke
parents:
diff changeset
2800 // is using large pages, use the large page size
a61af66fc99e Initial load
duke
parents:
diff changeset
2801 // if it is smaller than the alignment hint. This is
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 // a case where the VM wants to use a larger alignment size
a61af66fc99e Initial load
duke
parents:
diff changeset
2803 // for its own reasons but still want to use large pages
a61af66fc99e Initial load
duke
parents:
diff changeset
2804 // (which is what matters to setting the mpss range.
a61af66fc99e Initial load
duke
parents:
diff changeset
2805 size_t page_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2806 if (large_page_size() < alignment_hint) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2807 assert(UseLargePages, "Expected to be here for large page use only");
a61af66fc99e Initial load
duke
parents:
diff changeset
2808 page_size = large_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2810 // If the alignment hint is less than the large page
a61af66fc99e Initial load
duke
parents:
diff changeset
2811 // size, the VM wants a particular alignment (thus the hint)
a61af66fc99e Initial load
duke
parents:
diff changeset
2812 // for internal reasons. Try to set the mpss range using
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 // the alignment_hint.
a61af66fc99e Initial load
duke
parents:
diff changeset
2814 page_size = alignment_hint;
a61af66fc99e Initial load
duke
parents:
diff changeset
2815 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2816 // Since this is a hint, ignore any failures.
a61af66fc99e Initial load
duke
parents:
diff changeset
2817 (void)Solaris::set_mpss_range(addr, bytes, page_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2818 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2819 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2820 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2821 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2822 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2823
a61af66fc99e Initial load
duke
parents:
diff changeset
2824 // Uncommit the pages in a specified region.
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 void os::free_memory(char* addr, size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2826 if (madvise(addr, bytes, MADV_FREE) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2827 debug_only(warning("MADV_FREE failed."));
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2829 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2831
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2832 bool os::create_stack_guard_pages(char* addr, size_t size) {
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2833 return os::commit_memory(addr, size);
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2834 }
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2835
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2836 bool os::remove_stack_guard_pages(char* addr, size_t size) {
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2837 return os::uncommit_memory(addr, size);
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2838 }
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2839
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2840 // Change the page size in a given range.
a61af66fc99e Initial load
duke
parents:
diff changeset
2841 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2843 assert((intptr_t)(addr + bytes) % alignment_hint == 0, "End should be aligned.");
3292
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
2844 if (UseLargePages && UseMPSS) {
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
2845 Solaris::set_mpss_range(addr, bytes, alignment_hint);
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
2846 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2847 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2848
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 // Tell the OS to make the range local to the first-touching LWP
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 89
diff changeset
2850 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2851 assert((intptr_t)addr % os::vm_page_size() == 0, "Address should be page-aligned.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 if (madvise(addr, bytes, MADV_ACCESS_LWP) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 debug_only(warning("MADV_ACCESS_LWP failed."));
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2856
a61af66fc99e Initial load
duke
parents:
diff changeset
2857 // Tell the OS that this range would be accessed from different LWPs.
a61af66fc99e Initial load
duke
parents:
diff changeset
2858 void os::numa_make_global(char *addr, size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 assert((intptr_t)addr % os::vm_page_size() == 0, "Address should be page-aligned.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2860 if (madvise(addr, bytes, MADV_ACCESS_MANY) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2861 debug_only(warning("MADV_ACCESS_MANY failed."));
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2864
a61af66fc99e Initial load
duke
parents:
diff changeset
2865 // Get the number of the locality groups.
a61af66fc99e Initial load
duke
parents:
diff changeset
2866 size_t os::numa_get_groups_num() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2867 size_t n = Solaris::lgrp_nlgrps(Solaris::lgrp_cookie());
a61af66fc99e Initial load
duke
parents:
diff changeset
2868 return n != -1 ? n : 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2869 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2870
a61af66fc99e Initial load
duke
parents:
diff changeset
2871 // Get a list of leaf locality groups. A leaf lgroup is group that
a61af66fc99e Initial load
duke
parents:
diff changeset
2872 // doesn't have any children. Typical leaf group is a CPU or a CPU/memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2873 // board. An LWP is assigned to one of these groups upon creation.
a61af66fc99e Initial load
duke
parents:
diff changeset
2874 size_t os::numa_get_leaf_groups(int *ids, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2875 if ((ids[0] = Solaris::lgrp_root(Solaris::lgrp_cookie())) == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2876 ids[0] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2877 return 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2878 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2879 int result_size = 0, top = 1, bottom = 0, cur = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2880 for (int k = 0; k < size; k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2881 int r = Solaris::lgrp_children(Solaris::lgrp_cookie(), ids[cur],
a61af66fc99e Initial load
duke
parents:
diff changeset
2882 (Solaris::lgrp_id_t*)&ids[top], size - top);
a61af66fc99e Initial load
duke
parents:
diff changeset
2883 if (r == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2884 ids[0] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 return 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2886 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2887 if (!r) {
144
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2888 // That's a leaf node.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 assert (bottom <= cur, "Sanity check");
144
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2890 // Check if the node has memory
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2891 if (Solaris::lgrp_resources(Solaris::lgrp_cookie(), ids[cur],
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2892 NULL, 0, LGRP_RSRC_MEM) > 0) {
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2893 ids[bottom++] = ids[cur];
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2894 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2895 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 top += r;
a61af66fc99e Initial load
duke
parents:
diff changeset
2897 cur++;
a61af66fc99e Initial load
duke
parents:
diff changeset
2898 }
268
d6340ab4105b 6723228: NUMA allocator: assert(lgrp_id != -1, "No lgrp_id set")
iveresov
parents: 267
diff changeset
2899 if (bottom == 0) {
d6340ab4105b 6723228: NUMA allocator: assert(lgrp_id != -1, "No lgrp_id set")
iveresov
parents: 267
diff changeset
2900 // Handle a situation, when the OS reports no memory available.
d6340ab4105b 6723228: NUMA allocator: assert(lgrp_id != -1, "No lgrp_id set")
iveresov
parents: 267
diff changeset
2901 // Assume UMA architecture.
d6340ab4105b 6723228: NUMA allocator: assert(lgrp_id != -1, "No lgrp_id set")
iveresov
parents: 267
diff changeset
2902 ids[0] = 0;
d6340ab4105b 6723228: NUMA allocator: assert(lgrp_id != -1, "No lgrp_id set")
iveresov
parents: 267
diff changeset
2903 return 1;
d6340ab4105b 6723228: NUMA allocator: assert(lgrp_id != -1, "No lgrp_id set")
iveresov
parents: 267
diff changeset
2904 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2905 return bottom;
a61af66fc99e Initial load
duke
parents:
diff changeset
2906 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2907
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
2908 // Detect the topology change. Typically happens during CPU plugging-unplugging.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 bool os::numa_topology_changed() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2910 int is_stale = Solaris::lgrp_cookie_stale(Solaris::lgrp_cookie());
a61af66fc99e Initial load
duke
parents:
diff changeset
2911 if (is_stale != -1 && is_stale) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 Solaris::lgrp_fini(Solaris::lgrp_cookie());
a61af66fc99e Initial load
duke
parents:
diff changeset
2913 Solaris::lgrp_cookie_t c = Solaris::lgrp_init(Solaris::LGRP_VIEW_CALLER);
a61af66fc99e Initial load
duke
parents:
diff changeset
2914 assert(c != 0, "Failure to initialize LGRP API");
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 Solaris::set_lgrp_cookie(c);
a61af66fc99e Initial load
duke
parents:
diff changeset
2916 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2917 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2920
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 // Get the group id of the current LWP.
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 int os::numa_get_group_id() {
144
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2923 int lgrp_id = Solaris::lgrp_home(P_LWPID, P_MYID);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 if (lgrp_id == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 }
144
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2927 const int size = os::numa_get_groups_num();
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2928 int *ids = (int*)alloca(size * sizeof(int));
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2929
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2930 // Get the ids of all lgroups with memory; r is the count.
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2931 int r = Solaris::lgrp_resources(Solaris::lgrp_cookie(), lgrp_id,
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2932 (Solaris::lgrp_id_t*)ids, size, LGRP_RSRC_MEM);
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2933 if (r <= 0) {
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2934 return 0;
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2935 }
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2936 return ids[os::random() % r];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2938
a61af66fc99e Initial load
duke
parents:
diff changeset
2939 // Request information about the page.
a61af66fc99e Initial load
duke
parents:
diff changeset
2940 bool os::get_page_info(char *start, page_info* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2941 const uint_t info_types[] = { MEMINFO_VLGRP, MEMINFO_VPAGESIZE };
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 uint64_t addr = (uintptr_t)start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2943 uint64_t outdata[2];
a61af66fc99e Initial load
duke
parents:
diff changeset
2944 uint_t validity = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2945
a61af66fc99e Initial load
duke
parents:
diff changeset
2946 if (os::Solaris::meminfo(&addr, 1, info_types, 2, outdata, &validity) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2947 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2949
a61af66fc99e Initial load
duke
parents:
diff changeset
2950 info->size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2951 info->lgrp_id = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2952
a61af66fc99e Initial load
duke
parents:
diff changeset
2953 if ((validity & 1) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2954 if ((validity & 2) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 info->lgrp_id = outdata[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2957 if ((validity & 4) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2958 info->size = outdata[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2960 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2964
a61af66fc99e Initial load
duke
parents:
diff changeset
2965 // Scan the pages from start to end until a page different than
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 // the one described in the info parameter is encountered.
a61af66fc99e Initial load
duke
parents:
diff changeset
2967 char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2968 const uint_t info_types[] = { MEMINFO_VLGRP, MEMINFO_VPAGESIZE };
a61af66fc99e Initial load
duke
parents:
diff changeset
2969 const size_t types = sizeof(info_types) / sizeof(info_types[0]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 uint64_t addrs[MAX_MEMINFO_CNT], outdata[types * MAX_MEMINFO_CNT];
a61af66fc99e Initial load
duke
parents:
diff changeset
2971 uint_t validity[MAX_MEMINFO_CNT];
a61af66fc99e Initial load
duke
parents:
diff changeset
2972
a61af66fc99e Initial load
duke
parents:
diff changeset
2973 size_t page_size = MAX2((size_t)os::vm_page_size(), page_expected->size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2974 uint64_t p = (uint64_t)start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2975 while (p < (uint64_t)end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2976 addrs[0] = p;
a61af66fc99e Initial load
duke
parents:
diff changeset
2977 size_t addrs_count = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2978 while (addrs_count < MAX_MEMINFO_CNT && addrs[addrs_count - 1] < (uint64_t)end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2979 addrs[addrs_count] = addrs[addrs_count - 1] + page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
2980 addrs_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
2981 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2982
a61af66fc99e Initial load
duke
parents:
diff changeset
2983 if (os::Solaris::meminfo(addrs, addrs_count, info_types, types, outdata, validity) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2984 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2985 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2986
a61af66fc99e Initial load
duke
parents:
diff changeset
2987 size_t i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2988 for (; i < addrs_count; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2989 if ((validity[i] & 1) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2990 if ((validity[i] & 4) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2991 if (outdata[types * i + 1] != page_expected->size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2992 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2993 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2994 } else
a61af66fc99e Initial load
duke
parents:
diff changeset
2995 if (page_expected->size != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2996 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2997 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2998
a61af66fc99e Initial load
duke
parents:
diff changeset
2999 if ((validity[i] & 2) != 0 && page_expected->lgrp_id > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3000 if (outdata[types * i] != page_expected->lgrp_id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3001 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3002 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3003 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3004 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3006 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3007 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3008
a61af66fc99e Initial load
duke
parents:
diff changeset
3009 if (i != addrs_count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3010 if ((validity[i] & 2) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3011 page_found->lgrp_id = outdata[types * i];
a61af66fc99e Initial load
duke
parents:
diff changeset
3012 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3013 page_found->lgrp_id = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3014 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 if ((validity[i] & 4) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3016 page_found->size = outdata[types * i + 1];
a61af66fc99e Initial load
duke
parents:
diff changeset
3017 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3018 page_found->size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3019 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 return (char*)addrs[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
3021 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3022
a61af66fc99e Initial load
duke
parents:
diff changeset
3023 p = addrs[addrs_count - 1] + page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3024 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3025 return end;
a61af66fc99e Initial load
duke
parents:
diff changeset
3026 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3027
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 bool os::uncommit_memory(char* addr, size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 size_t size = bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 // Map uncommitted pages PROT_NONE so we fail early if we touch an
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 // uncommitted page. Otherwise, the read/write might succeed if we
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 // have enough swap space to back the physical page.
a61af66fc99e Initial load
duke
parents:
diff changeset
3033 return
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 NULL != Solaris::mmap_chunk(addr, size,
a61af66fc99e Initial load
duke
parents:
diff changeset
3035 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE,
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 PROT_NONE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3038
a61af66fc99e Initial load
duke
parents:
diff changeset
3039 char* os::Solaris::mmap_chunk(char *addr, size_t size, int flags, int prot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3040 char *b = (char *)mmap(addr, size, prot, flags, os::Solaris::_dev_zero_fd, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3041
a61af66fc99e Initial load
duke
parents:
diff changeset
3042 if (b == MAP_FAILED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 return b;
a61af66fc99e Initial load
duke
parents:
diff changeset
3046 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3047
60
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3048 char* os::Solaris::anon_mmap(char* requested_addr, size_t bytes, size_t alignment_hint, bool fixed) {
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3049 char* addr = requested_addr;
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3050 int flags = MAP_PRIVATE | MAP_NORESERVE;
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3051
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3052 assert(!(fixed && (alignment_hint > 0)), "alignment hint meaningless with fixed mmap");
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3053
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3054 if (fixed) {
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3055 flags |= MAP_FIXED;
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3056 } else if (has_map_align && (alignment_hint > (size_t) vm_page_size())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3057 flags |= MAP_ALIGN;
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 addr = (char*) alignment_hint;
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3060
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 // Map uncommitted pages PROT_NONE so we fail early if we touch an
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 // uncommitted page. Otherwise, the read/write might succeed if we
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 // have enough swap space to back the physical page.
60
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3064 return mmap_chunk(addr, bytes, flags, PROT_NONE);
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3065 }
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3066
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3067 char* os::reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3068 char* addr = Solaris::anon_mmap(requested_addr, bytes, alignment_hint, (requested_addr != NULL));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3069
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 guarantee(requested_addr == NULL || requested_addr == addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 "OS failed to return requested mmap address.");
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 return addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3073 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3074
a61af66fc99e Initial load
duke
parents:
diff changeset
3075 // Reserve memory at an arbitrary address, only if that area is
a61af66fc99e Initial load
duke
parents:
diff changeset
3076 // available (and not reserved for something else).
a61af66fc99e Initial load
duke
parents:
diff changeset
3077
a61af66fc99e Initial load
duke
parents:
diff changeset
3078 char* os::attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3079 const int max_tries = 10;
a61af66fc99e Initial load
duke
parents:
diff changeset
3080 char* base[max_tries];
a61af66fc99e Initial load
duke
parents:
diff changeset
3081 size_t size[max_tries];
a61af66fc99e Initial load
duke
parents:
diff changeset
3082
a61af66fc99e Initial load
duke
parents:
diff changeset
3083 // Solaris adds a gap between mmap'ed regions. The size of the gap
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 // is dependent on the requested size and the MMU. Our initial gap
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 // value here is just a guess and will be corrected later.
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 bool had_top_overlap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3087 bool have_adjusted_gap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 size_t gap = 0x400000;
a61af66fc99e Initial load
duke
parents:
diff changeset
3089
a61af66fc99e Initial load
duke
parents:
diff changeset
3090 // Assert only that the size is a multiple of the page size, since
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 // that's all that mmap requires, and since that's all we really know
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 // about at this low abstraction level. If we need higher alignment,
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 // we can either pass an alignment to this method or verify alignment
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 // in one of the methods further up the call chain. See bug 5044738.
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
a61af66fc99e Initial load
duke
parents:
diff changeset
3096
60
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3097 // Since snv_84, Solaris attempts to honor the address hint - see 5003415.
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3098 // Give it a try, if the kernel honors the hint we can return immediately.
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3099 char* addr = Solaris::anon_mmap(requested_addr, bytes, 0, false);
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3100 volatile int err = errno;
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3101 if (addr == requested_addr) {
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3102 return addr;
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3103 } else if (addr != NULL) {
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3104 unmap_memory(addr, bytes);
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3105 }
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3106
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3107 if (PrintMiscellaneous && Verbose) {
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3108 char buf[256];
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3109 buf[0] = '\0';
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3110 if (addr == NULL) {
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3111 jio_snprintf(buf, sizeof(buf), ": %s", strerror(err));
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3112 }
2080
c04052fd6ae1 7006505: Use kstat info to identify SPARC processor
kvn
parents: 1980
diff changeset
3113 warning("attempt_reserve_memory_at: couldn't reserve " SIZE_FORMAT " bytes at "
60
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3114 PTR_FORMAT ": reserve_memory_helper returned " PTR_FORMAT
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3115 "%s", bytes, requested_addr, addr, buf);
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3116 }
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3117
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3118 // Address hint method didn't work. Fall back to the old method.
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3119 // In theory, once SNV becomes our oldest supported platform, this
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3120 // code will no longer be needed.
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3121 //
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3122 // Repeatedly allocate blocks until the block is allocated at the
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 // right spot. Give up after max_tries.
a61af66fc99e Initial load
duke
parents:
diff changeset
3124 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 for (i = 0; i < max_tries; ++i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3126 base[i] = reserve_memory(bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3127
a61af66fc99e Initial load
duke
parents:
diff changeset
3128 if (base[i] != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3129 // Is this the block we wanted?
a61af66fc99e Initial load
duke
parents:
diff changeset
3130 if (base[i] == requested_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3131 size[i] = bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3132 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3134
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 // check that the gap value is right
a61af66fc99e Initial load
duke
parents:
diff changeset
3136 if (had_top_overlap && !have_adjusted_gap) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 size_t actual_gap = base[i-1] - base[i] - bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3138 if (gap != actual_gap) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3139 // adjust the gap value and retry the last 2 allocations
a61af66fc99e Initial load
duke
parents:
diff changeset
3140 assert(i > 0, "gap adjustment code problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
3141 have_adjusted_gap = true; // adjust the gap only once, just in case
a61af66fc99e Initial load
duke
parents:
diff changeset
3142 gap = actual_gap;
a61af66fc99e Initial load
duke
parents:
diff changeset
3143 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3144 warning("attempt_reserve_memory_at: adjusted gap to 0x%lx", gap);
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 unmap_memory(base[i], bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3147 unmap_memory(base[i-1], size[i-1]);
a61af66fc99e Initial load
duke
parents:
diff changeset
3148 i-=2;
a61af66fc99e Initial load
duke
parents:
diff changeset
3149 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3152
a61af66fc99e Initial load
duke
parents:
diff changeset
3153 // Does this overlap the block we wanted? Give back the overlapped
a61af66fc99e Initial load
duke
parents:
diff changeset
3154 // parts and try again.
a61af66fc99e Initial load
duke
parents:
diff changeset
3155 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3156 // There is still a bug in this code: if top_overlap == bytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
3157 // the overlap is offset from requested region by the value of gap.
a61af66fc99e Initial load
duke
parents:
diff changeset
3158 // In this case giving back the overlapped part will not work,
a61af66fc99e Initial load
duke
parents:
diff changeset
3159 // because we'll give back the entire block at base[i] and
a61af66fc99e Initial load
duke
parents:
diff changeset
3160 // therefore the subsequent allocation will not generate a new gap.
a61af66fc99e Initial load
duke
parents:
diff changeset
3161 // This could be fixed with a new algorithm that used larger
a61af66fc99e Initial load
duke
parents:
diff changeset
3162 // or variable size chunks to find the requested region -
a61af66fc99e Initial load
duke
parents:
diff changeset
3163 // but such a change would introduce additional complications.
a61af66fc99e Initial load
duke
parents:
diff changeset
3164 // It's rare enough that the planets align for this bug,
a61af66fc99e Initial load
duke
parents:
diff changeset
3165 // so we'll just wait for a fix for 6204603/5003415 which
a61af66fc99e Initial load
duke
parents:
diff changeset
3166 // will provide a mmap flag to allow us to avoid this business.
a61af66fc99e Initial load
duke
parents:
diff changeset
3167
a61af66fc99e Initial load
duke
parents:
diff changeset
3168 size_t top_overlap = requested_addr + (bytes + gap) - base[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
3169 if (top_overlap >= 0 && top_overlap < bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3170 had_top_overlap = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3171 unmap_memory(base[i], top_overlap);
a61af66fc99e Initial load
duke
parents:
diff changeset
3172 base[i] += top_overlap;
a61af66fc99e Initial load
duke
parents:
diff changeset
3173 size[i] = bytes - top_overlap;
a61af66fc99e Initial load
duke
parents:
diff changeset
3174 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3175 size_t bottom_overlap = base[i] + bytes - requested_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3176 if (bottom_overlap >= 0 && bottom_overlap < bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3177 if (PrintMiscellaneous && Verbose && bottom_overlap == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3178 warning("attempt_reserve_memory_at: possible alignment bug");
a61af66fc99e Initial load
duke
parents:
diff changeset
3179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3180 unmap_memory(requested_addr, bottom_overlap);
a61af66fc99e Initial load
duke
parents:
diff changeset
3181 size[i] = bytes - bottom_overlap;
a61af66fc99e Initial load
duke
parents:
diff changeset
3182 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3183 size[i] = bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3188
a61af66fc99e Initial load
duke
parents:
diff changeset
3189 // Give back the unused reserved pieces.
a61af66fc99e Initial load
duke
parents:
diff changeset
3190
a61af66fc99e Initial load
duke
parents:
diff changeset
3191 for (int j = 0; j < i; ++j) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3192 if (base[j] != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3193 unmap_memory(base[j], size[j]);
a61af66fc99e Initial load
duke
parents:
diff changeset
3194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3196
a61af66fc99e Initial load
duke
parents:
diff changeset
3197 return (i < max_tries) ? requested_addr : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3199
a61af66fc99e Initial load
duke
parents:
diff changeset
3200 bool os::release_memory(char* addr, size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3201 size_t size = bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3202 return munmap(addr, size) == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3204
a61af66fc99e Initial load
duke
parents:
diff changeset
3205 static bool solaris_mprotect(char* addr, size_t bytes, int prot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3206 assert(addr == (char*)align_size_down((uintptr_t)addr, os::vm_page_size()),
a61af66fc99e Initial load
duke
parents:
diff changeset
3207 "addr must be page aligned");
a61af66fc99e Initial load
duke
parents:
diff changeset
3208 int retVal = mprotect(addr, bytes, prot);
a61af66fc99e Initial load
duke
parents:
diff changeset
3209 return retVal == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3211
237
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3212 // Protect memory (Used to pass readonly pages through
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3213 // JNI GetArray<type>Elements with empty arrays.)
477
24fda36852ce 6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents: 462
diff changeset
3214 // Also, used for serialization page and for compressed oops null pointer
24fda36852ce 6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents: 462
diff changeset
3215 // checking.
237
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3216 bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3217 bool is_committed) {
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3218 unsigned int p = 0;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3219 switch (prot) {
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3220 case MEM_PROT_NONE: p = PROT_NONE; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3221 case MEM_PROT_READ: p = PROT_READ; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3222 case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3223 case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3224 default:
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3225 ShouldNotReachHere();
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3226 }
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3227 // is_committed is unused.
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3228 return solaris_mprotect(addr, bytes, p);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3230
a61af66fc99e Initial load
duke
parents:
diff changeset
3231 // guard_memory and unguard_memory only happens within stack guard pages.
a61af66fc99e Initial load
duke
parents:
diff changeset
3232 // Since ISM pertains only to the heap, guard and unguard memory should not
a61af66fc99e Initial load
duke
parents:
diff changeset
3233 /// happen with an ISM region.
a61af66fc99e Initial load
duke
parents:
diff changeset
3234 bool os::guard_memory(char* addr, size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3235 return solaris_mprotect(addr, bytes, PROT_NONE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3237
a61af66fc99e Initial load
duke
parents:
diff changeset
3238 bool os::unguard_memory(char* addr, size_t bytes) {
477
24fda36852ce 6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents: 462
diff changeset
3239 return solaris_mprotect(addr, bytes, PROT_READ|PROT_WRITE);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3241
a61af66fc99e Initial load
duke
parents:
diff changeset
3242 // Large page support
a61af66fc99e Initial load
duke
parents:
diff changeset
3243
a61af66fc99e Initial load
duke
parents:
diff changeset
3244 // UseLargePages is the master flag to enable/disable large page memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
3245 // UseMPSS and UseISM are supported for compatibility reasons. Their combined
a61af66fc99e Initial load
duke
parents:
diff changeset
3246 // effects can be described in the following table:
a61af66fc99e Initial load
duke
parents:
diff changeset
3247 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3248 // UseLargePages UseMPSS UseISM
a61af66fc99e Initial load
duke
parents:
diff changeset
3249 // false * * => UseLargePages is the master switch, turning
a61af66fc99e Initial load
duke
parents:
diff changeset
3250 // it off will turn off both UseMPSS and
a61af66fc99e Initial load
duke
parents:
diff changeset
3251 // UseISM. VM will not use large page memory
a61af66fc99e Initial load
duke
parents:
diff changeset
3252 // regardless the settings of UseMPSS/UseISM.
a61af66fc99e Initial load
duke
parents:
diff changeset
3253 // true false false => Unless future Solaris provides other
a61af66fc99e Initial load
duke
parents:
diff changeset
3254 // mechanism to use large page memory, this
a61af66fc99e Initial load
duke
parents:
diff changeset
3255 // combination is equivalent to -UseLargePages,
a61af66fc99e Initial load
duke
parents:
diff changeset
3256 // VM will not use large page memory
a61af66fc99e Initial load
duke
parents:
diff changeset
3257 // true true false => JVM will use MPSS for large page memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
3258 // This is the default behavior.
a61af66fc99e Initial load
duke
parents:
diff changeset
3259 // true false true => JVM will use ISM for large page memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
3260 // true true true => JVM will use ISM if it is available.
a61af66fc99e Initial load
duke
parents:
diff changeset
3261 // Otherwise, JVM will fall back to MPSS.
a61af66fc99e Initial load
duke
parents:
diff changeset
3262 // Becaues ISM is now available on all
a61af66fc99e Initial load
duke
parents:
diff changeset
3263 // supported Solaris versions, this combination
a61af66fc99e Initial load
duke
parents:
diff changeset
3264 // is equivalent to +UseISM -UseMPSS.
a61af66fc99e Initial load
duke
parents:
diff changeset
3265
a61af66fc99e Initial load
duke
parents:
diff changeset
3266 static size_t _large_page_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3267
a61af66fc99e Initial load
duke
parents:
diff changeset
3268 bool os::Solaris::ism_sanity_check(bool warn, size_t * page_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3269 // x86 uses either 2M or 4M page, depending on whether PAE (Physical Address
a61af66fc99e Initial load
duke
parents:
diff changeset
3270 // Extensions) mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. Sparc
a61af66fc99e Initial load
duke
parents:
diff changeset
3271 // can support multiple page sizes.
a61af66fc99e Initial load
duke
parents:
diff changeset
3272
a61af66fc99e Initial load
duke
parents:
diff changeset
3273 // Don't bother to probe page size because getpagesizes() comes with MPSS.
a61af66fc99e Initial load
duke
parents:
diff changeset
3274 // ISM is only recommended on old Solaris where there is no MPSS support.
a61af66fc99e Initial load
duke
parents:
diff changeset
3275 // Simply choose a conservative value as default.
a61af66fc99e Initial load
duke
parents:
diff changeset
3276 *page_size = LargePageSizeInBytes ? LargePageSizeInBytes :
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
3277 SPARC_ONLY(4 * M) IA32_ONLY(4 * M) AMD64_ONLY(2 * M)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
3278 ARM_ONLY(2 * M);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3279
a61af66fc99e Initial load
duke
parents:
diff changeset
3280 // ISM is available on all supported Solaris versions
a61af66fc99e Initial load
duke
parents:
diff changeset
3281 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3283
a61af66fc99e Initial load
duke
parents:
diff changeset
3284 // Insertion sort for small arrays (descending order).
a61af66fc99e Initial load
duke
parents:
diff changeset
3285 static void insertion_sort_descending(size_t* array, int len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3286 for (int i = 0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3287 size_t val = array[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
3288 for (size_t key = i; key > 0 && array[key - 1] < val; --key) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3289 size_t tmp = array[key];
a61af66fc99e Initial load
duke
parents:
diff changeset
3290 array[key] = array[key - 1];
a61af66fc99e Initial load
duke
parents:
diff changeset
3291 array[key - 1] = tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
3292 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3295
a61af66fc99e Initial load
duke
parents:
diff changeset
3296 bool os::Solaris::mpss_sanity_check(bool warn, size_t * page_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3297 const unsigned int usable_count = VM_Version::page_size_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
3298 if (usable_count == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3299 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3300 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3301
3859
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3302 // Find the right getpagesizes interface. When solaris 11 is the minimum
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3303 // build platform, getpagesizes() (without the '2') can be called directly.
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3304 typedef int (*gps_t)(size_t[], int);
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3305 gps_t gps_func = CAST_TO_FN_PTR(gps_t, dlsym(RTLD_DEFAULT, "getpagesizes2"));
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3306 if (gps_func == NULL) {
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3307 gps_func = CAST_TO_FN_PTR(gps_t, dlsym(RTLD_DEFAULT, "getpagesizes"));
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3308 if (gps_func == NULL) {
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3309 if (warn) {
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3310 warning("MPSS is not supported by the operating system.");
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3311 }
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3312 return false;
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3313 }
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3314 }
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3315
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3316 // Fill the array of page sizes.
3859
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3317 int n = (*gps_func)(_page_sizes, page_sizes_max);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3318 assert(n > 0, "Solaris bug?");
3859
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3319
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3320 if (n == page_sizes_max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3321 // Add a sentinel value (necessary only if the array was completely filled
a61af66fc99e Initial load
duke
parents:
diff changeset
3322 // since it is static (zeroed at initialization)).
a61af66fc99e Initial load
duke
parents:
diff changeset
3323 _page_sizes[--n] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3324 DEBUG_ONLY(warning("increase the size of the os::_page_sizes array.");)
a61af66fc99e Initial load
duke
parents:
diff changeset
3325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3326 assert(_page_sizes[n] == 0, "missing sentinel");
3859
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3327 trace_page_sizes("available page sizes", _page_sizes, n);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3328
a61af66fc99e Initial load
duke
parents:
diff changeset
3329 if (n == 1) return false; // Only one page size available.
a61af66fc99e Initial load
duke
parents:
diff changeset
3330
a61af66fc99e Initial load
duke
parents:
diff changeset
3331 // Skip sizes larger than 4M (or LargePageSizeInBytes if it was set) and
a61af66fc99e Initial load
duke
parents:
diff changeset
3332 // select up to usable_count elements. First sort the array, find the first
a61af66fc99e Initial load
duke
parents:
diff changeset
3333 // acceptable value, then copy the usable sizes to the top of the array and
a61af66fc99e Initial load
duke
parents:
diff changeset
3334 // trim the rest. Make sure to include the default page size :-).
a61af66fc99e Initial load
duke
parents:
diff changeset
3335 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3336 // A better policy could get rid of the 4M limit by taking the sizes of the
a61af66fc99e Initial load
duke
parents:
diff changeset
3337 // important VM memory regions (java heap and possibly the code cache) into
a61af66fc99e Initial load
duke
parents:
diff changeset
3338 // account.
a61af66fc99e Initial load
duke
parents:
diff changeset
3339 insertion_sort_descending(_page_sizes, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
3340 const size_t size_limit =
a61af66fc99e Initial load
duke
parents:
diff changeset
3341 FLAG_IS_DEFAULT(LargePageSizeInBytes) ? 4 * M : LargePageSizeInBytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3342 int beg;
a61af66fc99e Initial load
duke
parents:
diff changeset
3343 for (beg = 0; beg < n && _page_sizes[beg] > size_limit; ++beg) /* empty */ ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3344 const int end = MIN2((int)usable_count, n) - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3345 for (int cur = 0; cur < end; ++cur, ++beg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3346 _page_sizes[cur] = _page_sizes[beg];
a61af66fc99e Initial load
duke
parents:
diff changeset
3347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3348 _page_sizes[end] = vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3349 _page_sizes[end + 1] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3350
a61af66fc99e Initial load
duke
parents:
diff changeset
3351 if (_page_sizes[end] > _page_sizes[end - 1]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3352 // Default page size is not the smallest; sort again.
a61af66fc99e Initial load
duke
parents:
diff changeset
3353 insertion_sort_descending(_page_sizes, end + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3354 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3355 *page_size = _page_sizes[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
3356
3859
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3357 trace_page_sizes("usable page sizes", _page_sizes, end + 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3358 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3360
3318
188c9a5d6a6d 7040485: Use transparent huge page on linux by default
iveresov
parents: 3292
diff changeset
3361 void os::large_page_init() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3362 if (!UseLargePages) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3363 UseISM = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3364 UseMPSS = false;
3318
188c9a5d6a6d 7040485: Use transparent huge page on linux by default
iveresov
parents: 3292
diff changeset
3365 return;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3367
a61af66fc99e Initial load
duke
parents:
diff changeset
3368 // print a warning if any large page related flag is specified on command line
a61af66fc99e Initial load
duke
parents:
diff changeset
3369 bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3370 !FLAG_IS_DEFAULT(UseISM) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3371 !FLAG_IS_DEFAULT(UseMPSS) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3372 !FLAG_IS_DEFAULT(LargePageSizeInBytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3373 UseISM = UseISM &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3374 Solaris::ism_sanity_check(warn_on_failure, &_large_page_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3375 if (UseISM) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3376 // ISM disables MPSS to be compatible with old JDK behavior
a61af66fc99e Initial load
duke
parents:
diff changeset
3377 UseMPSS = false;
79
82db0859acbe 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 61
diff changeset
3378 _page_sizes[0] = _large_page_size;
82db0859acbe 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 61
diff changeset
3379 _page_sizes[1] = vm_page_size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3380 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3381
a61af66fc99e Initial load
duke
parents:
diff changeset
3382 UseMPSS = UseMPSS &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3383 Solaris::mpss_sanity_check(warn_on_failure, &_large_page_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3384
a61af66fc99e Initial load
duke
parents:
diff changeset
3385 UseLargePages = UseISM || UseMPSS;
a61af66fc99e Initial load
duke
parents:
diff changeset
3386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3387
a61af66fc99e Initial load
duke
parents:
diff changeset
3388 bool os::Solaris::set_mpss_range(caddr_t start, size_t bytes, size_t align) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3389 // Signal to OS that we want large pages for addresses
a61af66fc99e Initial load
duke
parents:
diff changeset
3390 // from addr, addr + bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
3391 struct memcntl_mha mpss_struct;
a61af66fc99e Initial load
duke
parents:
diff changeset
3392 mpss_struct.mha_cmd = MHA_MAPSIZE_VA;
a61af66fc99e Initial load
duke
parents:
diff changeset
3393 mpss_struct.mha_pagesize = align;
a61af66fc99e Initial load
duke
parents:
diff changeset
3394 mpss_struct.mha_flags = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3395 if (memcntl(start, bytes, MC_HAT_ADVISE,
a61af66fc99e Initial load
duke
parents:
diff changeset
3396 (caddr_t) &mpss_struct, 0, 0) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3397 debug_only(warning("Attempt to use MPSS failed."));
a61af66fc99e Initial load
duke
parents:
diff changeset
3398 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3400 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3401 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3402
3885
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
3403 char* os::reserve_memory_special(size_t size, char* addr, bool exec) {
656
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
3404 // "exec" is passed in but not used. Creating the shared image for
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
3405 // the code cache doesn't have an SHM_X executable permission to check.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3406 assert(UseLargePages && UseISM, "only for ISM large pages");
a61af66fc99e Initial load
duke
parents:
diff changeset
3407
a61af66fc99e Initial load
duke
parents:
diff changeset
3408 char* retAddr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3409 int shmid;
a61af66fc99e Initial load
duke
parents:
diff changeset
3410 key_t ismKey;
a61af66fc99e Initial load
duke
parents:
diff changeset
3411
a61af66fc99e Initial load
duke
parents:
diff changeset
3412 bool warn_on_failure = UseISM &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3413 (!FLAG_IS_DEFAULT(UseLargePages) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3414 !FLAG_IS_DEFAULT(UseISM) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3415 !FLAG_IS_DEFAULT(LargePageSizeInBytes)
a61af66fc99e Initial load
duke
parents:
diff changeset
3416 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3417 char msg[128];
a61af66fc99e Initial load
duke
parents:
diff changeset
3418
a61af66fc99e Initial load
duke
parents:
diff changeset
3419 ismKey = IPC_PRIVATE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3420
a61af66fc99e Initial load
duke
parents:
diff changeset
3421 // Create a large shared memory region to attach to based on size.
a61af66fc99e Initial load
duke
parents:
diff changeset
3422 // Currently, size is the total size of the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
3423 shmid = shmget(ismKey, size, SHM_R | SHM_W | IPC_CREAT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3424 if (shmid == -1){
a61af66fc99e Initial load
duke
parents:
diff changeset
3425 if (warn_on_failure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3426 jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno);
a61af66fc99e Initial load
duke
parents:
diff changeset
3427 warning(msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3429 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3431
a61af66fc99e Initial load
duke
parents:
diff changeset
3432 // Attach to the region
a61af66fc99e Initial load
duke
parents:
diff changeset
3433 retAddr = (char *) shmat(shmid, 0, SHM_SHARE_MMU | SHM_R | SHM_W);
a61af66fc99e Initial load
duke
parents:
diff changeset
3434 int err = errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3435
a61af66fc99e Initial load
duke
parents:
diff changeset
3436 // Remove shmid. If shmat() is successful, the actual shared memory segment
a61af66fc99e Initial load
duke
parents:
diff changeset
3437 // will be deleted when it's detached by shmdt() or when the process
a61af66fc99e Initial load
duke
parents:
diff changeset
3438 // terminates. If shmat() is not successful this will remove the shared
a61af66fc99e Initial load
duke
parents:
diff changeset
3439 // segment immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
3440 shmctl(shmid, IPC_RMID, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3441
a61af66fc99e Initial load
duke
parents:
diff changeset
3442 if (retAddr == (char *) -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3443 if (warn_on_failure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3444 jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err);
a61af66fc99e Initial load
duke
parents:
diff changeset
3445 warning(msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3446 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3447 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3448 }
3885
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
3449 if ((retAddr != NULL) && UseNUMAInterleaving) {
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
3450 numa_make_global(retAddr, size);
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
3451 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3452 return retAddr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3454
a61af66fc99e Initial load
duke
parents:
diff changeset
3455 bool os::release_memory_special(char* base, size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3456 // detaching the SHM segment will also delete it, see reserve_memory_special()
a61af66fc99e Initial load
duke
parents:
diff changeset
3457 int rslt = shmdt(base);
a61af66fc99e Initial load
duke
parents:
diff changeset
3458 return rslt == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3460
a61af66fc99e Initial load
duke
parents:
diff changeset
3461 size_t os::large_page_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3462 return _large_page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3464
a61af66fc99e Initial load
duke
parents:
diff changeset
3465 // MPSS allows application to commit large page memory on demand; with ISM
a61af66fc99e Initial load
duke
parents:
diff changeset
3466 // the entire memory region must be allocated as shared memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
3467 bool os::can_commit_large_page_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3468 return UseISM ? false : true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3470
79
82db0859acbe 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 61
diff changeset
3471 bool os::can_execute_large_page_memory() {
82db0859acbe 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 61
diff changeset
3472 return UseISM ? false : true;
82db0859acbe 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 61
diff changeset
3473 }
82db0859acbe 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 61
diff changeset
3474
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3475 static int os_sleep(jlong millis, bool interruptible) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3476 const jlong limit = INT_MAX;
a61af66fc99e Initial load
duke
parents:
diff changeset
3477 jlong prevtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
3478 int res;
a61af66fc99e Initial load
duke
parents:
diff changeset
3479
a61af66fc99e Initial load
duke
parents:
diff changeset
3480 while (millis > limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3481 if ((res = os_sleep(limit, interruptible)) != OS_OK)
a61af66fc99e Initial load
duke
parents:
diff changeset
3482 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
3483 millis -= limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
3484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3485
a61af66fc99e Initial load
duke
parents:
diff changeset
3486 // Restart interrupted polls with new parameters until the proper delay
a61af66fc99e Initial load
duke
parents:
diff changeset
3487 // has been completed.
a61af66fc99e Initial load
duke
parents:
diff changeset
3488
a61af66fc99e Initial load
duke
parents:
diff changeset
3489 prevtime = getTimeMillis();
a61af66fc99e Initial load
duke
parents:
diff changeset
3490
a61af66fc99e Initial load
duke
parents:
diff changeset
3491 while (millis > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3492 jlong newtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
3493
a61af66fc99e Initial load
duke
parents:
diff changeset
3494 if (!interruptible) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3495 // Following assert fails for os::yield_all:
a61af66fc99e Initial load
duke
parents:
diff changeset
3496 // assert(!thread->is_Java_thread(), "must not be java thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
3497 res = poll(NULL, 0, millis);
a61af66fc99e Initial load
duke
parents:
diff changeset
3498 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3499 JavaThread *jt = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
3500
a61af66fc99e Initial load
duke
parents:
diff changeset
3501 INTERRUPTIBLE_NORESTART_VM_ALWAYS(poll(NULL, 0, millis), res, jt,
a61af66fc99e Initial load
duke
parents:
diff changeset
3502 os::Solaris::clear_interrupted);
a61af66fc99e Initial load
duke
parents:
diff changeset
3503 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3504
a61af66fc99e Initial load
duke
parents:
diff changeset
3505 // INTERRUPTIBLE_NORESTART_VM_ALWAYS returns res == OS_INTRPT for
a61af66fc99e Initial load
duke
parents:
diff changeset
3506 // thread.Interrupt.
a61af66fc99e Initial load
duke
parents:
diff changeset
3507
1967
22260322f0be 6751923: JNDI wake up when clock_settime() is called
zgu
parents: 1867
diff changeset
3508 // See c/r 6751923. Poll can return 0 before time
22260322f0be 6751923: JNDI wake up when clock_settime() is called
zgu
parents: 1867
diff changeset
3509 // has elapsed if time is set via clock_settime (as NTP does).
22260322f0be 6751923: JNDI wake up when clock_settime() is called
zgu
parents: 1867
diff changeset
3510 // res == 0 if poll timed out (see man poll RETURN VALUES)
22260322f0be 6751923: JNDI wake up when clock_settime() is called
zgu
parents: 1867
diff changeset
3511 // using the logic below checks that we really did
22260322f0be 6751923: JNDI wake up when clock_settime() is called
zgu
parents: 1867
diff changeset
3512 // sleep at least "millis" if not we'll sleep again.
22260322f0be 6751923: JNDI wake up when clock_settime() is called
zgu
parents: 1867
diff changeset
3513 if( ( res == 0 ) || ((res == OS_ERR) && (errno == EINTR))) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3514 newtime = getTimeMillis();
a61af66fc99e Initial load
duke
parents:
diff changeset
3515 assert(newtime >= prevtime, "time moving backwards");
a61af66fc99e Initial load
duke
parents:
diff changeset
3516 /* Doing prevtime and newtime in microseconds doesn't help precision,
a61af66fc99e Initial load
duke
parents:
diff changeset
3517 and trying to round up to avoid lost milliseconds can result in a
a61af66fc99e Initial load
duke
parents:
diff changeset
3518 too-short delay. */
a61af66fc99e Initial load
duke
parents:
diff changeset
3519 millis -= newtime - prevtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
3520 if(millis <= 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
3521 return OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3522 prevtime = newtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
3523 } else
a61af66fc99e Initial load
duke
parents:
diff changeset
3524 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
3525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3526
a61af66fc99e Initial load
duke
parents:
diff changeset
3527 return OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3529
a61af66fc99e Initial load
duke
parents:
diff changeset
3530 // Read calls from inside the vm need to perform state transitions
a61af66fc99e Initial load
duke
parents:
diff changeset
3531 size_t os::read(int fd, void *buf, unsigned int nBytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3532 INTERRUPTIBLE_RETURN_INT_VM(::read(fd, buf, nBytes), os::Solaris::clear_interrupted);
a61af66fc99e Initial load
duke
parents:
diff changeset
3533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3534
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3535 size_t os::restartable_read(int fd, void *buf, unsigned int nBytes) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3536 INTERRUPTIBLE_RETURN_INT(::read(fd, buf, nBytes), os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3537 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3538
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3539 int os::sleep(Thread* thread, jlong millis, bool interruptible) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3540 assert(thread == Thread::current(), "thread consistency check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3541
a61af66fc99e Initial load
duke
parents:
diff changeset
3542 // TODO-FIXME: this should be removed.
a61af66fc99e Initial load
duke
parents:
diff changeset
3543 // On Solaris machines (especially 2.5.1) we found that sometimes the VM gets into a live lock
a61af66fc99e Initial load
duke
parents:
diff changeset
3544 // situation with a JavaThread being starved out of a lwp. The kernel doesn't seem to generate
a61af66fc99e Initial load
duke
parents:
diff changeset
3545 // a SIGWAITING signal which would enable the threads library to create a new lwp for the starving
a61af66fc99e Initial load
duke
parents:
diff changeset
3546 // thread. We suspect that because the Watcher thread keeps waking up at periodic intervals the kernel
a61af66fc99e Initial load
duke
parents:
diff changeset
3547 // is fooled into believing that the system is making progress. In the code below we block the
a61af66fc99e Initial load
duke
parents:
diff changeset
3548 // the watcher thread while safepoint is in progress so that it would not appear as though the
a61af66fc99e Initial load
duke
parents:
diff changeset
3549 // system is making progress.
a61af66fc99e Initial load
duke
parents:
diff changeset
3550 if (!Solaris::T2_libthread() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3551 thread->is_Watcher_thread() && SafepointSynchronize::is_synchronizing() && !Arguments::has_profile()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3552 // We now try to acquire the threads lock. Since this lock is held by the VM thread during
a61af66fc99e Initial load
duke
parents:
diff changeset
3553 // the entire safepoint, the watcher thread will line up here during the safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
3554 Threads_lock->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
3555 Threads_lock->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
3556 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3557
a61af66fc99e Initial load
duke
parents:
diff changeset
3558 if (thread->is_Java_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3559 // This is a JavaThread so we honor the _thread_blocked protocol
a61af66fc99e Initial load
duke
parents:
diff changeset
3560 // even for sleeps of 0 milliseconds. This was originally done
a61af66fc99e Initial load
duke
parents:
diff changeset
3561 // as a workaround for bug 4338139. However, now we also do it
a61af66fc99e Initial load
duke
parents:
diff changeset
3562 // to honor the suspend-equivalent protocol.
a61af66fc99e Initial load
duke
parents:
diff changeset
3563
a61af66fc99e Initial load
duke
parents:
diff changeset
3564 JavaThread *jt = (JavaThread *) thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
3565 ThreadBlockInVM tbivm(jt);
a61af66fc99e Initial load
duke
parents:
diff changeset
3566
a61af66fc99e Initial load
duke
parents:
diff changeset
3567 jt->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
3568 // cleared by handle_special_suspend_equivalent_condition() or
a61af66fc99e Initial load
duke
parents:
diff changeset
3569 // java_suspend_self() via check_and_wait_while_suspended()
a61af66fc99e Initial load
duke
parents:
diff changeset
3570
a61af66fc99e Initial load
duke
parents:
diff changeset
3571 int ret_code;
a61af66fc99e Initial load
duke
parents:
diff changeset
3572 if (millis <= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3573 thr_yield();
a61af66fc99e Initial load
duke
parents:
diff changeset
3574 ret_code = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3575 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3576 // The original sleep() implementation did not create an
a61af66fc99e Initial load
duke
parents:
diff changeset
3577 // OSThreadWaitState helper for sleeps of 0 milliseconds.
a61af66fc99e Initial load
duke
parents:
diff changeset
3578 // I'm preserving that decision for now.
a61af66fc99e Initial load
duke
parents:
diff changeset
3579 OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
a61af66fc99e Initial load
duke
parents:
diff changeset
3580
a61af66fc99e Initial load
duke
parents:
diff changeset
3581 ret_code = os_sleep(millis, interruptible);
a61af66fc99e Initial load
duke
parents:
diff changeset
3582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3583
a61af66fc99e Initial load
duke
parents:
diff changeset
3584 // were we externally suspended while we were waiting?
a61af66fc99e Initial load
duke
parents:
diff changeset
3585 jt->check_and_wait_while_suspended();
a61af66fc99e Initial load
duke
parents:
diff changeset
3586
a61af66fc99e Initial load
duke
parents:
diff changeset
3587 return ret_code;
a61af66fc99e Initial load
duke
parents:
diff changeset
3588 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3589
a61af66fc99e Initial load
duke
parents:
diff changeset
3590 // non-JavaThread from this point on:
a61af66fc99e Initial load
duke
parents:
diff changeset
3591
a61af66fc99e Initial load
duke
parents:
diff changeset
3592 if (millis <= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3593 thr_yield();
a61af66fc99e Initial load
duke
parents:
diff changeset
3594 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3595 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3596
a61af66fc99e Initial load
duke
parents:
diff changeset
3597 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
a61af66fc99e Initial load
duke
parents:
diff changeset
3598
a61af66fc99e Initial load
duke
parents:
diff changeset
3599 return os_sleep(millis, interruptible);
a61af66fc99e Initial load
duke
parents:
diff changeset
3600 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3601
a61af66fc99e Initial load
duke
parents:
diff changeset
3602 int os::naked_sleep() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3603 // %% make the sleep time an integer flag. for now use 1 millisec.
a61af66fc99e Initial load
duke
parents:
diff changeset
3604 return os_sleep(1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3606
a61af66fc99e Initial load
duke
parents:
diff changeset
3607 // Sleep forever; naked call to OS-specific sleep; use with CAUTION
a61af66fc99e Initial load
duke
parents:
diff changeset
3608 void os::infinite_sleep() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3609 while (true) { // sleep forever ...
a61af66fc99e Initial load
duke
parents:
diff changeset
3610 ::sleep(100); // ... 100 seconds at a time
a61af66fc99e Initial load
duke
parents:
diff changeset
3611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3613
a61af66fc99e Initial load
duke
parents:
diff changeset
3614 // Used to convert frequent JVM_Yield() to nops
a61af66fc99e Initial load
duke
parents:
diff changeset
3615 bool os::dont_yield() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3616 if (DontYieldALot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3617 static hrtime_t last_time = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3618 hrtime_t diff = getTimeNanos() - last_time;
a61af66fc99e Initial load
duke
parents:
diff changeset
3619
a61af66fc99e Initial load
duke
parents:
diff changeset
3620 if (diff < DontYieldALotInterval * 1000000)
a61af66fc99e Initial load
duke
parents:
diff changeset
3621 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3622
a61af66fc99e Initial load
duke
parents:
diff changeset
3623 last_time += diff;
a61af66fc99e Initial load
duke
parents:
diff changeset
3624
a61af66fc99e Initial load
duke
parents:
diff changeset
3625 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3627 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3628 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3631
a61af66fc99e Initial load
duke
parents:
diff changeset
3632 // Caveat: Solaris os::yield() causes a thread-state transition whereas
a61af66fc99e Initial load
duke
parents:
diff changeset
3633 // the linux and win32 implementations do not. This should be checked.
a61af66fc99e Initial load
duke
parents:
diff changeset
3634
a61af66fc99e Initial load
duke
parents:
diff changeset
3635 void os::yield() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3636 // Yields to all threads with same or greater priority
a61af66fc99e Initial load
duke
parents:
diff changeset
3637 os::sleep(Thread::current(), 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3638 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3639
a61af66fc99e Initial load
duke
parents:
diff changeset
3640 // Note that yield semantics are defined by the scheduling class to which
a61af66fc99e Initial load
duke
parents:
diff changeset
3641 // the thread currently belongs. Typically, yield will _not yield to
a61af66fc99e Initial load
duke
parents:
diff changeset
3642 // other equal or higher priority threads that reside on the dispatch queues
a61af66fc99e Initial load
duke
parents:
diff changeset
3643 // of other CPUs.
a61af66fc99e Initial load
duke
parents:
diff changeset
3644
a61af66fc99e Initial load
duke
parents:
diff changeset
3645 os::YieldResult os::NakedYield() { thr_yield(); return os::YIELD_UNKNOWN; }
a61af66fc99e Initial load
duke
parents:
diff changeset
3646
a61af66fc99e Initial load
duke
parents:
diff changeset
3647
a61af66fc99e Initial load
duke
parents:
diff changeset
3648 // On Solaris we found that yield_all doesn't always yield to all other threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
3649 // There have been cases where there is a thread ready to execute but it doesn't
a61af66fc99e Initial load
duke
parents:
diff changeset
3650 // get an lwp as the VM thread continues to spin with sleeps of 1 millisecond.
a61af66fc99e Initial load
duke
parents:
diff changeset
3651 // The 1 millisecond wait doesn't seem long enough for the kernel to issue a
a61af66fc99e Initial load
duke
parents:
diff changeset
3652 // SIGWAITING signal which will cause a new lwp to be created. So we count the
a61af66fc99e Initial load
duke
parents:
diff changeset
3653 // number of times yield_all is called in the one loop and increase the sleep
a61af66fc99e Initial load
duke
parents:
diff changeset
3654 // time after 8 attempts. If this fails too we increase the concurrency level
a61af66fc99e Initial load
duke
parents:
diff changeset
3655 // so that the starving thread would get an lwp
a61af66fc99e Initial load
duke
parents:
diff changeset
3656
a61af66fc99e Initial load
duke
parents:
diff changeset
3657 void os::yield_all(int attempts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3658 // Yields to all threads, including threads with lower priorities
a61af66fc99e Initial load
duke
parents:
diff changeset
3659 if (attempts == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3660 os::sleep(Thread::current(), 1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3661 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3662 int iterations = attempts % 30;
a61af66fc99e Initial load
duke
parents:
diff changeset
3663 if (iterations == 0 && !os::Solaris::T2_libthread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3664 // thr_setconcurrency and _getconcurrency make sense only under T1.
a61af66fc99e Initial load
duke
parents:
diff changeset
3665 int noofLWPS = thr_getconcurrency();
a61af66fc99e Initial load
duke
parents:
diff changeset
3666 if (noofLWPS < (Threads::number_of_threads() + 2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3667 thr_setconcurrency(thr_getconcurrency() + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3668 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3669 } else if (iterations < 25) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3670 os::sleep(Thread::current(), 1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3671 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3672 os::sleep(Thread::current(), 10, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3673 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3674 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3676
a61af66fc99e Initial load
duke
parents:
diff changeset
3677 // Called from the tight loops to possibly influence time-sharing heuristics
a61af66fc99e Initial load
duke
parents:
diff changeset
3678 void os::loop_breaker(int attempts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3679 os::yield_all(attempts);
a61af66fc99e Initial load
duke
parents:
diff changeset
3680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3681
a61af66fc99e Initial load
duke
parents:
diff changeset
3682
a61af66fc99e Initial load
duke
parents:
diff changeset
3683 // Interface for setting lwp priorities. If we are using T2 libthread,
a61af66fc99e Initial load
duke
parents:
diff changeset
3684 // which forces the use of BoundThreads or we manually set UseBoundThreads,
a61af66fc99e Initial load
duke
parents:
diff changeset
3685 // all of our threads will be assigned to real lwp's. Using the thr_setprio
a61af66fc99e Initial load
duke
parents:
diff changeset
3686 // function is meaningless in this mode so we must adjust the real lwp's priority
a61af66fc99e Initial load
duke
parents:
diff changeset
3687 // The routines below implement the getting and setting of lwp priorities.
a61af66fc99e Initial load
duke
parents:
diff changeset
3688 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3689 // Note: There are three priority scales used on Solaris. Java priotities
a61af66fc99e Initial load
duke
parents:
diff changeset
3690 // which range from 1 to 10, libthread "thr_setprio" scale which range
a61af66fc99e Initial load
duke
parents:
diff changeset
3691 // from 0 to 127, and the current scheduling class of the process we
a61af66fc99e Initial load
duke
parents:
diff changeset
3692 // are running in. This is typically from -60 to +60.
a61af66fc99e Initial load
duke
parents:
diff changeset
3693 // The setting of the lwp priorities in done after a call to thr_setprio
a61af66fc99e Initial load
duke
parents:
diff changeset
3694 // so Java priorities are mapped to libthread priorities and we map from
a61af66fc99e Initial load
duke
parents:
diff changeset
3695 // the latter to lwp priorities. We don't keep priorities stored in
a61af66fc99e Initial load
duke
parents:
diff changeset
3696 // Java priorities since some of our worker threads want to set priorities
a61af66fc99e Initial load
duke
parents:
diff changeset
3697 // higher than all Java threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
3698 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3699 // For related information:
a61af66fc99e Initial load
duke
parents:
diff changeset
3700 // (1) man -s 2 priocntl
a61af66fc99e Initial load
duke
parents:
diff changeset
3701 // (2) man -s 4 priocntl
a61af66fc99e Initial load
duke
parents:
diff changeset
3702 // (3) man dispadmin
a61af66fc99e Initial load
duke
parents:
diff changeset
3703 // = librt.so
a61af66fc99e Initial load
duke
parents:
diff changeset
3704 // = libthread/common/rtsched.c - thrp_setlwpprio().
a61af66fc99e Initial load
duke
parents:
diff changeset
3705 // = ps -cL <pid> ... to validate priority.
a61af66fc99e Initial load
duke
parents:
diff changeset
3706 // = sched_get_priority_min and _max
a61af66fc99e Initial load
duke
parents:
diff changeset
3707 // pthread_create
a61af66fc99e Initial load
duke
parents:
diff changeset
3708 // sched_setparam
a61af66fc99e Initial load
duke
parents:
diff changeset
3709 // pthread_setschedparam
a61af66fc99e Initial load
duke
parents:
diff changeset
3710 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3711 // Assumptions:
a61af66fc99e Initial load
duke
parents:
diff changeset
3712 // + We assume that all threads in the process belong to the same
a61af66fc99e Initial load
duke
parents:
diff changeset
3713 // scheduling class. IE. an homogenous process.
a61af66fc99e Initial load
duke
parents:
diff changeset
3714 // + Must be root or in IA group to change change "interactive" attribute.
a61af66fc99e Initial load
duke
parents:
diff changeset
3715 // Priocntl() will fail silently. The only indication of failure is when
a61af66fc99e Initial load
duke
parents:
diff changeset
3716 // we read-back the value and notice that it hasn't changed.
a61af66fc99e Initial load
duke
parents:
diff changeset
3717 // + Interactive threads enter the runq at the head, non-interactive at the tail.
a61af66fc99e Initial load
duke
parents:
diff changeset
3718 // + For RT, change timeslice as well. Invariant:
a61af66fc99e Initial load
duke
parents:
diff changeset
3719 // constant "priority integral"
a61af66fc99e Initial load
duke
parents:
diff changeset
3720 // Konst == TimeSlice * (60-Priority)
a61af66fc99e Initial load
duke
parents:
diff changeset
3721 // Given a priority, compute appropriate timeslice.
a61af66fc99e Initial load
duke
parents:
diff changeset
3722 // + Higher numerical values have higher priority.
a61af66fc99e Initial load
duke
parents:
diff changeset
3723
a61af66fc99e Initial load
duke
parents:
diff changeset
3724 // sched class attributes
a61af66fc99e Initial load
duke
parents:
diff changeset
3725 typedef struct {
a61af66fc99e Initial load
duke
parents:
diff changeset
3726 int schedPolicy; // classID
a61af66fc99e Initial load
duke
parents:
diff changeset
3727 int maxPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3728 int minPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3729 } SchedInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
3730
a61af66fc99e Initial load
duke
parents:
diff changeset
3731
a61af66fc99e Initial load
duke
parents:
diff changeset
3732 static SchedInfo tsLimits, iaLimits, rtLimits;
a61af66fc99e Initial load
duke
parents:
diff changeset
3733
a61af66fc99e Initial load
duke
parents:
diff changeset
3734 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3735 static int ReadBackValidate = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3736 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3737 static int myClass = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3738 static int myMin = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3739 static int myMax = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3740 static int myCur = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3741 static bool priocntl_enable = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3742
a61af66fc99e Initial load
duke
parents:
diff changeset
3743
a61af66fc99e Initial load
duke
parents:
diff changeset
3744 // Call the version of priocntl suitable for all supported versions
a61af66fc99e Initial load
duke
parents:
diff changeset
3745 // of Solaris. We need to call through this wrapper so that we can
a61af66fc99e Initial load
duke
parents:
diff changeset
3746 // build on Solaris 9 and run on Solaris 8, 9 and 10.
a61af66fc99e Initial load
duke
parents:
diff changeset
3747 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3748 // This code should be removed if we ever stop supporting Solaris 8
a61af66fc99e Initial load
duke
parents:
diff changeset
3749 // and earlier releases.
a61af66fc99e Initial load
duke
parents:
diff changeset
3750
a61af66fc99e Initial load
duke
parents:
diff changeset
3751 static long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3752 typedef long (*priocntl_type)(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3753 static priocntl_type priocntl_ptr = priocntl_stub;
a61af66fc99e Initial load
duke
parents:
diff changeset
3754
a61af66fc99e Initial load
duke
parents:
diff changeset
3755 // Stub to set the value of the real pointer, and then call the real
a61af66fc99e Initial load
duke
parents:
diff changeset
3756 // function.
a61af66fc99e Initial load
duke
parents:
diff changeset
3757
a61af66fc99e Initial load
duke
parents:
diff changeset
3758 static long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3759 // Try Solaris 8- name only.
a61af66fc99e Initial load
duke
parents:
diff changeset
3760 priocntl_type tmp = (priocntl_type)dlsym(RTLD_DEFAULT, "__priocntl");
a61af66fc99e Initial load
duke
parents:
diff changeset
3761 guarantee(tmp != NULL, "priocntl function not found.");
a61af66fc99e Initial load
duke
parents:
diff changeset
3762 priocntl_ptr = tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
3763 return (*priocntl_ptr)(PC_VERSION, idtype, id, cmd, arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3764 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3765
a61af66fc99e Initial load
duke
parents:
diff changeset
3766
a61af66fc99e Initial load
duke
parents:
diff changeset
3767 // lwp_priocntl_init
a61af66fc99e Initial load
duke
parents:
diff changeset
3768 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3769 // Try to determine the priority scale for our process.
a61af66fc99e Initial load
duke
parents:
diff changeset
3770 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3771 // Return errno or 0 if OK.
a61af66fc99e Initial load
duke
parents:
diff changeset
3772 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3773 static
a61af66fc99e Initial load
duke
parents:
diff changeset
3774 int lwp_priocntl_init ()
a61af66fc99e Initial load
duke
parents:
diff changeset
3775 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3776 int rslt;
a61af66fc99e Initial load
duke
parents:
diff changeset
3777 pcinfo_t ClassInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
3778 pcparms_t ParmInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
3779 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
3780
a61af66fc99e Initial load
duke
parents:
diff changeset
3781 if (!UseThreadPriorities) return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3782
a61af66fc99e Initial load
duke
parents:
diff changeset
3783 // We are using Bound threads, we need to determine our priority ranges
a61af66fc99e Initial load
duke
parents:
diff changeset
3784 if (os::Solaris::T2_libthread() || UseBoundThreads) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3785 // If ThreadPriorityPolicy is 1, switch tables
a61af66fc99e Initial load
duke
parents:
diff changeset
3786 if (ThreadPriorityPolicy == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3787 for (i = 0 ; i < MaxPriority+1; i++)
a61af66fc99e Initial load
duke
parents:
diff changeset
3788 os::java_to_os_priority[i] = prio_policy1[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
3789 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3790 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3791 // Not using Bound Threads, set to ThreadPolicy 1
a61af66fc99e Initial load
duke
parents:
diff changeset
3792 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3793 for ( i = 0 ; i < MaxPriority+1; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3794 os::java_to_os_priority[i] = prio_policy1[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
3795 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3796 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3797 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3798
a61af66fc99e Initial load
duke
parents:
diff changeset
3799
a61af66fc99e Initial load
duke
parents:
diff changeset
3800 // Get IDs for a set of well-known scheduling classes.
a61af66fc99e Initial load
duke
parents:
diff changeset
3801 // TODO-FIXME: GETCLINFO returns the current # of classes in the
a61af66fc99e Initial load
duke
parents:
diff changeset
3802 // the system. We should have a loop that iterates over the
a61af66fc99e Initial load
duke
parents:
diff changeset
3803 // classID values, which are known to be "small" integers.
a61af66fc99e Initial load
duke
parents:
diff changeset
3804
a61af66fc99e Initial load
duke
parents:
diff changeset
3805 strcpy(ClassInfo.pc_clname, "TS");
a61af66fc99e Initial load
duke
parents:
diff changeset
3806 ClassInfo.pc_cid = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3807 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
3808 if (rslt < 0) return errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3809 assert(ClassInfo.pc_cid != -1, "cid for TS class is -1");
a61af66fc99e Initial load
duke
parents:
diff changeset
3810 tsLimits.schedPolicy = ClassInfo.pc_cid;
a61af66fc99e Initial load
duke
parents:
diff changeset
3811 tsLimits.maxPrio = ((tsinfo_t*)ClassInfo.pc_clinfo)->ts_maxupri;
a61af66fc99e Initial load
duke
parents:
diff changeset
3812 tsLimits.minPrio = -tsLimits.maxPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3813
a61af66fc99e Initial load
duke
parents:
diff changeset
3814 strcpy(ClassInfo.pc_clname, "IA");
a61af66fc99e Initial load
duke
parents:
diff changeset
3815 ClassInfo.pc_cid = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3816 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
3817 if (rslt < 0) return errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3818 assert(ClassInfo.pc_cid != -1, "cid for IA class is -1");
a61af66fc99e Initial load
duke
parents:
diff changeset
3819 iaLimits.schedPolicy = ClassInfo.pc_cid;
a61af66fc99e Initial load
duke
parents:
diff changeset
3820 iaLimits.maxPrio = ((iainfo_t*)ClassInfo.pc_clinfo)->ia_maxupri;
a61af66fc99e Initial load
duke
parents:
diff changeset
3821 iaLimits.minPrio = -iaLimits.maxPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3822
a61af66fc99e Initial load
duke
parents:
diff changeset
3823 strcpy(ClassInfo.pc_clname, "RT");
a61af66fc99e Initial load
duke
parents:
diff changeset
3824 ClassInfo.pc_cid = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3825 rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
3826 if (rslt < 0) return errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3827 assert(ClassInfo.pc_cid != -1, "cid for RT class is -1");
a61af66fc99e Initial load
duke
parents:
diff changeset
3828 rtLimits.schedPolicy = ClassInfo.pc_cid;
a61af66fc99e Initial load
duke
parents:
diff changeset
3829 rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri;
a61af66fc99e Initial load
duke
parents:
diff changeset
3830 rtLimits.minPrio = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3831
a61af66fc99e Initial load
duke
parents:
diff changeset
3832
a61af66fc99e Initial load
duke
parents:
diff changeset
3833 // Query our "current" scheduling class.
a61af66fc99e Initial load
duke
parents:
diff changeset
3834 // This will normally be IA,TS or, rarely, RT.
a61af66fc99e Initial load
duke
parents:
diff changeset
3835 memset (&ParmInfo, 0, sizeof(ParmInfo));
a61af66fc99e Initial load
duke
parents:
diff changeset
3836 ParmInfo.pc_cid = PC_CLNULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3837 rslt = (*priocntl_ptr) (PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo );
a61af66fc99e Initial load
duke
parents:
diff changeset
3838 if ( rslt < 0 ) return errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3839 myClass = ParmInfo.pc_cid;
a61af66fc99e Initial load
duke
parents:
diff changeset
3840
a61af66fc99e Initial load
duke
parents:
diff changeset
3841 // We now know our scheduling classId, get specific information
a61af66fc99e Initial load
duke
parents:
diff changeset
3842 // the class.
a61af66fc99e Initial load
duke
parents:
diff changeset
3843 ClassInfo.pc_cid = myClass;
a61af66fc99e Initial load
duke
parents:
diff changeset
3844 ClassInfo.pc_clname[0] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3845 rslt = (*priocntl_ptr) (PC_VERSION, (idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo );
a61af66fc99e Initial load
duke
parents:
diff changeset
3846 if ( rslt < 0 ) return errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3847
a61af66fc99e Initial load
duke
parents:
diff changeset
3848 if (ThreadPriorityVerbose)
a61af66fc99e Initial load
duke
parents:
diff changeset
3849 tty->print_cr ("lwp_priocntl_init: Class=%d(%s)...", myClass, ClassInfo.pc_clname);
a61af66fc99e Initial load
duke
parents:
diff changeset
3850
a61af66fc99e Initial load
duke
parents:
diff changeset
3851 memset(&ParmInfo, 0, sizeof(pcparms_t));
a61af66fc99e Initial load
duke
parents:
diff changeset
3852 ParmInfo.pc_cid = PC_CLNULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3853 rslt = (*priocntl_ptr)(PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
3854 if (rslt < 0) return errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3855
a61af66fc99e Initial load
duke
parents:
diff changeset
3856 if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3857 myMin = rtLimits.minPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3858 myMax = rtLimits.maxPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3859 } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3860 iaparms_t *iaInfo = (iaparms_t*)ParmInfo.pc_clparms;
a61af66fc99e Initial load
duke
parents:
diff changeset
3861 myMin = iaLimits.minPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3862 myMax = iaLimits.maxPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3863 myMax = MIN2(myMax, (int)iaInfo->ia_uprilim); // clamp - restrict
a61af66fc99e Initial load
duke
parents:
diff changeset
3864 } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3865 tsparms_t *tsInfo = (tsparms_t*)ParmInfo.pc_clparms;
a61af66fc99e Initial load
duke
parents:
diff changeset
3866 myMin = tsLimits.minPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3867 myMax = tsLimits.maxPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3868 myMax = MIN2(myMax, (int)tsInfo->ts_uprilim); // clamp - restrict
a61af66fc99e Initial load
duke
parents:
diff changeset
3869 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3870 // No clue - punt
a61af66fc99e Initial load
duke
parents:
diff changeset
3871 if (ThreadPriorityVerbose)
a61af66fc99e Initial load
duke
parents:
diff changeset
3872 tty->print_cr ("Unknown scheduling class: %s ... \n", ClassInfo.pc_clname);
a61af66fc99e Initial load
duke
parents:
diff changeset
3873 return EINVAL; // no clue, punt
a61af66fc99e Initial load
duke
parents:
diff changeset
3874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3875
a61af66fc99e Initial load
duke
parents:
diff changeset
3876 if (ThreadPriorityVerbose)
a61af66fc99e Initial load
duke
parents:
diff changeset
3877 tty->print_cr ("Thread priority Range: [%d..%d]\n", myMin, myMax);
a61af66fc99e Initial load
duke
parents:
diff changeset
3878
a61af66fc99e Initial load
duke
parents:
diff changeset
3879 priocntl_enable = true; // Enable changing priorities
a61af66fc99e Initial load
duke
parents:
diff changeset
3880 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3881 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3882
a61af66fc99e Initial load
duke
parents:
diff changeset
3883 #define IAPRI(x) ((iaparms_t *)((x).pc_clparms))
a61af66fc99e Initial load
duke
parents:
diff changeset
3884 #define RTPRI(x) ((rtparms_t *)((x).pc_clparms))
a61af66fc99e Initial load
duke
parents:
diff changeset
3885 #define TSPRI(x) ((tsparms_t *)((x).pc_clparms))
a61af66fc99e Initial load
duke
parents:
diff changeset
3886
a61af66fc99e Initial load
duke
parents:
diff changeset
3887
a61af66fc99e Initial load
duke
parents:
diff changeset
3888 // scale_to_lwp_priority
a61af66fc99e Initial load
duke
parents:
diff changeset
3889 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3890 // Convert from the libthread "thr_setprio" scale to our current
a61af66fc99e Initial load
duke
parents:
diff changeset
3891 // lwp scheduling class scale.
a61af66fc99e Initial load
duke
parents:
diff changeset
3892 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3893 static
a61af66fc99e Initial load
duke
parents:
diff changeset
3894 int scale_to_lwp_priority (int rMin, int rMax, int x)
a61af66fc99e Initial load
duke
parents:
diff changeset
3895 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3896 int v;
a61af66fc99e Initial load
duke
parents:
diff changeset
3897
a61af66fc99e Initial load
duke
parents:
diff changeset
3898 if (x == 127) return rMax; // avoid round-down
a61af66fc99e Initial load
duke
parents:
diff changeset
3899 v = (((x*(rMax-rMin)))/128)+rMin;
a61af66fc99e Initial load
duke
parents:
diff changeset
3900 return v;
a61af66fc99e Initial load
duke
parents:
diff changeset
3901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3902
a61af66fc99e Initial load
duke
parents:
diff changeset
3903
a61af66fc99e Initial load
duke
parents:
diff changeset
3904 // set_lwp_priority
a61af66fc99e Initial load
duke
parents:
diff changeset
3905 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3906 // Set the priority of the lwp. This call should only be made
a61af66fc99e Initial load
duke
parents:
diff changeset
3907 // when using bound threads (T2 threads are bound by default).
a61af66fc99e Initial load
duke
parents:
diff changeset
3908 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3909 int set_lwp_priority (int ThreadID, int lwpid, int newPrio )
a61af66fc99e Initial load
duke
parents:
diff changeset
3910 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3911 int rslt;
a61af66fc99e Initial load
duke
parents:
diff changeset
3912 int Actual, Expected, prv;
a61af66fc99e Initial load
duke
parents:
diff changeset
3913 pcparms_t ParmInfo; // for GET-SET
a61af66fc99e Initial load
duke
parents:
diff changeset
3914 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3915 pcparms_t ReadBack; // for readback
a61af66fc99e Initial load
duke
parents:
diff changeset
3916 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3917
a61af66fc99e Initial load
duke
parents:
diff changeset
3918 // Set priority via PC_GETPARMS, update, PC_SETPARMS
a61af66fc99e Initial load
duke
parents:
diff changeset
3919 // Query current values.
a61af66fc99e Initial load
duke
parents:
diff changeset
3920 // TODO: accelerate this by eliminating the PC_GETPARMS call.
a61af66fc99e Initial load
duke
parents:
diff changeset
3921 // Cache "pcparms_t" in global ParmCache.
a61af66fc99e Initial load
duke
parents:
diff changeset
3922 // TODO: elide set-to-same-value
a61af66fc99e Initial load
duke
parents:
diff changeset
3923
a61af66fc99e Initial load
duke
parents:
diff changeset
3924 // If something went wrong on init, don't change priorities.
a61af66fc99e Initial load
duke
parents:
diff changeset
3925 if ( !priocntl_enable ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3926 if (ThreadPriorityVerbose)
a61af66fc99e Initial load
duke
parents:
diff changeset
3927 tty->print_cr("Trying to set priority but init failed, ignoring");
a61af66fc99e Initial load
duke
parents:
diff changeset
3928 return EINVAL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3929 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3930
a61af66fc99e Initial load
duke
parents:
diff changeset
3931
a61af66fc99e Initial load
duke
parents:
diff changeset
3932 // If lwp hasn't started yet, just return
a61af66fc99e Initial load
duke
parents:
diff changeset
3933 // the _start routine will call us again.
a61af66fc99e Initial load
duke
parents:
diff changeset
3934 if ( lwpid <= 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3935 if (ThreadPriorityVerbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3936 tty->print_cr ("deferring the set_lwp_priority of thread " INTPTR_FORMAT " to %d, lwpid not set",
a61af66fc99e Initial load
duke
parents:
diff changeset
3937 ThreadID, newPrio);
a61af66fc99e Initial load
duke
parents:
diff changeset
3938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3939 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3940 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3941
a61af66fc99e Initial load
duke
parents:
diff changeset
3942 if (ThreadPriorityVerbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3943 tty->print_cr ("set_lwp_priority(" INTPTR_FORMAT "@" INTPTR_FORMAT " %d) ",
a61af66fc99e Initial load
duke
parents:
diff changeset
3944 ThreadID, lwpid, newPrio);
a61af66fc99e Initial load
duke
parents:
diff changeset
3945 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3946
a61af66fc99e Initial load
duke
parents:
diff changeset
3947 memset(&ParmInfo, 0, sizeof(pcparms_t));
a61af66fc99e Initial load
duke
parents:
diff changeset
3948 ParmInfo.pc_cid = PC_CLNULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3949 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
3950 if (rslt < 0) return errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3951
a61af66fc99e Initial load
duke
parents:
diff changeset
3952 if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3953 rtparms_t *rtInfo = (rtparms_t*)ParmInfo.pc_clparms;
a61af66fc99e Initial load
duke
parents:
diff changeset
3954 rtInfo->rt_pri = scale_to_lwp_priority (rtLimits.minPrio, rtLimits.maxPrio, newPrio);
a61af66fc99e Initial load
duke
parents:
diff changeset
3955 rtInfo->rt_tqsecs = RT_NOCHANGE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3956 rtInfo->rt_tqnsecs = RT_NOCHANGE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3957 if (ThreadPriorityVerbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3958 tty->print_cr("RT: %d->%d\n", newPrio, rtInfo->rt_pri);
a61af66fc99e Initial load
duke
parents:
diff changeset
3959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3960 } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3961 iaparms_t *iaInfo = (iaparms_t*)ParmInfo.pc_clparms;
a61af66fc99e Initial load
duke
parents:
diff changeset
3962 int maxClamped = MIN2(iaLimits.maxPrio, (int)iaInfo->ia_uprilim);
a61af66fc99e Initial load
duke
parents:
diff changeset
3963 iaInfo->ia_upri = scale_to_lwp_priority(iaLimits.minPrio, maxClamped, newPrio);
a61af66fc99e Initial load
duke
parents:
diff changeset
3964 iaInfo->ia_uprilim = IA_NOCHANGE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3965 iaInfo->ia_mode = IA_NOCHANGE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3966 if (ThreadPriorityVerbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3967 tty->print_cr ("IA: [%d...%d] %d->%d\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
3968 iaLimits.minPrio, maxClamped, newPrio, iaInfo->ia_upri);
a61af66fc99e Initial load
duke
parents:
diff changeset
3969 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3970 } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3971 tsparms_t *tsInfo = (tsparms_t*)ParmInfo.pc_clparms;
a61af66fc99e Initial load
duke
parents:
diff changeset
3972 int maxClamped = MIN2(tsLimits.maxPrio, (int)tsInfo->ts_uprilim);
a61af66fc99e Initial load
duke
parents:
diff changeset
3973 prv = tsInfo->ts_upri;
a61af66fc99e Initial load
duke
parents:
diff changeset
3974 tsInfo->ts_upri = scale_to_lwp_priority(tsLimits.minPrio, maxClamped, newPrio);
a61af66fc99e Initial load
duke
parents:
diff changeset
3975 tsInfo->ts_uprilim = IA_NOCHANGE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3976 if (ThreadPriorityVerbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3977 tty->print_cr ("TS: %d [%d...%d] %d->%d\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
3978 prv, tsLimits.minPrio, maxClamped, newPrio, tsInfo->ts_upri);
a61af66fc99e Initial load
duke
parents:
diff changeset
3979 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3980 if (prv == tsInfo->ts_upri) return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3981 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3982 if ( ThreadPriorityVerbose ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3983 tty->print_cr ("Unknown scheduling class\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3984 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3985 return EINVAL; // no clue, punt
a61af66fc99e Initial load
duke
parents:
diff changeset
3986 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3987
a61af66fc99e Initial load
duke
parents:
diff changeset
3988 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
3989 if (ThreadPriorityVerbose && rslt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3990 tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno);
a61af66fc99e Initial load
duke
parents:
diff changeset
3991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3992 if (rslt < 0) return errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3993
a61af66fc99e Initial load
duke
parents:
diff changeset
3994 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3995 // Sanity check: read back what we just attempted to set.
a61af66fc99e Initial load
duke
parents:
diff changeset
3996 // In theory it could have changed in the interim ...
a61af66fc99e Initial load
duke
parents:
diff changeset
3997 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3998 // The priocntl system call is tricky.
a61af66fc99e Initial load
duke
parents:
diff changeset
3999 // Sometimes it'll validate the priority value argument and
a61af66fc99e Initial load
duke
parents:
diff changeset
4000 // return EINVAL if unhappy. At other times it fails silently.
a61af66fc99e Initial load
duke
parents:
diff changeset
4001 // Readbacks are prudent.
a61af66fc99e Initial load
duke
parents:
diff changeset
4002
a61af66fc99e Initial load
duke
parents:
diff changeset
4003 if (!ReadBackValidate) return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4004
a61af66fc99e Initial load
duke
parents:
diff changeset
4005 memset(&ReadBack, 0, sizeof(pcparms_t));
a61af66fc99e Initial load
duke
parents:
diff changeset
4006 ReadBack.pc_cid = PC_CLNULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4007 rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack);
a61af66fc99e Initial load
duke
parents:
diff changeset
4008 assert(rslt >= 0, "priocntl failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
4009 Actual = Expected = 0xBAD;
a61af66fc99e Initial load
duke
parents:
diff changeset
4010 assert(ParmInfo.pc_cid == ReadBack.pc_cid, "cid's don't match");
a61af66fc99e Initial load
duke
parents:
diff changeset
4011 if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4012 Actual = RTPRI(ReadBack)->rt_pri;
a61af66fc99e Initial load
duke
parents:
diff changeset
4013 Expected = RTPRI(ParmInfo)->rt_pri;
a61af66fc99e Initial load
duke
parents:
diff changeset
4014 } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4015 Actual = IAPRI(ReadBack)->ia_upri;
a61af66fc99e Initial load
duke
parents:
diff changeset
4016 Expected = IAPRI(ParmInfo)->ia_upri;
a61af66fc99e Initial load
duke
parents:
diff changeset
4017 } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4018 Actual = TSPRI(ReadBack)->ts_upri;
a61af66fc99e Initial load
duke
parents:
diff changeset
4019 Expected = TSPRI(ParmInfo)->ts_upri;
a61af66fc99e Initial load
duke
parents:
diff changeset
4020 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4021 if ( ThreadPriorityVerbose ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4022 tty->print_cr("set_lwp_priority: unexpected class in readback: %d\n", ParmInfo.pc_cid);
a61af66fc99e Initial load
duke
parents:
diff changeset
4023 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4024 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4025
a61af66fc99e Initial load
duke
parents:
diff changeset
4026 if (Actual != Expected) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4027 if ( ThreadPriorityVerbose ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4028 tty->print_cr ("set_lwp_priority(%d %d) Class=%d: actual=%d vs expected=%d\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
4029 lwpid, newPrio, ReadBack.pc_cid, Actual, Expected);
a61af66fc99e Initial load
duke
parents:
diff changeset
4030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4031 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4032 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4033
a61af66fc99e Initial load
duke
parents:
diff changeset
4034 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4035 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4036
a61af66fc99e Initial load
duke
parents:
diff changeset
4037
a61af66fc99e Initial load
duke
parents:
diff changeset
4038
a61af66fc99e Initial load
duke
parents:
diff changeset
4039 // Solaris only gives access to 128 real priorities at a time,
a61af66fc99e Initial load
duke
parents:
diff changeset
4040 // so we expand Java's ten to fill this range. This would be better
a61af66fc99e Initial load
duke
parents:
diff changeset
4041 // if we dynamically adjusted relative priorities.
a61af66fc99e Initial load
duke
parents:
diff changeset
4042 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4043 // The ThreadPriorityPolicy option allows us to select 2 different
a61af66fc99e Initial load
duke
parents:
diff changeset
4044 // priority scales.
a61af66fc99e Initial load
duke
parents:
diff changeset
4045 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4046 // ThreadPriorityPolicy=0
a61af66fc99e Initial load
duke
parents:
diff changeset
4047 // Since the Solaris' default priority is MaximumPriority, we do not
a61af66fc99e Initial load
duke
parents:
diff changeset
4048 // set a priority lower than Max unless a priority lower than
a61af66fc99e Initial load
duke
parents:
diff changeset
4049 // NormPriority is requested.
a61af66fc99e Initial load
duke
parents:
diff changeset
4050 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4051 // ThreadPriorityPolicy=1
a61af66fc99e Initial load
duke
parents:
diff changeset
4052 // This mode causes the priority table to get filled with
a61af66fc99e Initial load
duke
parents:
diff changeset
4053 // linear values. NormPriority get's mapped to 50% of the
a61af66fc99e Initial load
duke
parents:
diff changeset
4054 // Maximum priority an so on. This will cause VM threads
a61af66fc99e Initial load
duke
parents:
diff changeset
4055 // to get unfair treatment against other Solaris processes
a61af66fc99e Initial load
duke
parents:
diff changeset
4056 // which do not explicitly alter their thread priorities.
a61af66fc99e Initial load
duke
parents:
diff changeset
4057 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4058
a61af66fc99e Initial load
duke
parents:
diff changeset
4059
a61af66fc99e Initial load
duke
parents:
diff changeset
4060 int os::java_to_os_priority[MaxPriority + 1] = {
a61af66fc99e Initial load
duke
parents:
diff changeset
4061 -99999, // 0 Entry should never be used
a61af66fc99e Initial load
duke
parents:
diff changeset
4062
a61af66fc99e Initial load
duke
parents:
diff changeset
4063 0, // 1 MinPriority
a61af66fc99e Initial load
duke
parents:
diff changeset
4064 32, // 2
a61af66fc99e Initial load
duke
parents:
diff changeset
4065 64, // 3
a61af66fc99e Initial load
duke
parents:
diff changeset
4066
a61af66fc99e Initial load
duke
parents:
diff changeset
4067 96, // 4
a61af66fc99e Initial load
duke
parents:
diff changeset
4068 127, // 5 NormPriority
a61af66fc99e Initial load
duke
parents:
diff changeset
4069 127, // 6
a61af66fc99e Initial load
duke
parents:
diff changeset
4070
a61af66fc99e Initial load
duke
parents:
diff changeset
4071 127, // 7
a61af66fc99e Initial load
duke
parents:
diff changeset
4072 127, // 8
a61af66fc99e Initial load
duke
parents:
diff changeset
4073 127, // 9 NearMaxPriority
a61af66fc99e Initial load
duke
parents:
diff changeset
4074
a61af66fc99e Initial load
duke
parents:
diff changeset
4075 127 // 10 MaxPriority
a61af66fc99e Initial load
duke
parents:
diff changeset
4076 };
a61af66fc99e Initial load
duke
parents:
diff changeset
4077
a61af66fc99e Initial load
duke
parents:
diff changeset
4078
a61af66fc99e Initial load
duke
parents:
diff changeset
4079 OSReturn os::set_native_priority(Thread* thread, int newpri) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4080 assert(newpri >= MinimumPriority && newpri <= MaximumPriority, "bad priority mapping");
a61af66fc99e Initial load
duke
parents:
diff changeset
4081 if ( !UseThreadPriorities ) return OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
4082 int status = thr_setprio(thread->osthread()->thread_id(), newpri);
a61af66fc99e Initial load
duke
parents:
diff changeset
4083 if ( os::Solaris::T2_libthread() || (UseBoundThreads && thread->osthread()->is_vm_created()) )
a61af66fc99e Initial load
duke
parents:
diff changeset
4084 status |= (set_lwp_priority (thread->osthread()->thread_id(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4085 thread->osthread()->lwp_id(), newpri ));
a61af66fc99e Initial load
duke
parents:
diff changeset
4086 return (status == 0) ? OS_OK : OS_ERR;
a61af66fc99e Initial load
duke
parents:
diff changeset
4087 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4088
a61af66fc99e Initial load
duke
parents:
diff changeset
4089
a61af66fc99e Initial load
duke
parents:
diff changeset
4090 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4091 int p;
a61af66fc99e Initial load
duke
parents:
diff changeset
4092 if ( !UseThreadPriorities ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4093 *priority_ptr = NormalPriority;
a61af66fc99e Initial load
duke
parents:
diff changeset
4094 return OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
4095 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4096 int status = thr_getprio(thread->osthread()->thread_id(), &p);
a61af66fc99e Initial load
duke
parents:
diff changeset
4097 if (status != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4098 return OS_ERR;
a61af66fc99e Initial load
duke
parents:
diff changeset
4099 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4100 *priority_ptr = p;
a61af66fc99e Initial load
duke
parents:
diff changeset
4101 return OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
4102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4103
a61af66fc99e Initial load
duke
parents:
diff changeset
4104
a61af66fc99e Initial load
duke
parents:
diff changeset
4105 // Hint to the underlying OS that a task switch would not be good.
a61af66fc99e Initial load
duke
parents:
diff changeset
4106 // Void return because it's a hint and can fail.
a61af66fc99e Initial load
duke
parents:
diff changeset
4107 void os::hint_no_preempt() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4108 schedctl_start(schedctl_init());
a61af66fc99e Initial load
duke
parents:
diff changeset
4109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4110
a61af66fc99e Initial load
duke
parents:
diff changeset
4111 void os::interrupt(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4112 assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer");
a61af66fc99e Initial load
duke
parents:
diff changeset
4113
a61af66fc99e Initial load
duke
parents:
diff changeset
4114 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
4115
a61af66fc99e Initial load
duke
parents:
diff changeset
4116 int isInterrupted = osthread->interrupted();
a61af66fc99e Initial load
duke
parents:
diff changeset
4117 if (!isInterrupted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4118 osthread->set_interrupted(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4119 OrderAccess::fence();
a61af66fc99e Initial load
duke
parents:
diff changeset
4120 // os::sleep() is implemented with either poll (NULL,0,timeout) or
a61af66fc99e Initial load
duke
parents:
diff changeset
4121 // by parking on _SleepEvent. If the former, thr_kill will unwedge
a61af66fc99e Initial load
duke
parents:
diff changeset
4122 // the sleeper by SIGINTR, otherwise the unpark() will wake the sleeper.
a61af66fc99e Initial load
duke
parents:
diff changeset
4123 ParkEvent * const slp = thread->_SleepEvent ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4124 if (slp != NULL) slp->unpark() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4126
a61af66fc99e Initial load
duke
parents:
diff changeset
4127 // For JSR166: unpark after setting status but before thr_kill -dl
a61af66fc99e Initial load
duke
parents:
diff changeset
4128 if (thread->is_Java_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4129 ((JavaThread*)thread)->parker()->unpark();
a61af66fc99e Initial load
duke
parents:
diff changeset
4130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4131
a61af66fc99e Initial load
duke
parents:
diff changeset
4132 // Handle interruptible wait() ...
a61af66fc99e Initial load
duke
parents:
diff changeset
4133 ParkEvent * const ev = thread->_ParkEvent ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4134 if (ev != NULL) ev->unpark() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4135
a61af66fc99e Initial load
duke
parents:
diff changeset
4136 // When events are used everywhere for os::sleep, then this thr_kill
a61af66fc99e Initial load
duke
parents:
diff changeset
4137 // will only be needed if UseVMInterruptibleIO is true.
a61af66fc99e Initial load
duke
parents:
diff changeset
4138
a61af66fc99e Initial load
duke
parents:
diff changeset
4139 if (!isInterrupted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4140 int status = thr_kill(osthread->thread_id(), os::Solaris::SIGinterrupt());
a61af66fc99e Initial load
duke
parents:
diff changeset
4141 assert_status(status == 0, status, "thr_kill");
a61af66fc99e Initial load
duke
parents:
diff changeset
4142
a61af66fc99e Initial load
duke
parents:
diff changeset
4143 // Bump thread interruption counter
a61af66fc99e Initial load
duke
parents:
diff changeset
4144 RuntimeService::record_thread_interrupt_signaled_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
4145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4147
a61af66fc99e Initial load
duke
parents:
diff changeset
4148
a61af66fc99e Initial load
duke
parents:
diff changeset
4149 bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4150 assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer");
a61af66fc99e Initial load
duke
parents:
diff changeset
4151
a61af66fc99e Initial load
duke
parents:
diff changeset
4152 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
4153
a61af66fc99e Initial load
duke
parents:
diff changeset
4154 bool res = osthread->interrupted();
a61af66fc99e Initial load
duke
parents:
diff changeset
4155
a61af66fc99e Initial load
duke
parents:
diff changeset
4156 // NOTE that since there is no "lock" around these two operations,
a61af66fc99e Initial load
duke
parents:
diff changeset
4157 // there is the possibility that the interrupted flag will be
a61af66fc99e Initial load
duke
parents:
diff changeset
4158 // "false" but that the interrupt event will be set. This is
a61af66fc99e Initial load
duke
parents:
diff changeset
4159 // intentional. The effect of this is that Object.wait() will appear
a61af66fc99e Initial load
duke
parents:
diff changeset
4160 // to have a spurious wakeup, which is not harmful, and the
a61af66fc99e Initial load
duke
parents:
diff changeset
4161 // possibility is so rare that it is not worth the added complexity
a61af66fc99e Initial load
duke
parents:
diff changeset
4162 // to add yet another lock. It has also been recommended not to put
a61af66fc99e Initial load
duke
parents:
diff changeset
4163 // the interrupted flag into the os::Solaris::Event structure,
a61af66fc99e Initial load
duke
parents:
diff changeset
4164 // because it hides the issue.
a61af66fc99e Initial load
duke
parents:
diff changeset
4165 if (res && clear_interrupted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4166 osthread->set_interrupted(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
4167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4168 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
4169 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4170
a61af66fc99e Initial load
duke
parents:
diff changeset
4171
a61af66fc99e Initial load
duke
parents:
diff changeset
4172 void os::print_statistics() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4174
a61af66fc99e Initial load
duke
parents:
diff changeset
4175 int os::message_box(const char* title, const char* message) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4176 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
4177 fdStream err(defaultStream::error_fd());
a61af66fc99e Initial load
duke
parents:
diff changeset
4178 for (i = 0; i < 78; i++) err.print_raw("=");
a61af66fc99e Initial load
duke
parents:
diff changeset
4179 err.cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4180 err.print_raw_cr(title);
a61af66fc99e Initial load
duke
parents:
diff changeset
4181 for (i = 0; i < 78; i++) err.print_raw("-");
a61af66fc99e Initial load
duke
parents:
diff changeset
4182 err.cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4183 err.print_raw_cr(message);
a61af66fc99e Initial load
duke
parents:
diff changeset
4184 for (i = 0; i < 78; i++) err.print_raw("=");
a61af66fc99e Initial load
duke
parents:
diff changeset
4185 err.cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4186
a61af66fc99e Initial load
duke
parents:
diff changeset
4187 char buf[16];
a61af66fc99e Initial load
duke
parents:
diff changeset
4188 // Prevent process from exiting upon "read error" without consuming all CPU
a61af66fc99e Initial load
duke
parents:
diff changeset
4189 while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); }
a61af66fc99e Initial load
duke
parents:
diff changeset
4190
a61af66fc99e Initial load
duke
parents:
diff changeset
4191 return buf[0] == 'y' || buf[0] == 'Y';
a61af66fc99e Initial load
duke
parents:
diff changeset
4192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4193
a61af66fc99e Initial load
duke
parents:
diff changeset
4194 // A lightweight implementation that does not suspend the target thread and
a61af66fc99e Initial load
duke
parents:
diff changeset
4195 // thus returns only a hint. Used for profiling only!
a61af66fc99e Initial load
duke
parents:
diff changeset
4196 ExtendedPC os::get_thread_pc(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4197 // Make sure that it is called by the watcher and the Threads lock is owned.
a61af66fc99e Initial load
duke
parents:
diff changeset
4198 assert(Thread::current()->is_Watcher_thread(), "Must be watcher and own Threads_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
4199 // For now, is only used to profile the VM Thread
a61af66fc99e Initial load
duke
parents:
diff changeset
4200 assert(thread->is_VM_thread(), "Can only be called for VMThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
4201 ExtendedPC epc;
a61af66fc99e Initial load
duke
parents:
diff changeset
4202
a61af66fc99e Initial load
duke
parents:
diff changeset
4203 GetThreadPC_Callback cb(ProfileVM_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
4204 OSThread *osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
4205 const int time_to_wait = 400; // 400ms wait for initial response
a61af66fc99e Initial load
duke
parents:
diff changeset
4206 int status = cb.interrupt(thread, time_to_wait);
a61af66fc99e Initial load
duke
parents:
diff changeset
4207
a61af66fc99e Initial load
duke
parents:
diff changeset
4208 if (cb.is_done() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4209 epc = cb.addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4210 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4211 DEBUG_ONLY(tty->print_cr("Failed to get pc for thread: %d got %d status",
a61af66fc99e Initial load
duke
parents:
diff changeset
4212 osthread->thread_id(), status););
a61af66fc99e Initial load
duke
parents:
diff changeset
4213 // epc is already NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
4214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4215 return epc;
a61af66fc99e Initial load
duke
parents:
diff changeset
4216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4217
a61af66fc99e Initial load
duke
parents:
diff changeset
4218
a61af66fc99e Initial load
duke
parents:
diff changeset
4219 // This does not do anything on Solaris. This is basically a hook for being
a61af66fc99e Initial load
duke
parents:
diff changeset
4220 // able to use structured exception handling (thread-local exception filters) on, e.g., Win32.
a61af66fc99e Initial load
duke
parents:
diff changeset
4221 void os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4222 f(value, method, args, thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
4223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4224
a61af66fc99e Initial load
duke
parents:
diff changeset
4225 // This routine may be used by user applications as a "hook" to catch signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
4226 // The user-defined signal handler must pass unrecognized signals to this
a61af66fc99e Initial load
duke
parents:
diff changeset
4227 // routine, and if it returns true (non-zero), then the signal handler must
a61af66fc99e Initial load
duke
parents:
diff changeset
4228 // return immediately. If the flag "abort_if_unrecognized" is true, then this
a61af66fc99e Initial load
duke
parents:
diff changeset
4229 // routine will never retun false (zero), but instead will execute a VM panic
a61af66fc99e Initial load
duke
parents:
diff changeset
4230 // routine kill the process.
a61af66fc99e Initial load
duke
parents:
diff changeset
4231 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4232 // If this routine returns false, it is OK to call it again. This allows
a61af66fc99e Initial load
duke
parents:
diff changeset
4233 // the user-defined signal handler to perform checks either before or after
a61af66fc99e Initial load
duke
parents:
diff changeset
4234 // the VM performs its own checks. Naturally, the user code would be making
a61af66fc99e Initial load
duke
parents:
diff changeset
4235 // a serious error if it tried to handle an exception (such as a null check
a61af66fc99e Initial load
duke
parents:
diff changeset
4236 // or breakpoint) that the VM was generating for its own correct operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
4237 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4238 // This routine may recognize any of the following kinds of signals:
a61af66fc99e Initial load
duke
parents:
diff changeset
4239 // SIGBUS, SIGSEGV, SIGILL, SIGFPE, BREAK_SIGNAL, SIGPIPE, SIGXFSZ,
a61af66fc99e Initial load
duke
parents:
diff changeset
4240 // os::Solaris::SIGasync
a61af66fc99e Initial load
duke
parents:
diff changeset
4241 // It should be consulted by handlers for any of those signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
4242 // It explicitly does not recognize os::Solaris::SIGinterrupt
a61af66fc99e Initial load
duke
parents:
diff changeset
4243 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4244 // The caller of this routine must pass in the three arguments supplied
a61af66fc99e Initial load
duke
parents:
diff changeset
4245 // to the function referred to in the "sa_sigaction" (not the "sa_handler")
a61af66fc99e Initial load
duke
parents:
diff changeset
4246 // field of the structure passed to sigaction(). This routine assumes that
a61af66fc99e Initial load
duke
parents:
diff changeset
4247 // the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART.
a61af66fc99e Initial load
duke
parents:
diff changeset
4248 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4249 // Note that the VM will print warnings if it detects conflicting signal
a61af66fc99e Initial load
duke
parents:
diff changeset
4250 // handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers".
a61af66fc99e Initial load
duke
parents:
diff changeset
4251 //
2191
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
4252 extern "C" JNIEXPORT int
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
4253 JVM_handle_solaris_signal(int signo, siginfo_t* siginfo, void* ucontext,
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
4254 int abort_if_unrecognized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4255
a61af66fc99e Initial load
duke
parents:
diff changeset
4256
a61af66fc99e Initial load
duke
parents:
diff changeset
4257 void signalHandler(int sig, siginfo_t* info, void* ucVoid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4258 JVM_handle_solaris_signal(sig, info, ucVoid, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4260
a61af66fc99e Initial load
duke
parents:
diff changeset
4261 /* Do not delete - if guarantee is ever removed, a signal handler (even empty)
a61af66fc99e Initial load
duke
parents:
diff changeset
4262 is needed to provoke threads blocked on IO to return an EINTR
a61af66fc99e Initial load
duke
parents:
diff changeset
4263 Note: this explicitly does NOT call JVM_handle_solaris_signal and
a61af66fc99e Initial load
duke
parents:
diff changeset
4264 does NOT participate in signal chaining due to requirement for
a61af66fc99e Initial load
duke
parents:
diff changeset
4265 NOT setting SA_RESTART to make EINTR work. */
a61af66fc99e Initial load
duke
parents:
diff changeset
4266 extern "C" void sigINTRHandler(int sig, siginfo_t* info, void* ucVoid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4267 if (UseSignalChaining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4268 struct sigaction *actp = os::Solaris::get_chained_signal_action(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4269 if (actp && actp->sa_handler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4270 vm_exit_during_initialization("Signal chaining detected for VM interrupt signal, try -XX:+UseAltSigs");
a61af66fc99e Initial load
duke
parents:
diff changeset
4271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4274
a61af66fc99e Initial load
duke
parents:
diff changeset
4275 // This boolean allows users to forward their own non-matching signals
a61af66fc99e Initial load
duke
parents:
diff changeset
4276 // to JVM_handle_solaris_signal, harmlessly.
a61af66fc99e Initial load
duke
parents:
diff changeset
4277 bool os::Solaris::signal_handlers_are_installed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4278
a61af66fc99e Initial load
duke
parents:
diff changeset
4279 // For signal-chaining
a61af66fc99e Initial load
duke
parents:
diff changeset
4280 bool os::Solaris::libjsig_is_loaded = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4281 typedef struct sigaction *(*get_signal_t)(int);
a61af66fc99e Initial load
duke
parents:
diff changeset
4282 get_signal_t os::Solaris::get_signal_action = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4283
a61af66fc99e Initial load
duke
parents:
diff changeset
4284 struct sigaction* os::Solaris::get_chained_signal_action(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4285 struct sigaction *actp = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4286
a61af66fc99e Initial load
duke
parents:
diff changeset
4287 if ((libjsig_is_loaded) && (sig <= Maxlibjsigsigs)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4288 // Retrieve the old signal handler from libjsig
a61af66fc99e Initial load
duke
parents:
diff changeset
4289 actp = (*get_signal_action)(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4290 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4291 if (actp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4292 // Retrieve the preinstalled signal handler from jvm
a61af66fc99e Initial load
duke
parents:
diff changeset
4293 actp = get_preinstalled_handler(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4295
a61af66fc99e Initial load
duke
parents:
diff changeset
4296 return actp;
a61af66fc99e Initial load
duke
parents:
diff changeset
4297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4298
a61af66fc99e Initial load
duke
parents:
diff changeset
4299 static bool call_chained_handler(struct sigaction *actp, int sig,
a61af66fc99e Initial load
duke
parents:
diff changeset
4300 siginfo_t *siginfo, void *context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4301 // Call the old signal handler
a61af66fc99e Initial load
duke
parents:
diff changeset
4302 if (actp->sa_handler == SIG_DFL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4303 // It's more reasonable to let jvm treat it as an unexpected exception
a61af66fc99e Initial load
duke
parents:
diff changeset
4304 // instead of taking the default action.
a61af66fc99e Initial load
duke
parents:
diff changeset
4305 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4306 } else if (actp->sa_handler != SIG_IGN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4307 if ((actp->sa_flags & SA_NODEFER) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4308 // automaticlly block the signal
a61af66fc99e Initial load
duke
parents:
diff changeset
4309 sigaddset(&(actp->sa_mask), sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4311
a61af66fc99e Initial load
duke
parents:
diff changeset
4312 sa_handler_t hand;
a61af66fc99e Initial load
duke
parents:
diff changeset
4313 sa_sigaction_t sa;
a61af66fc99e Initial load
duke
parents:
diff changeset
4314 bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4315 // retrieve the chained handler
a61af66fc99e Initial load
duke
parents:
diff changeset
4316 if (siginfo_flag_set) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4317 sa = actp->sa_sigaction;
a61af66fc99e Initial load
duke
parents:
diff changeset
4318 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4319 hand = actp->sa_handler;
a61af66fc99e Initial load
duke
parents:
diff changeset
4320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4321
a61af66fc99e Initial load
duke
parents:
diff changeset
4322 if ((actp->sa_flags & SA_RESETHAND) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4323 actp->sa_handler = SIG_DFL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4325
a61af66fc99e Initial load
duke
parents:
diff changeset
4326 // try to honor the signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
4327 sigset_t oset;
a61af66fc99e Initial load
duke
parents:
diff changeset
4328 thr_sigsetmask(SIG_SETMASK, &(actp->sa_mask), &oset);
a61af66fc99e Initial load
duke
parents:
diff changeset
4329
a61af66fc99e Initial load
duke
parents:
diff changeset
4330 // call into the chained handler
a61af66fc99e Initial load
duke
parents:
diff changeset
4331 if (siginfo_flag_set) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4332 (*sa)(sig, siginfo, context);
a61af66fc99e Initial load
duke
parents:
diff changeset
4333 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4334 (*hand)(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4336
a61af66fc99e Initial load
duke
parents:
diff changeset
4337 // restore the signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
4338 thr_sigsetmask(SIG_SETMASK, &oset, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4340 // Tell jvm's signal handler the signal is taken care of.
a61af66fc99e Initial load
duke
parents:
diff changeset
4341 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4343
a61af66fc99e Initial load
duke
parents:
diff changeset
4344 bool os::Solaris::chained_handler(int sig, siginfo_t* siginfo, void* context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4345 bool chained = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4346 // signal-chaining
a61af66fc99e Initial load
duke
parents:
diff changeset
4347 if (UseSignalChaining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4348 struct sigaction *actp = get_chained_signal_action(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4349 if (actp != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4350 chained = call_chained_handler(actp, sig, siginfo, context);
a61af66fc99e Initial load
duke
parents:
diff changeset
4351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4353 return chained;
a61af66fc99e Initial load
duke
parents:
diff changeset
4354 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4355
a61af66fc99e Initial load
duke
parents:
diff changeset
4356 struct sigaction* os::Solaris::get_preinstalled_handler(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4357 assert((chainedsigactions != (struct sigaction *)NULL) && (preinstalled_sigs != (int *)NULL) , "signals not yet initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
4358 if (preinstalled_sigs[sig] != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4359 return &chainedsigactions[sig];
a61af66fc99e Initial load
duke
parents:
diff changeset
4360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4361 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4363
a61af66fc99e Initial load
duke
parents:
diff changeset
4364 void os::Solaris::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4365
a61af66fc99e Initial load
duke
parents:
diff changeset
4366 assert(sig > 0 && sig <= Maxsignum, "vm signal out of expected range");
a61af66fc99e Initial load
duke
parents:
diff changeset
4367 assert((chainedsigactions != (struct sigaction *)NULL) && (preinstalled_sigs != (int *)NULL) , "signals not yet initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
4368 chainedsigactions[sig] = oldAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
4369 preinstalled_sigs[sig] = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4371
a61af66fc99e Initial load
duke
parents:
diff changeset
4372 void os::Solaris::set_signal_handler(int sig, bool set_installed, bool oktochain) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4373 // Check for overwrite.
a61af66fc99e Initial load
duke
parents:
diff changeset
4374 struct sigaction oldAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
4375 sigaction(sig, (struct sigaction*)NULL, &oldAct);
a61af66fc99e Initial load
duke
parents:
diff changeset
4376 void* oldhand = oldAct.sa_sigaction ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
4377 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4378 if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
4379 oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
4380 oldhand != CAST_FROM_FN_PTR(void*, signalHandler)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4381 if (AllowUserSignalHandlers || !set_installed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4382 // Do not overwrite; user takes responsibility to forward to us.
a61af66fc99e Initial load
duke
parents:
diff changeset
4383 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
4384 } else if (UseSignalChaining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4385 if (oktochain) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4386 // save the old handler in jvm
a61af66fc99e Initial load
duke
parents:
diff changeset
4387 save_preinstalled_handler(sig, oldAct);
a61af66fc99e Initial load
duke
parents:
diff changeset
4388 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4389 vm_exit_during_initialization("Signal chaining not allowed for VM interrupt signal, try -XX:+UseAltSigs.");
a61af66fc99e Initial load
duke
parents:
diff changeset
4390 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4391 // libjsig also interposes the sigaction() call below and saves the
a61af66fc99e Initial load
duke
parents:
diff changeset
4392 // old sigaction on it own.
a61af66fc99e Initial load
duke
parents:
diff changeset
4393 } else {
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
4394 fatal(err_msg("Encountered unexpected pre-existing sigaction handler "
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
4395 "%#lx for signal %d.", (long)oldhand, sig));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4398
a61af66fc99e Initial load
duke
parents:
diff changeset
4399 struct sigaction sigAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
4400 sigfillset(&(sigAct.sa_mask));
a61af66fc99e Initial load
duke
parents:
diff changeset
4401 sigAct.sa_handler = SIG_DFL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4402
a61af66fc99e Initial load
duke
parents:
diff changeset
4403 sigAct.sa_sigaction = signalHandler;
a61af66fc99e Initial load
duke
parents:
diff changeset
4404 // Handle SIGSEGV on alternate signal stack if
a61af66fc99e Initial load
duke
parents:
diff changeset
4405 // not using stack banging
a61af66fc99e Initial load
duke
parents:
diff changeset
4406 if (!UseStackBanging && sig == SIGSEGV) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4407 sigAct.sa_flags = SA_SIGINFO | SA_RESTART | SA_ONSTACK;
a61af66fc99e Initial load
duke
parents:
diff changeset
4408 // Interruptible i/o requires SA_RESTART cleared so EINTR
a61af66fc99e Initial load
duke
parents:
diff changeset
4409 // is returned instead of restarting system calls
a61af66fc99e Initial load
duke
parents:
diff changeset
4410 } else if (sig == os::Solaris::SIGinterrupt()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4411 sigemptyset(&sigAct.sa_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
4412 sigAct.sa_handler = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4413 sigAct.sa_flags = SA_SIGINFO;
a61af66fc99e Initial load
duke
parents:
diff changeset
4414 sigAct.sa_sigaction = sigINTRHandler;
a61af66fc99e Initial load
duke
parents:
diff changeset
4415 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4416 sigAct.sa_flags = SA_SIGINFO | SA_RESTART;
a61af66fc99e Initial load
duke
parents:
diff changeset
4417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4418 os::Solaris::set_our_sigflags(sig, sigAct.sa_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
4419
a61af66fc99e Initial load
duke
parents:
diff changeset
4420 sigaction(sig, &sigAct, &oldAct);
a61af66fc99e Initial load
duke
parents:
diff changeset
4421
a61af66fc99e Initial load
duke
parents:
diff changeset
4422 void* oldhand2 = oldAct.sa_sigaction ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
4423 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4424 assert(oldhand2 == oldhand, "no concurrent signal handler installation");
a61af66fc99e Initial load
duke
parents:
diff changeset
4425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4426
a61af66fc99e Initial load
duke
parents:
diff changeset
4427
a61af66fc99e Initial load
duke
parents:
diff changeset
4428 #define DO_SIGNAL_CHECK(sig) \
a61af66fc99e Initial load
duke
parents:
diff changeset
4429 if (!sigismember(&check_signal_done, sig)) \
a61af66fc99e Initial load
duke
parents:
diff changeset
4430 os::Solaris::check_signal_handler(sig)
a61af66fc99e Initial load
duke
parents:
diff changeset
4431
a61af66fc99e Initial load
duke
parents:
diff changeset
4432 // This method is a periodic task to check for misbehaving JNI applications
a61af66fc99e Initial load
duke
parents:
diff changeset
4433 // under CheckJNI, we can add any periodic checks here
a61af66fc99e Initial load
duke
parents:
diff changeset
4434
a61af66fc99e Initial load
duke
parents:
diff changeset
4435 void os::run_periodic_checks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4436 // A big source of grief is hijacking virt. addr 0x0 on Solaris,
a61af66fc99e Initial load
duke
parents:
diff changeset
4437 // thereby preventing a NULL checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
4438 if(!check_addr0_done) check_addr0_done = check_addr0(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
4439
a61af66fc99e Initial load
duke
parents:
diff changeset
4440 if (check_signals == false) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
4441
a61af66fc99e Initial load
duke
parents:
diff changeset
4442 // SEGV and BUS if overridden could potentially prevent
a61af66fc99e Initial load
duke
parents:
diff changeset
4443 // generation of hs*.log in the event of a crash, debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
4444 // such a case can be very challenging, so we absolutely
a61af66fc99e Initial load
duke
parents:
diff changeset
4445 // check for the following for a good measure:
a61af66fc99e Initial load
duke
parents:
diff changeset
4446 DO_SIGNAL_CHECK(SIGSEGV);
a61af66fc99e Initial load
duke
parents:
diff changeset
4447 DO_SIGNAL_CHECK(SIGILL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4448 DO_SIGNAL_CHECK(SIGFPE);
a61af66fc99e Initial load
duke
parents:
diff changeset
4449 DO_SIGNAL_CHECK(SIGBUS);
a61af66fc99e Initial load
duke
parents:
diff changeset
4450 DO_SIGNAL_CHECK(SIGPIPE);
a61af66fc99e Initial load
duke
parents:
diff changeset
4451 DO_SIGNAL_CHECK(SIGXFSZ);
a61af66fc99e Initial load
duke
parents:
diff changeset
4452
a61af66fc99e Initial load
duke
parents:
diff changeset
4453 // ReduceSignalUsage allows the user to override these handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
4454 // see comments at the very top and jvm_solaris.h
a61af66fc99e Initial load
duke
parents:
diff changeset
4455 if (!ReduceSignalUsage) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4456 DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4457 DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4458 DO_SIGNAL_CHECK(SHUTDOWN3_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4459 DO_SIGNAL_CHECK(BREAK_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4461
a61af66fc99e Initial load
duke
parents:
diff changeset
4462 // See comments above for using JVM1/JVM2 and UseAltSigs
a61af66fc99e Initial load
duke
parents:
diff changeset
4463 DO_SIGNAL_CHECK(os::Solaris::SIGinterrupt());
a61af66fc99e Initial load
duke
parents:
diff changeset
4464 DO_SIGNAL_CHECK(os::Solaris::SIGasync());
a61af66fc99e Initial load
duke
parents:
diff changeset
4465
a61af66fc99e Initial load
duke
parents:
diff changeset
4466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4467
a61af66fc99e Initial load
duke
parents:
diff changeset
4468 typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *);
a61af66fc99e Initial load
duke
parents:
diff changeset
4469
a61af66fc99e Initial load
duke
parents:
diff changeset
4470 static os_sigaction_t os_sigaction = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4471
a61af66fc99e Initial load
duke
parents:
diff changeset
4472 void os::Solaris::check_signal_handler(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4473 char buf[O_BUFLEN];
a61af66fc99e Initial load
duke
parents:
diff changeset
4474 address jvmHandler = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4475
a61af66fc99e Initial load
duke
parents:
diff changeset
4476 struct sigaction act;
a61af66fc99e Initial load
duke
parents:
diff changeset
4477 if (os_sigaction == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4478 // only trust the default sigaction, in case it has been interposed
a61af66fc99e Initial load
duke
parents:
diff changeset
4479 os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction");
a61af66fc99e Initial load
duke
parents:
diff changeset
4480 if (os_sigaction == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
4481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4482
a61af66fc99e Initial load
duke
parents:
diff changeset
4483 os_sigaction(sig, (struct sigaction*)NULL, &act);
a61af66fc99e Initial load
duke
parents:
diff changeset
4484
a61af66fc99e Initial load
duke
parents:
diff changeset
4485 address thisHandler = (act.sa_flags & SA_SIGINFO)
a61af66fc99e Initial load
duke
parents:
diff changeset
4486 ? CAST_FROM_FN_PTR(address, act.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
4487 : CAST_FROM_FN_PTR(address, act.sa_handler) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4488
a61af66fc99e Initial load
duke
parents:
diff changeset
4489
a61af66fc99e Initial load
duke
parents:
diff changeset
4490 switch(sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4491 case SIGSEGV:
a61af66fc99e Initial load
duke
parents:
diff changeset
4492 case SIGBUS:
a61af66fc99e Initial load
duke
parents:
diff changeset
4493 case SIGFPE:
a61af66fc99e Initial load
duke
parents:
diff changeset
4494 case SIGPIPE:
a61af66fc99e Initial load
duke
parents:
diff changeset
4495 case SIGXFSZ:
a61af66fc99e Initial load
duke
parents:
diff changeset
4496 case SIGILL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4497 jvmHandler = CAST_FROM_FN_PTR(address, signalHandler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4498 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4499
a61af66fc99e Initial load
duke
parents:
diff changeset
4500 case SHUTDOWN1_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4501 case SHUTDOWN2_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4502 case SHUTDOWN3_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4503 case BREAK_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4504 jvmHandler = (address)user_handler();
a61af66fc99e Initial load
duke
parents:
diff changeset
4505 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4506
a61af66fc99e Initial load
duke
parents:
diff changeset
4507 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
4508 int intrsig = os::Solaris::SIGinterrupt();
a61af66fc99e Initial load
duke
parents:
diff changeset
4509 int asynsig = os::Solaris::SIGasync();
a61af66fc99e Initial load
duke
parents:
diff changeset
4510
a61af66fc99e Initial load
duke
parents:
diff changeset
4511 if (sig == intrsig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4512 jvmHandler = CAST_FROM_FN_PTR(address, sigINTRHandler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4513 } else if (sig == asynsig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4514 jvmHandler = CAST_FROM_FN_PTR(address, signalHandler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4515 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4516 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
4517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4518 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4520
a61af66fc99e Initial load
duke
parents:
diff changeset
4521
a61af66fc99e Initial load
duke
parents:
diff changeset
4522 if (thisHandler != jvmHandler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4523 tty->print("Warning: %s handler ", exception_name(sig, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4524 tty->print("expected:%s", get_signal_handler_name(jvmHandler, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4525 tty->print_cr(" found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4526 // No need to check this sig any longer
a61af66fc99e Initial load
duke
parents:
diff changeset
4527 sigaddset(&check_signal_done, sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4528 } else if(os::Solaris::get_our_sigflags(sig) != 0 && act.sa_flags != os::Solaris::get_our_sigflags(sig)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4529 tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4530 tty->print("expected:" PTR32_FORMAT, os::Solaris::get_our_sigflags(sig));
a61af66fc99e Initial load
duke
parents:
diff changeset
4531 tty->print_cr(" found:" PTR32_FORMAT, act.sa_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
4532 // No need to check this sig any longer
a61af66fc99e Initial load
duke
parents:
diff changeset
4533 sigaddset(&check_signal_done, sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4535
a61af66fc99e Initial load
duke
parents:
diff changeset
4536 // Print all the signal handler state
a61af66fc99e Initial load
duke
parents:
diff changeset
4537 if (sigismember(&check_signal_done, sig)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4538 print_signal_handlers(tty, buf, O_BUFLEN);
a61af66fc99e Initial load
duke
parents:
diff changeset
4539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4540
a61af66fc99e Initial load
duke
parents:
diff changeset
4541 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4542
a61af66fc99e Initial load
duke
parents:
diff changeset
4543 void os::Solaris::install_signal_handlers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4544 bool libjsigdone = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4545 signal_handlers_are_installed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4546
a61af66fc99e Initial load
duke
parents:
diff changeset
4547 // signal-chaining
a61af66fc99e Initial load
duke
parents:
diff changeset
4548 typedef void (*signal_setting_t)();
a61af66fc99e Initial load
duke
parents:
diff changeset
4549 signal_setting_t begin_signal_setting = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4550 signal_setting_t end_signal_setting = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4551 begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
4552 dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting"));
a61af66fc99e Initial load
duke
parents:
diff changeset
4553 if (begin_signal_setting != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4554 end_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
4555 dlsym(RTLD_DEFAULT, "JVM_end_signal_setting"));
a61af66fc99e Initial load
duke
parents:
diff changeset
4556 get_signal_action = CAST_TO_FN_PTR(get_signal_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
4557 dlsym(RTLD_DEFAULT, "JVM_get_signal_action"));
a61af66fc99e Initial load
duke
parents:
diff changeset
4558 get_libjsig_version = CAST_TO_FN_PTR(version_getting_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
4559 dlsym(RTLD_DEFAULT, "JVM_get_libjsig_version"));
a61af66fc99e Initial load
duke
parents:
diff changeset
4560 libjsig_is_loaded = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4561 if (os::Solaris::get_libjsig_version != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4562 libjsigversion = (*os::Solaris::get_libjsig_version)();
a61af66fc99e Initial load
duke
parents:
diff changeset
4563 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4564 assert(UseSignalChaining, "should enable signal-chaining");
a61af66fc99e Initial load
duke
parents:
diff changeset
4565 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4566 if (libjsig_is_loaded) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4567 // Tell libjsig jvm is setting signal handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
4568 (*begin_signal_setting)();
a61af66fc99e Initial load
duke
parents:
diff changeset
4569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4570
a61af66fc99e Initial load
duke
parents:
diff changeset
4571 set_signal_handler(SIGSEGV, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4572 set_signal_handler(SIGPIPE, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4573 set_signal_handler(SIGXFSZ, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4574 set_signal_handler(SIGBUS, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4575 set_signal_handler(SIGILL, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4576 set_signal_handler(SIGFPE, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4577
a61af66fc99e Initial load
duke
parents:
diff changeset
4578
a61af66fc99e Initial load
duke
parents:
diff changeset
4579 if (os::Solaris::SIGinterrupt() > OLDMAXSIGNUM || os::Solaris::SIGasync() > OLDMAXSIGNUM) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4580
a61af66fc99e Initial load
duke
parents:
diff changeset
4581 // Pre-1.4.1 Libjsig limited to signal chaining signals <= 32 so
a61af66fc99e Initial load
duke
parents:
diff changeset
4582 // can not register overridable signals which might be > 32
a61af66fc99e Initial load
duke
parents:
diff changeset
4583 if (libjsig_is_loaded && libjsigversion <= JSIG_VERSION_1_4_1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4584 // Tell libjsig jvm has finished setting signal handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
4585 (*end_signal_setting)();
a61af66fc99e Initial load
duke
parents:
diff changeset
4586 libjsigdone = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4588 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4589
a61af66fc99e Initial load
duke
parents:
diff changeset
4590 // Never ok to chain our SIGinterrupt
a61af66fc99e Initial load
duke
parents:
diff changeset
4591 set_signal_handler(os::Solaris::SIGinterrupt(), true, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
4592 set_signal_handler(os::Solaris::SIGasync(), true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4593
a61af66fc99e Initial load
duke
parents:
diff changeset
4594 if (libjsig_is_loaded && !libjsigdone) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4595 // Tell libjsig jvm finishes setting signal handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
4596 (*end_signal_setting)();
a61af66fc99e Initial load
duke
parents:
diff changeset
4597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4598
a61af66fc99e Initial load
duke
parents:
diff changeset
4599 // We don't activate signal checker if libjsig is in place, we trust ourselves
3956
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4600 // and if UserSignalHandler is installed all bets are off.
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4601 // Log that signal checking is off only if -verbose:jni is specified.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4602 if (CheckJNICalls) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4603 if (libjsig_is_loaded) {
3956
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4604 if (PrintJNIResolving) {
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4605 tty->print_cr("Info: libjsig is activated, all active signal checking is disabled");
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4606 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4607 check_signals = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4608 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4609 if (AllowUserSignalHandlers) {
3956
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4610 if (PrintJNIResolving) {
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4611 tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled");
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4612 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4613 check_signals = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4614 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4615 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4617
a61af66fc99e Initial load
duke
parents:
diff changeset
4618
a61af66fc99e Initial load
duke
parents:
diff changeset
4619 void report_error(const char* file_name, int line_no, const char* title, const char* format, ...);
a61af66fc99e Initial load
duke
parents:
diff changeset
4620
a61af66fc99e Initial load
duke
parents:
diff changeset
4621 const char * signames[] = {
a61af66fc99e Initial load
duke
parents:
diff changeset
4622 "SIG0",
a61af66fc99e Initial load
duke
parents:
diff changeset
4623 "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP",
a61af66fc99e Initial load
duke
parents:
diff changeset
4624 "SIGABRT", "SIGEMT", "SIGFPE", "SIGKILL", "SIGBUS",
a61af66fc99e Initial load
duke
parents:
diff changeset
4625 "SIGSEGV", "SIGSYS", "SIGPIPE", "SIGALRM", "SIGTERM",
a61af66fc99e Initial load
duke
parents:
diff changeset
4626 "SIGUSR1", "SIGUSR2", "SIGCLD", "SIGPWR", "SIGWINCH",
a61af66fc99e Initial load
duke
parents:
diff changeset
4627 "SIGURG", "SIGPOLL", "SIGSTOP", "SIGTSTP", "SIGCONT",
a61af66fc99e Initial load
duke
parents:
diff changeset
4628 "SIGTTIN", "SIGTTOU", "SIGVTALRM", "SIGPROF", "SIGXCPU",
a61af66fc99e Initial load
duke
parents:
diff changeset
4629 "SIGXFSZ", "SIGWAITING", "SIGLWP", "SIGFREEZE", "SIGTHAW",
a61af66fc99e Initial load
duke
parents:
diff changeset
4630 "SIGCANCEL", "SIGLOST"
a61af66fc99e Initial load
duke
parents:
diff changeset
4631 };
a61af66fc99e Initial load
duke
parents:
diff changeset
4632
a61af66fc99e Initial load
duke
parents:
diff changeset
4633 const char* os::exception_name(int exception_code, char* buf, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4634 if (0 < exception_code && exception_code <= SIGRTMAX) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4635 // signal
a61af66fc99e Initial load
duke
parents:
diff changeset
4636 if (exception_code < sizeof(signames)/sizeof(const char*)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4637 jio_snprintf(buf, size, "%s", signames[exception_code]);
a61af66fc99e Initial load
duke
parents:
diff changeset
4638 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4639 jio_snprintf(buf, size, "SIG%d", exception_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
4640 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4641 return buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
4642 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4643 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4646
a61af66fc99e Initial load
duke
parents:
diff changeset
4647 // (Static) wrappers for the new libthread API
a61af66fc99e Initial load
duke
parents:
diff changeset
4648 int_fnP_thread_t_iP_uP_stack_tP_gregset_t os::Solaris::_thr_getstate;
a61af66fc99e Initial load
duke
parents:
diff changeset
4649 int_fnP_thread_t_i_gregset_t os::Solaris::_thr_setstate;
a61af66fc99e Initial load
duke
parents:
diff changeset
4650 int_fnP_thread_t_i os::Solaris::_thr_setmutator;
a61af66fc99e Initial load
duke
parents:
diff changeset
4651 int_fnP_thread_t os::Solaris::_thr_suspend_mutator;
a61af66fc99e Initial load
duke
parents:
diff changeset
4652 int_fnP_thread_t os::Solaris::_thr_continue_mutator;
a61af66fc99e Initial load
duke
parents:
diff changeset
4653
641
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4654 // (Static) wrapper for getisax(2) call.
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4655 os::Solaris::getisax_func_t os::Solaris::_getisax = 0;
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4656
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4657 // (Static) wrappers for the liblgrp API
a61af66fc99e Initial load
duke
parents:
diff changeset
4658 os::Solaris::lgrp_home_func_t os::Solaris::_lgrp_home;
a61af66fc99e Initial load
duke
parents:
diff changeset
4659 os::Solaris::lgrp_init_func_t os::Solaris::_lgrp_init;
a61af66fc99e Initial load
duke
parents:
diff changeset
4660 os::Solaris::lgrp_fini_func_t os::Solaris::_lgrp_fini;
a61af66fc99e Initial load
duke
parents:
diff changeset
4661 os::Solaris::lgrp_root_func_t os::Solaris::_lgrp_root;
a61af66fc99e Initial load
duke
parents:
diff changeset
4662 os::Solaris::lgrp_children_func_t os::Solaris::_lgrp_children;
144
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
4663 os::Solaris::lgrp_resources_func_t os::Solaris::_lgrp_resources;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4664 os::Solaris::lgrp_nlgrps_func_t os::Solaris::_lgrp_nlgrps;
a61af66fc99e Initial load
duke
parents:
diff changeset
4665 os::Solaris::lgrp_cookie_stale_func_t os::Solaris::_lgrp_cookie_stale;
a61af66fc99e Initial load
duke
parents:
diff changeset
4666 os::Solaris::lgrp_cookie_t os::Solaris::_lgrp_cookie = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4667
a61af66fc99e Initial load
duke
parents:
diff changeset
4668 // (Static) wrapper for meminfo() call.
a61af66fc99e Initial load
duke
parents:
diff changeset
4669 os::Solaris::meminfo_func_t os::Solaris::_meminfo = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4670
641
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4671 static address resolve_symbol_lazy(const char* name) {
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4672 address addr = (address) dlsym(RTLD_DEFAULT, name);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4673 if(addr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4674 // RTLD_DEFAULT was not defined on some early versions of 2.5.1
a61af66fc99e Initial load
duke
parents:
diff changeset
4675 addr = (address) dlsym(RTLD_NEXT, name);
641
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4676 }
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4677 return addr;
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4678 }
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4679
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4680 static address resolve_symbol(const char* name) {
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4681 address addr = resolve_symbol_lazy(name);
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4682 if(addr == NULL) {
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4683 fatal(dlerror());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4685 return addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
4686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4687
a61af66fc99e Initial load
duke
parents:
diff changeset
4688
a61af66fc99e Initial load
duke
parents:
diff changeset
4689
a61af66fc99e Initial load
duke
parents:
diff changeset
4690 // isT2_libthread()
a61af66fc99e Initial load
duke
parents:
diff changeset
4691 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4692 // Routine to determine if we are currently using the new T2 libthread.
a61af66fc99e Initial load
duke
parents:
diff changeset
4693 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4694 // We determine if we are using T2 by reading /proc/self/lstatus and
a61af66fc99e Initial load
duke
parents:
diff changeset
4695 // looking for a thread with the ASLWP bit set. If we find this status
a61af66fc99e Initial load
duke
parents:
diff changeset
4696 // bit set, we must assume that we are NOT using T2. The T2 team
a61af66fc99e Initial load
duke
parents:
diff changeset
4697 // has approved this algorithm.
a61af66fc99e Initial load
duke
parents:
diff changeset
4698 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4699 // We need to determine if we are running with the new T2 libthread
a61af66fc99e Initial load
duke
parents:
diff changeset
4700 // since setting native thread priorities is handled differently
a61af66fc99e Initial load
duke
parents:
diff changeset
4701 // when using this library. All threads created using T2 are bound
a61af66fc99e Initial load
duke
parents:
diff changeset
4702 // threads. Calling thr_setprio is meaningless in this case.
a61af66fc99e Initial load
duke
parents:
diff changeset
4703 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4704 bool isT2_libthread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4705 static prheader_t * lwpArray = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4706 static int lwpSize = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4707 static int lwpFile = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4708 lwpstatus_t * that;
a61af66fc99e Initial load
duke
parents:
diff changeset
4709 char lwpName [128];
a61af66fc99e Initial load
duke
parents:
diff changeset
4710 bool isT2 = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4711
a61af66fc99e Initial load
duke
parents:
diff changeset
4712 #define ADR(x) ((uintptr_t)(x))
a61af66fc99e Initial load
duke
parents:
diff changeset
4713 #define LWPINDEX(ary,ix) ((lwpstatus_t *)(((ary)->pr_entsize * (ix)) + (ADR((ary) + 1))))
a61af66fc99e Initial load
duke
parents:
diff changeset
4714
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4715 lwpFile = ::open("/proc/self/lstatus", O_RDONLY, 0);
89
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4716 if (lwpFile < 0) {
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4717 if (ThreadPriorityVerbose) warning ("Couldn't open /proc/self/lstatus\n");
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4718 return false;
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4719 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4720 lwpSize = 16*1024;
a61af66fc99e Initial load
duke
parents:
diff changeset
4721 for (;;) {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4722 ::lseek64 (lwpFile, 0, SEEK_SET);
89
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4723 lwpArray = (prheader_t *)NEW_C_HEAP_ARRAY(char, lwpSize);
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4724 if (::read(lwpFile, lwpArray, lwpSize) < 0) {
89
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4725 if (ThreadPriorityVerbose) warning("Error reading /proc/self/lstatus\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4726 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4727 }
89
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4728 if ((lwpArray->pr_nent * lwpArray->pr_entsize) <= lwpSize) {
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4729 // We got a good snapshot - now iterate over the list.
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4730 int aslwpcount = 0;
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4731 for (int i = 0; i < lwpArray->pr_nent; i++ ) {
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4732 that = LWPINDEX(lwpArray,i);
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4733 if (that->pr_flags & PR_ASLWP) {
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4734 aslwpcount++;
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4735 }
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4736 }
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4737 if (aslwpcount == 0) isT2 = true;
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4738 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4739 }
89
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4740 lwpSize = lwpArray->pr_nent * lwpArray->pr_entsize;
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4741 FREE_C_HEAP_ARRAY(char, lwpArray); // retry.
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4742 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4743
a61af66fc99e Initial load
duke
parents:
diff changeset
4744 FREE_C_HEAP_ARRAY(char, lwpArray);
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4745 ::close (lwpFile);
89
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4746 if (ThreadPriorityVerbose) {
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4747 if (isT2) tty->print_cr("We are running with a T2 libthread\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4748 else tty->print_cr("We are not running with a T2 libthread\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4749 }
89
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4750 return isT2;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4751 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4752
a61af66fc99e Initial load
duke
parents:
diff changeset
4753
a61af66fc99e Initial load
duke
parents:
diff changeset
4754 void os::Solaris::libthread_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4755 address func = (address)dlsym(RTLD_DEFAULT, "_thr_suspend_allmutators");
a61af66fc99e Initial load
duke
parents:
diff changeset
4756
a61af66fc99e Initial load
duke
parents:
diff changeset
4757 // Determine if we are running with the new T2 libthread
a61af66fc99e Initial load
duke
parents:
diff changeset
4758 os::Solaris::set_T2_libthread(isT2_libthread());
a61af66fc99e Initial load
duke
parents:
diff changeset
4759
a61af66fc99e Initial load
duke
parents:
diff changeset
4760 lwp_priocntl_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
4761
a61af66fc99e Initial load
duke
parents:
diff changeset
4762 // RTLD_DEFAULT was not defined on some early versions of 5.5.1
a61af66fc99e Initial load
duke
parents:
diff changeset
4763 if(func == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4764 func = (address) dlsym(RTLD_NEXT, "_thr_suspend_allmutators");
a61af66fc99e Initial load
duke
parents:
diff changeset
4765 // Guarantee that this VM is running on an new enough OS (5.6 or
a61af66fc99e Initial load
duke
parents:
diff changeset
4766 // later) that it will have a new enough libthread.so.
a61af66fc99e Initial load
duke
parents:
diff changeset
4767 guarantee(func != NULL, "libthread.so is too old.");
a61af66fc99e Initial load
duke
parents:
diff changeset
4768 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4769
a61af66fc99e Initial load
duke
parents:
diff changeset
4770 // Initialize the new libthread getstate API wrappers
a61af66fc99e Initial load
duke
parents:
diff changeset
4771 func = resolve_symbol("thr_getstate");
a61af66fc99e Initial load
duke
parents:
diff changeset
4772 os::Solaris::set_thr_getstate(CAST_TO_FN_PTR(int_fnP_thread_t_iP_uP_stack_tP_gregset_t, func));
a61af66fc99e Initial load
duke
parents:
diff changeset
4773
a61af66fc99e Initial load
duke
parents:
diff changeset
4774 func = resolve_symbol("thr_setstate");
a61af66fc99e Initial load
duke
parents:
diff changeset
4775 os::Solaris::set_thr_setstate(CAST_TO_FN_PTR(int_fnP_thread_t_i_gregset_t, func));
a61af66fc99e Initial load
duke
parents:
diff changeset
4776
a61af66fc99e Initial load
duke
parents:
diff changeset
4777 func = resolve_symbol("thr_setmutator");
a61af66fc99e Initial load
duke
parents:
diff changeset
4778 os::Solaris::set_thr_setmutator(CAST_TO_FN_PTR(int_fnP_thread_t_i, func));
a61af66fc99e Initial load
duke
parents:
diff changeset
4779
a61af66fc99e Initial load
duke
parents:
diff changeset
4780 func = resolve_symbol("thr_suspend_mutator");
a61af66fc99e Initial load
duke
parents:
diff changeset
4781 os::Solaris::set_thr_suspend_mutator(CAST_TO_FN_PTR(int_fnP_thread_t, func));
a61af66fc99e Initial load
duke
parents:
diff changeset
4782
a61af66fc99e Initial load
duke
parents:
diff changeset
4783 func = resolve_symbol("thr_continue_mutator");
a61af66fc99e Initial load
duke
parents:
diff changeset
4784 os::Solaris::set_thr_continue_mutator(CAST_TO_FN_PTR(int_fnP_thread_t, func));
a61af66fc99e Initial load
duke
parents:
diff changeset
4785
a61af66fc99e Initial load
duke
parents:
diff changeset
4786 int size;
a61af66fc99e Initial load
duke
parents:
diff changeset
4787 void (*handler_info_func)(address *, int *);
a61af66fc99e Initial load
duke
parents:
diff changeset
4788 handler_info_func = CAST_TO_FN_PTR(void (*)(address *, int *), resolve_symbol("thr_sighndlrinfo"));
a61af66fc99e Initial load
duke
parents:
diff changeset
4789 handler_info_func(&handler_start, &size);
a61af66fc99e Initial load
duke
parents:
diff changeset
4790 handler_end = handler_start + size;
a61af66fc99e Initial load
duke
parents:
diff changeset
4791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4792
a61af66fc99e Initial load
duke
parents:
diff changeset
4793
a61af66fc99e Initial load
duke
parents:
diff changeset
4794 int_fnP_mutex_tP os::Solaris::_mutex_lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
4795 int_fnP_mutex_tP os::Solaris::_mutex_trylock;
a61af66fc99e Initial load
duke
parents:
diff changeset
4796 int_fnP_mutex_tP os::Solaris::_mutex_unlock;
a61af66fc99e Initial load
duke
parents:
diff changeset
4797 int_fnP_mutex_tP_i_vP os::Solaris::_mutex_init;
a61af66fc99e Initial load
duke
parents:
diff changeset
4798 int_fnP_mutex_tP os::Solaris::_mutex_destroy;
a61af66fc99e Initial load
duke
parents:
diff changeset
4799 int os::Solaris::_mutex_scope = USYNC_THREAD;
a61af66fc99e Initial load
duke
parents:
diff changeset
4800
a61af66fc99e Initial load
duke
parents:
diff changeset
4801 int_fnP_cond_tP_mutex_tP_timestruc_tP os::Solaris::_cond_timedwait;
a61af66fc99e Initial load
duke
parents:
diff changeset
4802 int_fnP_cond_tP_mutex_tP os::Solaris::_cond_wait;
a61af66fc99e Initial load
duke
parents:
diff changeset
4803 int_fnP_cond_tP os::Solaris::_cond_signal;
a61af66fc99e Initial load
duke
parents:
diff changeset
4804 int_fnP_cond_tP os::Solaris::_cond_broadcast;
a61af66fc99e Initial load
duke
parents:
diff changeset
4805 int_fnP_cond_tP_i_vP os::Solaris::_cond_init;
a61af66fc99e Initial load
duke
parents:
diff changeset
4806 int_fnP_cond_tP os::Solaris::_cond_destroy;
a61af66fc99e Initial load
duke
parents:
diff changeset
4807 int os::Solaris::_cond_scope = USYNC_THREAD;
a61af66fc99e Initial load
duke
parents:
diff changeset
4808
a61af66fc99e Initial load
duke
parents:
diff changeset
4809 void os::Solaris::synchronization_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4810 if(UseLWPSynchronization) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4811 os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_lock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4812 os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_trylock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4813 os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_unlock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4814 os::Solaris::set_mutex_init(lwp_mutex_init);
a61af66fc99e Initial load
duke
parents:
diff changeset
4815 os::Solaris::set_mutex_destroy(lwp_mutex_destroy);
a61af66fc99e Initial load
duke
parents:
diff changeset
4816 os::Solaris::set_mutex_scope(USYNC_THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
4817
a61af66fc99e Initial load
duke
parents:
diff changeset
4818 os::Solaris::set_cond_timedwait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP_timestruc_tP, resolve_symbol("_lwp_cond_timedwait")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4819 os::Solaris::set_cond_wait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP, resolve_symbol("_lwp_cond_wait")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4820 os::Solaris::set_cond_signal(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("_lwp_cond_signal")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4821 os::Solaris::set_cond_broadcast(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("_lwp_cond_broadcast")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4822 os::Solaris::set_cond_init(lwp_cond_init);
a61af66fc99e Initial load
duke
parents:
diff changeset
4823 os::Solaris::set_cond_destroy(lwp_cond_destroy);
a61af66fc99e Initial load
duke
parents:
diff changeset
4824 os::Solaris::set_cond_scope(USYNC_THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
4825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4826 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4827 os::Solaris::set_mutex_scope(USYNC_THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
4828 os::Solaris::set_cond_scope(USYNC_THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
4829
a61af66fc99e Initial load
duke
parents:
diff changeset
4830 if(UsePthreads) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4831 os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_lock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4832 os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_trylock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4833 os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_unlock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4834 os::Solaris::set_mutex_init(pthread_mutex_default_init);
a61af66fc99e Initial load
duke
parents:
diff changeset
4835 os::Solaris::set_mutex_destroy(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_destroy")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4836
a61af66fc99e Initial load
duke
parents:
diff changeset
4837 os::Solaris::set_cond_timedwait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP_timestruc_tP, resolve_symbol("pthread_cond_timedwait")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4838 os::Solaris::set_cond_wait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP, resolve_symbol("pthread_cond_wait")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4839 os::Solaris::set_cond_signal(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("pthread_cond_signal")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4840 os::Solaris::set_cond_broadcast(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("pthread_cond_broadcast")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4841 os::Solaris::set_cond_init(pthread_cond_default_init);
a61af66fc99e Initial load
duke
parents:
diff changeset
4842 os::Solaris::set_cond_destroy(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("pthread_cond_destroy")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4843 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4844 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4845 os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("mutex_lock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4846 os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("mutex_trylock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4847 os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("mutex_unlock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4848 os::Solaris::set_mutex_init(::mutex_init);
a61af66fc99e Initial load
duke
parents:
diff changeset
4849 os::Solaris::set_mutex_destroy(::mutex_destroy);
a61af66fc99e Initial load
duke
parents:
diff changeset
4850
a61af66fc99e Initial load
duke
parents:
diff changeset
4851 os::Solaris::set_cond_timedwait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP_timestruc_tP, resolve_symbol("cond_timedwait")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4852 os::Solaris::set_cond_wait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP, resolve_symbol("cond_wait")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4853 os::Solaris::set_cond_signal(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("cond_signal")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4854 os::Solaris::set_cond_broadcast(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("cond_broadcast")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4855 os::Solaris::set_cond_init(::cond_init);
a61af66fc99e Initial load
duke
parents:
diff changeset
4856 os::Solaris::set_cond_destroy(::cond_destroy);
a61af66fc99e Initial load
duke
parents:
diff changeset
4857 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4858 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4859 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4860
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
4861 bool os::Solaris::liblgrp_init() {
267
9d6a3a6891f8 6720130: NUMA allocator: The linux version should search for libnuma.so.1
iveresov
parents: 144
diff changeset
4862 void *handle = dlopen("liblgrp.so.1", RTLD_LAZY);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4863 if (handle != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4864 os::Solaris::set_lgrp_home(CAST_TO_FN_PTR(lgrp_home_func_t, dlsym(handle, "lgrp_home")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4865 os::Solaris::set_lgrp_init(CAST_TO_FN_PTR(lgrp_init_func_t, dlsym(handle, "lgrp_init")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4866 os::Solaris::set_lgrp_fini(CAST_TO_FN_PTR(lgrp_fini_func_t, dlsym(handle, "lgrp_fini")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4867 os::Solaris::set_lgrp_root(CAST_TO_FN_PTR(lgrp_root_func_t, dlsym(handle, "lgrp_root")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4868 os::Solaris::set_lgrp_children(CAST_TO_FN_PTR(lgrp_children_func_t, dlsym(handle, "lgrp_children")));
144
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
4869 os::Solaris::set_lgrp_resources(CAST_TO_FN_PTR(lgrp_resources_func_t, dlsym(handle, "lgrp_resources")));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4870 os::Solaris::set_lgrp_nlgrps(CAST_TO_FN_PTR(lgrp_nlgrps_func_t, dlsym(handle, "lgrp_nlgrps")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4871 os::Solaris::set_lgrp_cookie_stale(CAST_TO_FN_PTR(lgrp_cookie_stale_func_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
4872 dlsym(handle, "lgrp_cookie_stale")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4873
a61af66fc99e Initial load
duke
parents:
diff changeset
4874 lgrp_cookie_t c = lgrp_init(LGRP_VIEW_CALLER);
a61af66fc99e Initial load
duke
parents:
diff changeset
4875 set_lgrp_cookie(c);
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
4876 return true;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
4877 }
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
4878 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4879 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4880
a61af66fc99e Initial load
duke
parents:
diff changeset
4881 void os::Solaris::misc_sym_init() {
641
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4882 address func;
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4883
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4884 // getisax
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4885 func = resolve_symbol_lazy("getisax");
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4886 if (func != NULL) {
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4887 os::Solaris::_getisax = CAST_TO_FN_PTR(getisax_func_t, func);
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4888 }
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4889
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4890 // meminfo
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4891 func = resolve_symbol_lazy("meminfo");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4892 if (func != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4893 os::Solaris::set_meminfo(CAST_TO_FN_PTR(meminfo_func_t, func));
a61af66fc99e Initial load
duke
parents:
diff changeset
4894 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4895 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4896
641
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4897 uint_t os::Solaris::getisax(uint32_t* array, uint_t n) {
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4898 assert(_getisax != NULL, "_getisax not set");
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4899 return _getisax(array, n);
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4900 }
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4901
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4902 // Symbol doesn't exist in Solaris 8 pset.h
a61af66fc99e Initial load
duke
parents:
diff changeset
4903 #ifndef PS_MYID
a61af66fc99e Initial load
duke
parents:
diff changeset
4904 #define PS_MYID -3
a61af66fc99e Initial load
duke
parents:
diff changeset
4905 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4906
a61af66fc99e Initial load
duke
parents:
diff changeset
4907 // int pset_getloadavg(psetid_t pset, double loadavg[], int nelem);
a61af66fc99e Initial load
duke
parents:
diff changeset
4908 typedef long (*pset_getloadavg_type)(psetid_t pset, double loadavg[], int nelem);
a61af66fc99e Initial load
duke
parents:
diff changeset
4909 static pset_getloadavg_type pset_getloadavg_ptr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4910
a61af66fc99e Initial load
duke
parents:
diff changeset
4911 void init_pset_getloadavg_ptr(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4912 pset_getloadavg_ptr =
a61af66fc99e Initial load
duke
parents:
diff changeset
4913 (pset_getloadavg_type)dlsym(RTLD_DEFAULT, "pset_getloadavg");
a61af66fc99e Initial load
duke
parents:
diff changeset
4914 if (PrintMiscellaneous && Verbose && pset_getloadavg_ptr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4915 warning("pset_getloadavg function not found");
a61af66fc99e Initial load
duke
parents:
diff changeset
4916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4917 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4918
a61af66fc99e Initial load
duke
parents:
diff changeset
4919 int os::Solaris::_dev_zero_fd = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4920
a61af66fc99e Initial load
duke
parents:
diff changeset
4921 // this is called _before_ the global arguments have been parsed
a61af66fc99e Initial load
duke
parents:
diff changeset
4922 void os::init(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4923 _initial_pid = getpid();
a61af66fc99e Initial load
duke
parents:
diff changeset
4924
a61af66fc99e Initial load
duke
parents:
diff changeset
4925 max_hrtime = first_hrtime = gethrtime();
a61af66fc99e Initial load
duke
parents:
diff changeset
4926
a61af66fc99e Initial load
duke
parents:
diff changeset
4927 init_random(1234567);
a61af66fc99e Initial load
duke
parents:
diff changeset
4928
a61af66fc99e Initial load
duke
parents:
diff changeset
4929 page_size = sysconf(_SC_PAGESIZE);
a61af66fc99e Initial load
duke
parents:
diff changeset
4930 if (page_size == -1)
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
4931 fatal(err_msg("os_solaris.cpp: os::init: sysconf failed (%s)",
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
4932 strerror(errno)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4933 init_page_sizes((size_t) page_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
4934
a61af66fc99e Initial load
duke
parents:
diff changeset
4935 Solaris::initialize_system_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
4936
641
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4937 // Initialize misc. symbols as soon as possible, so we can use them
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4938 // if we need them.
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4939 Solaris::misc_sym_init();
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4940
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4941 int fd = ::open("/dev/zero", O_RDWR);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4942 if (fd < 0) {
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
4943 fatal(err_msg("os::init: cannot open /dev/zero (%s)", strerror(errno)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4944 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4945 Solaris::set_dev_zero_fd(fd);
a61af66fc99e Initial load
duke
parents:
diff changeset
4946
a61af66fc99e Initial load
duke
parents:
diff changeset
4947 // Close on exec, child won't inherit.
a61af66fc99e Initial load
duke
parents:
diff changeset
4948 fcntl(fd, F_SETFD, FD_CLOEXEC);
a61af66fc99e Initial load
duke
parents:
diff changeset
4949 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4950
a61af66fc99e Initial load
duke
parents:
diff changeset
4951 clock_tics_per_sec = CLK_TCK;
a61af66fc99e Initial load
duke
parents:
diff changeset
4952
a61af66fc99e Initial load
duke
parents:
diff changeset
4953 // check if dladdr1() exists; dladdr1 can provide more information than
a61af66fc99e Initial load
duke
parents:
diff changeset
4954 // dladdr for os::dll_address_to_function_name. It comes with SunOS 5.9
a61af66fc99e Initial load
duke
parents:
diff changeset
4955 // and is available on linker patches for 5.7 and 5.8.
a61af66fc99e Initial load
duke
parents:
diff changeset
4956 // libdl.so must have been loaded, this call is just an entry lookup
a61af66fc99e Initial load
duke
parents:
diff changeset
4957 void * hdl = dlopen("libdl.so", RTLD_NOW);
a61af66fc99e Initial load
duke
parents:
diff changeset
4958 if (hdl)
a61af66fc99e Initial load
duke
parents:
diff changeset
4959 dladdr1_func = CAST_TO_FN_PTR(dladdr1_func_type, dlsym(hdl, "dladdr1"));
a61af66fc99e Initial load
duke
parents:
diff changeset
4960
a61af66fc99e Initial load
duke
parents:
diff changeset
4961 // (Solaris only) this switches to calls that actually do locking.
a61af66fc99e Initial load
duke
parents:
diff changeset
4962 ThreadCritical::initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
4963
a61af66fc99e Initial load
duke
parents:
diff changeset
4964 main_thread = thr_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
4965
a61af66fc99e Initial load
duke
parents:
diff changeset
4966 // Constant minimum stack size allowed. It must be at least
a61af66fc99e Initial load
duke
parents:
diff changeset
4967 // the minimum of what the OS supports (thr_min_stack()), and
a61af66fc99e Initial load
duke
parents:
diff changeset
4968 // enough to allow the thread to get to user bytecode execution.
a61af66fc99e Initial load
duke
parents:
diff changeset
4969 Solaris::min_stack_allowed = MAX2(thr_min_stack(), Solaris::min_stack_allowed);
a61af66fc99e Initial load
duke
parents:
diff changeset
4970 // If the pagesize of the VM is greater than 8K determine the appropriate
a61af66fc99e Initial load
duke
parents:
diff changeset
4971 // number of initial guard pages. The user can change this with the
a61af66fc99e Initial load
duke
parents:
diff changeset
4972 // command line arguments, if needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
4973 if (vm_page_size() > 8*K) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4974 StackYellowPages = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4975 StackRedPages = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4976 StackShadowPages = round_to((StackShadowPages*8*K), vm_page_size()) / vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
4977 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4979
a61af66fc99e Initial load
duke
parents:
diff changeset
4980 // To install functions for atexit system call
a61af66fc99e Initial load
duke
parents:
diff changeset
4981 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
4982 static void perfMemory_exit_helper() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4983 perfMemory_exit();
a61af66fc99e Initial load
duke
parents:
diff changeset
4984 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4985 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4986
a61af66fc99e Initial load
duke
parents:
diff changeset
4987 // this is called _after_ the global arguments have been parsed
a61af66fc99e Initial load
duke
parents:
diff changeset
4988 jint os::init_2(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4989 // try to enable extended file IO ASAP, see 6431278
a61af66fc99e Initial load
duke
parents:
diff changeset
4990 os::Solaris::try_enable_extended_io();
a61af66fc99e Initial load
duke
parents:
diff changeset
4991
a61af66fc99e Initial load
duke
parents:
diff changeset
4992 // Allocate a single page and mark it as readable for safepoint polling. Also
a61af66fc99e Initial load
duke
parents:
diff changeset
4993 // use this first mmap call to check support for MAP_ALIGN.
a61af66fc99e Initial load
duke
parents:
diff changeset
4994 address polling_page = (address)Solaris::mmap_chunk((char*)page_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
4995 page_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
4996 MAP_PRIVATE | MAP_ALIGN,
a61af66fc99e Initial load
duke
parents:
diff changeset
4997 PROT_READ);
a61af66fc99e Initial load
duke
parents:
diff changeset
4998 if (polling_page == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4999 has_map_align = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5000 polling_page = (address)Solaris::mmap_chunk(NULL, page_size, MAP_PRIVATE,
a61af66fc99e Initial load
duke
parents:
diff changeset
5001 PROT_READ);
a61af66fc99e Initial load
duke
parents:
diff changeset
5002 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5003
a61af66fc99e Initial load
duke
parents:
diff changeset
5004 os::set_polling_page(polling_page);
a61af66fc99e Initial load
duke
parents:
diff changeset
5005
a61af66fc99e Initial load
duke
parents:
diff changeset
5006 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
5007 if( Verbose && PrintMiscellaneous )
a61af66fc99e Initial load
duke
parents:
diff changeset
5008 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);
a61af66fc99e Initial load
duke
parents:
diff changeset
5009 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
5010
a61af66fc99e Initial load
duke
parents:
diff changeset
5011 if (!UseMembar) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5012 address mem_serialize_page = (address)Solaris::mmap_chunk( NULL, page_size, MAP_PRIVATE, PROT_READ | PROT_WRITE );
a61af66fc99e Initial load
duke
parents:
diff changeset
5013 guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page");
a61af66fc99e Initial load
duke
parents:
diff changeset
5014 os::set_memory_serialize_page( mem_serialize_page );
a61af66fc99e Initial load
duke
parents:
diff changeset
5015
a61af66fc99e Initial load
duke
parents:
diff changeset
5016 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
5017 if(Verbose && PrintMiscellaneous)
a61af66fc99e Initial load
duke
parents:
diff changeset
5018 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
a61af66fc99e Initial load
duke
parents:
diff changeset
5019 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
5020 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5021
3318
188c9a5d6a6d 7040485: Use transparent huge page on linux by default
iveresov
parents: 3292
diff changeset
5022 os::large_page_init();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5023
a61af66fc99e Initial load
duke
parents:
diff changeset
5024 // Check minimum allowable stack size for thread creation and to initialize
a61af66fc99e Initial load
duke
parents:
diff changeset
5025 // the java system classes, including StackOverflowError - depends on page
a61af66fc99e Initial load
duke
parents:
diff changeset
5026 // size. Add a page for compiler2 recursion in main thread.
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
5027 // Add in 2*BytesPerWord times page size to account for VM stack during
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5028 // class initialization depending on 32 or 64 bit VM.
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
5029 os::Solaris::min_stack_allowed = MAX2(os::Solaris::min_stack_allowed,
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
5030 (size_t)(StackYellowPages+StackRedPages+StackShadowPages+
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
5031 2*BytesPerWord COMPILER2_PRESENT(+1)) * page_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5032
a61af66fc99e Initial load
duke
parents:
diff changeset
5033 size_t threadStackSizeInBytes = ThreadStackSize * K;
a61af66fc99e Initial load
duke
parents:
diff changeset
5034 if (threadStackSizeInBytes != 0 &&
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
5035 threadStackSizeInBytes < os::Solaris::min_stack_allowed) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5036 tty->print_cr("\nThe stack size specified is too small, Specify at least %dk",
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
5037 os::Solaris::min_stack_allowed/K);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5038 return JNI_ERR;
a61af66fc99e Initial load
duke
parents:
diff changeset
5039 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5040
a61af66fc99e Initial load
duke
parents:
diff changeset
5041 // For 64kbps there will be a 64kb page size, which makes
a61af66fc99e Initial load
duke
parents:
diff changeset
5042 // the usable default stack size quite a bit less. Increase the
a61af66fc99e Initial load
duke
parents:
diff changeset
5043 // stack for 64kb (or any > than 8kb) pages, this increases
a61af66fc99e Initial load
duke
parents:
diff changeset
5044 // virtual memory fragmentation (since we're not creating the
a61af66fc99e Initial load
duke
parents:
diff changeset
5045 // stack on a power of 2 boundary. The real fix for this
a61af66fc99e Initial load
duke
parents:
diff changeset
5046 // should be to fix the guard page mechanism.
a61af66fc99e Initial load
duke
parents:
diff changeset
5047
a61af66fc99e Initial load
duke
parents:
diff changeset
5048 if (vm_page_size() > 8*K) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5049 threadStackSizeInBytes = (threadStackSizeInBytes != 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
5050 ? threadStackSizeInBytes +
a61af66fc99e Initial load
duke
parents:
diff changeset
5051 ((StackYellowPages + StackRedPages) * vm_page_size())
a61af66fc99e Initial load
duke
parents:
diff changeset
5052 : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5053 ThreadStackSize = threadStackSizeInBytes/K;
a61af66fc99e Initial load
duke
parents:
diff changeset
5054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5055
a61af66fc99e Initial load
duke
parents:
diff changeset
5056 // Make the stack size a multiple of the page size so that
a61af66fc99e Initial load
duke
parents:
diff changeset
5057 // the yellow/red zones can be guarded.
a61af66fc99e Initial load
duke
parents:
diff changeset
5058 JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
5059 vm_page_size()));
a61af66fc99e Initial load
duke
parents:
diff changeset
5060
a61af66fc99e Initial load
duke
parents:
diff changeset
5061 Solaris::libthread_init();
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5062
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5063 if (UseNUMA) {
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5064 if (!Solaris::liblgrp_init()) {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5065 UseNUMA = false;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5066 } else {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5067 size_t lgrp_limit = os::numa_get_groups_num();
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5068 int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit);
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5069 size_t lgrp_num = os::numa_get_leaf_groups(lgrp_ids, lgrp_limit);
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5070 FREE_C_HEAP_ARRAY(int, lgrp_ids);
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5071 if (lgrp_num < 2) {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5072 // There's only one locality group, disable NUMA.
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5073 UseNUMA = false;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5074 }
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5075 }
3292
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
5076 // ISM is not compatible with the NUMA allocator - it always allocates
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
5077 // pages round-robin across the lgroups.
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
5078 if (UseNUMA && UseLargePages && UseISM) {
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
5079 if (!FLAG_IS_DEFAULT(UseNUMA)) {
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
5080 if (FLAG_IS_DEFAULT(UseLargePages) && FLAG_IS_DEFAULT(UseISM)) {
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
5081 UseLargePages = false;
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
5082 } else {
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
5083 warning("UseNUMA is not compatible with ISM large pages, disabling NUMA allocator");
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
5084 UseNUMA = false;
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
5085 }
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
5086 } else {
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
5087 UseNUMA = false;
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
5088 }
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
5089 }
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5090 if (!UseNUMA && ForceNUMA) {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5091 UseNUMA = true;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5092 }
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5093 }
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5094
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5095 Solaris::signal_sets_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
5096 Solaris::init_signal_mem();
a61af66fc99e Initial load
duke
parents:
diff changeset
5097 Solaris::install_signal_handlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
5098
a61af66fc99e Initial load
duke
parents:
diff changeset
5099 if (libjsigversion < JSIG_VERSION_1_4_1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5100 Maxlibjsigsigs = OLDMAXSIGNUM;
a61af66fc99e Initial load
duke
parents:
diff changeset
5101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5102
a61af66fc99e Initial load
duke
parents:
diff changeset
5103 // initialize synchronization primitives to use either thread or
a61af66fc99e Initial load
duke
parents:
diff changeset
5104 // lwp synchronization (controlled by UseLWPSynchronization)
a61af66fc99e Initial load
duke
parents:
diff changeset
5105 Solaris::synchronization_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
5106
a61af66fc99e Initial load
duke
parents:
diff changeset
5107 if (MaxFDLimit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5108 // set the number of file descriptors to max. print out error
a61af66fc99e Initial load
duke
parents:
diff changeset
5109 // if getrlimit/setrlimit fails but continue regardless.
a61af66fc99e Initial load
duke
parents:
diff changeset
5110 struct rlimit nbr_files;
a61af66fc99e Initial load
duke
parents:
diff changeset
5111 int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
a61af66fc99e Initial load
duke
parents:
diff changeset
5112 if (status != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5113 if (PrintMiscellaneous && (Verbose || WizardMode))
a61af66fc99e Initial load
duke
parents:
diff changeset
5114 perror("os::init_2 getrlimit failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
5115 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5116 nbr_files.rlim_cur = nbr_files.rlim_max;
a61af66fc99e Initial load
duke
parents:
diff changeset
5117 status = setrlimit(RLIMIT_NOFILE, &nbr_files);
a61af66fc99e Initial load
duke
parents:
diff changeset
5118 if (status != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5119 if (PrintMiscellaneous && (Verbose || WizardMode))
a61af66fc99e Initial load
duke
parents:
diff changeset
5120 perror("os::init_2 setrlimit failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
5121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5124
a61af66fc99e Initial load
duke
parents:
diff changeset
5125 // Calculate theoretical max. size of Threads to guard gainst
a61af66fc99e Initial load
duke
parents:
diff changeset
5126 // artifical out-of-memory situations, where all available address-
a61af66fc99e Initial load
duke
parents:
diff changeset
5127 // space has been reserved by thread stacks. Default stack size is 1Mb.
a61af66fc99e Initial load
duke
parents:
diff changeset
5128 size_t pre_thread_stack_size = (JavaThread::stack_size_at_create()) ?
a61af66fc99e Initial load
duke
parents:
diff changeset
5129 JavaThread::stack_size_at_create() : (1*K*K);
a61af66fc99e Initial load
duke
parents:
diff changeset
5130 assert(pre_thread_stack_size != 0, "Must have a stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
5131 // Solaris has a maximum of 4Gb of user programs. Calculate the thread limit when
a61af66fc99e Initial load
duke
parents:
diff changeset
5132 // we should start doing Virtual Memory banging. Currently when the threads will
a61af66fc99e Initial load
duke
parents:
diff changeset
5133 // have used all but 200Mb of space.
a61af66fc99e Initial load
duke
parents:
diff changeset
5134 size_t max_address_space = ((unsigned int)4 * K * K * K) - (200 * K * K);
a61af66fc99e Initial load
duke
parents:
diff changeset
5135 Solaris::_os_thread_limit = max_address_space / pre_thread_stack_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
5136
a61af66fc99e Initial load
duke
parents:
diff changeset
5137 // at-exit methods are called in the reverse order of their registration.
a61af66fc99e Initial load
duke
parents:
diff changeset
5138 // In Solaris 7 and earlier, atexit functions are called on return from
a61af66fc99e Initial load
duke
parents:
diff changeset
5139 // main or as a result of a call to exit(3C). There can be only 32 of
a61af66fc99e Initial load
duke
parents:
diff changeset
5140 // these functions registered and atexit() does not set errno. In Solaris
a61af66fc99e Initial load
duke
parents:
diff changeset
5141 // 8 and later, there is no limit to the number of functions registered
a61af66fc99e Initial load
duke
parents:
diff changeset
5142 // and atexit() sets errno. In addition, in Solaris 8 and later, atexit
a61af66fc99e Initial load
duke
parents:
diff changeset
5143 // functions are called upon dlclose(3DL) in addition to return from main
a61af66fc99e Initial load
duke
parents:
diff changeset
5144 // and exit(3C).
a61af66fc99e Initial load
duke
parents:
diff changeset
5145
a61af66fc99e Initial load
duke
parents:
diff changeset
5146 if (PerfAllowAtExitRegistration) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5147 // only register atexit functions if PerfAllowAtExitRegistration is set.
a61af66fc99e Initial load
duke
parents:
diff changeset
5148 // atexit functions can be delayed until process exit time, which
a61af66fc99e Initial load
duke
parents:
diff changeset
5149 // can be problematic for embedded VM situations. Embedded VMs should
a61af66fc99e Initial load
duke
parents:
diff changeset
5150 // call DestroyJavaVM() to assure that VM resources are released.
a61af66fc99e Initial load
duke
parents:
diff changeset
5151
a61af66fc99e Initial load
duke
parents:
diff changeset
5152 // note: perfMemory_exit_helper atexit function may be removed in
a61af66fc99e Initial load
duke
parents:
diff changeset
5153 // the future if the appropriate cleanup code can be added to the
a61af66fc99e Initial load
duke
parents:
diff changeset
5154 // VM_Exit VMOperation's doit method.
a61af66fc99e Initial load
duke
parents:
diff changeset
5155 if (atexit(perfMemory_exit_helper) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5156 warning("os::init2 atexit(perfMemory_exit_helper) failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
5157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5159
a61af66fc99e Initial load
duke
parents:
diff changeset
5160 // Init pset_loadavg function pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
5161 init_pset_getloadavg_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
5162
a61af66fc99e Initial load
duke
parents:
diff changeset
5163 return JNI_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
5164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5165
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5166 void os::init_3(void) {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5167 return;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5168 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5169
a61af66fc99e Initial load
duke
parents:
diff changeset
5170 // Mark the polling page as unreadable
a61af66fc99e Initial load
duke
parents:
diff changeset
5171 void os::make_polling_page_unreadable(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5172 if( mprotect((char *)_polling_page, page_size, PROT_NONE) != 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
5173 fatal("Could not disable polling page");
a61af66fc99e Initial load
duke
parents:
diff changeset
5174 };
a61af66fc99e Initial load
duke
parents:
diff changeset
5175
a61af66fc99e Initial load
duke
parents:
diff changeset
5176 // Mark the polling page as readable
a61af66fc99e Initial load
duke
parents:
diff changeset
5177 void os::make_polling_page_readable(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5178 if( mprotect((char *)_polling_page, page_size, PROT_READ) != 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
5179 fatal("Could not enable polling page");
a61af66fc99e Initial load
duke
parents:
diff changeset
5180 };
a61af66fc99e Initial load
duke
parents:
diff changeset
5181
a61af66fc99e Initial load
duke
parents:
diff changeset
5182 // OS interface.
a61af66fc99e Initial load
duke
parents:
diff changeset
5183
a61af66fc99e Initial load
duke
parents:
diff changeset
5184 bool os::check_heap(bool force) { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
5185
a61af66fc99e Initial load
duke
parents:
diff changeset
5186 typedef int (*vsnprintf_t)(char* buf, size_t count, const char* fmt, va_list argptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
5187 static vsnprintf_t sol_vsnprintf = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5188
a61af66fc99e Initial load
duke
parents:
diff changeset
5189 int local_vsnprintf(char* buf, size_t count, const char* fmt, va_list argptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5190 if (!sol_vsnprintf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5191 //search for the named symbol in the objects that were loaded after libjvm
a61af66fc99e Initial load
duke
parents:
diff changeset
5192 void* where = RTLD_NEXT;
a61af66fc99e Initial load
duke
parents:
diff changeset
5193 if ((sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "__vsnprintf"))) == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
5194 sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "vsnprintf"));
a61af66fc99e Initial load
duke
parents:
diff changeset
5195 if (!sol_vsnprintf){
a61af66fc99e Initial load
duke
parents:
diff changeset
5196 //search for the named symbol in the objects that were loaded before libjvm
a61af66fc99e Initial load
duke
parents:
diff changeset
5197 where = RTLD_DEFAULT;
a61af66fc99e Initial load
duke
parents:
diff changeset
5198 if ((sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "__vsnprintf"))) == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
5199 sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "vsnprintf"));
a61af66fc99e Initial load
duke
parents:
diff changeset
5200 assert(sol_vsnprintf != NULL, "vsnprintf not found");
a61af66fc99e Initial load
duke
parents:
diff changeset
5201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5203 return (*sol_vsnprintf)(buf, count, fmt, argptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
5204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5205
a61af66fc99e Initial load
duke
parents:
diff changeset
5206
a61af66fc99e Initial load
duke
parents:
diff changeset
5207 // Is a (classpath) directory empty?
a61af66fc99e Initial load
duke
parents:
diff changeset
5208 bool os::dir_is_empty(const char* path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5209 DIR *dir = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5210 struct dirent *ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
5211
a61af66fc99e Initial load
duke
parents:
diff changeset
5212 dir = opendir(path);
a61af66fc99e Initial load
duke
parents:
diff changeset
5213 if (dir == NULL) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5214
a61af66fc99e Initial load
duke
parents:
diff changeset
5215 /* Scan the directory */
a61af66fc99e Initial load
duke
parents:
diff changeset
5216 bool result = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5217 char buf[sizeof(struct dirent) + MAX_PATH];
a61af66fc99e Initial load
duke
parents:
diff changeset
5218 struct dirent *dbuf = (struct dirent *) buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
5219 while (result && (ptr = readdir(dir, dbuf)) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5220 if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5221 result = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5224 closedir(dir);
a61af66fc99e Initial load
duke
parents:
diff changeset
5225 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
5226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5227
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5228 // This code originates from JDK's sysOpen and open64_w
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5229 // from src/solaris/hpi/src/system_md.c
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5230
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5231 #ifndef O_DELETE
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5232 #define O_DELETE 0x10000
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5233 #endif
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5234
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5235 // Open a file. Unlink the file immediately after open returns
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5236 // if the specified oflag has the O_DELETE flag set.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5237 // O_DELETE is used only in j2se/src/share/native/java/util/zip/ZipFile.c
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5238
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5239 int os::open(const char *path, int oflag, int mode) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5240 if (strlen(path) > MAX_PATH - 1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5241 errno = ENAMETOOLONG;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5242 return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5243 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5244 int fd;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5245 int o_delete = (oflag & O_DELETE);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5246 oflag = oflag & ~O_DELETE;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5247
2097
039eb4201e06 7009975: Large file support broken in hs20-b04
alanb
parents: 2068
diff changeset
5248 fd = ::open64(path, oflag, mode);
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5249 if (fd == -1) return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5250
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5251 //If the open succeeded, the file might still be a directory
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5252 {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5253 struct stat64 buf64;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5254 int ret = ::fstat64(fd, &buf64);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5255 int st_mode = buf64.st_mode;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5256
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5257 if (ret != -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5258 if ((st_mode & S_IFMT) == S_IFDIR) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5259 errno = EISDIR;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5260 ::close(fd);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5261 return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5262 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5263 } else {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5264 ::close(fd);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5265 return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5266 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5267 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5268 /*
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5269 * 32-bit Solaris systems suffer from:
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5270 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5271 * - an historical default soft limit of 256 per-process file
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5272 * descriptors that is too low for many Java programs.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5273 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5274 * - a design flaw where file descriptors created using stdio
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5275 * fopen must be less than 256, _even_ when the first limit above
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5276 * has been raised. This can cause calls to fopen (but not calls to
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5277 * open, for example) to fail mysteriously, perhaps in 3rd party
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5278 * native code (although the JDK itself uses fopen). One can hardly
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5279 * criticize them for using this most standard of all functions.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5280 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5281 * We attempt to make everything work anyways by:
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5282 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5283 * - raising the soft limit on per-process file descriptors beyond
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5284 * 256
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5285 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5286 * - As of Solaris 10u4, we can request that Solaris raise the 256
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5287 * stdio fopen limit by calling function enable_extended_FILE_stdio.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5288 * This is done in init_2 and recorded in enabled_extended_FILE_stdio
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5289 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5290 * - If we are stuck on an old (pre 10u4) Solaris system, we can
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5291 * workaround the bug by remapping non-stdio file descriptors below
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5292 * 256 to ones beyond 256, which is done below.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5293 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5294 * See:
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5295 * 1085341: 32-bit stdio routines should support file descriptors >255
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5296 * 6533291: Work around 32-bit Solaris stdio limit of 256 open files
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5297 * 6431278: Netbeans crash on 32 bit Solaris: need to call
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5298 * enable_extended_FILE_stdio() in VM initialisation
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5299 * Giri Mandalika's blog
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5300 * http://technopark02.blogspot.com/2005_05_01_archive.html
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5301 */
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5302 #ifndef _LP64
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5303 if ((!enabled_extended_FILE_stdio) && fd < 256) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5304 int newfd = ::fcntl(fd, F_DUPFD, 256);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5305 if (newfd != -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5306 ::close(fd);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5307 fd = newfd;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5308 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5309 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5310 #endif // 32-bit Solaris
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5311 /*
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5312 * All file descriptors that are opened in the JVM and not
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5313 * specifically destined for a subprocess should have the
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5314 * close-on-exec flag set. If we don't set it, then careless 3rd
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5315 * party native code might fork and exec without closing all
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5316 * appropriate file descriptors (e.g. as we do in closeDescriptors in
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5317 * UNIXProcess.c), and this in turn might:
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5318 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5319 * - cause end-of-file to fail to be detected on some file
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5320 * descriptors, resulting in mysterious hangs, or
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5321 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5322 * - might cause an fopen in the subprocess to fail on a system
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5323 * suffering from bug 1085341.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5324 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5325 * (Yes, the default setting of the close-on-exec flag is a Unix
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5326 * design flaw)
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5327 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5328 * See:
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5329 * 1085341: 32-bit stdio routines should support file descriptors >255
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5330 * 4843136: (process) pipe file descriptor from Runtime.exec not being closed
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5331 * 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5332 */
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5333 #ifdef FD_CLOEXEC
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5334 {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5335 int flags = ::fcntl(fd, F_GETFD);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5336 if (flags != -1)
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5337 ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5338 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5339 #endif
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5340
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5341 if (o_delete != 0) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5342 ::unlink(path);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5343 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5344 return fd;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5345 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5346
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5347 // create binary file, rewriting existing file if required
a61af66fc99e Initial load
duke
parents:
diff changeset
5348 int os::create_binary_file(const char* path, bool rewrite_existing) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5349 int oflags = O_WRONLY | O_CREAT;
a61af66fc99e Initial load
duke
parents:
diff changeset
5350 if (!rewrite_existing) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5351 oflags |= O_EXCL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5353 return ::open64(path, oflags, S_IREAD | S_IWRITE);
a61af66fc99e Initial load
duke
parents:
diff changeset
5354 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5355
a61af66fc99e Initial load
duke
parents:
diff changeset
5356 // return current position of file pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
5357 jlong os::current_file_offset(int fd) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5358 return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR);
a61af66fc99e Initial load
duke
parents:
diff changeset
5359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5360
a61af66fc99e Initial load
duke
parents:
diff changeset
5361 // move file pointer to the specified offset
a61af66fc99e Initial load
duke
parents:
diff changeset
5362 jlong os::seek_to_file_offset(int fd, jlong offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5363 return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET);
a61af66fc99e Initial load
duke
parents:
diff changeset
5364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5365
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5366 jlong os::lseek(int fd, jlong offset, int whence) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5367 return (jlong) ::lseek64(fd, offset, whence);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5368 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5369
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5370 char * os::native_path(char *path) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5371 return path;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5372 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5373
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5374 int os::ftruncate(int fd, jlong length) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5375 return ::ftruncate64(fd, length);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5376 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5377
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5378 int os::fsync(int fd) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5379 RESTARTABLE_RETURN_INT(::fsync(fd));
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5380 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5381
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5382 int os::available(int fd, jlong *bytes) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5383 jlong cur, end;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5384 int mode;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5385 struct stat64 buf64;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5386
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5387 if (::fstat64(fd, &buf64) >= 0) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5388 mode = buf64.st_mode;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5389 if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5390 /*
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5391 * XXX: is the following call interruptible? If so, this might
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5392 * need to go through the INTERRUPT_IO() wrapper as for other
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5393 * blocking, interruptible calls in this file.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5394 */
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5395 int n,ioctl_return;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5396
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5397 INTERRUPTIBLE(::ioctl(fd, FIONREAD, &n),ioctl_return,os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5398 if (ioctl_return>= 0) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5399 *bytes = n;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5400 return 1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5401 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5402 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5403 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5404 if ((cur = ::lseek64(fd, 0L, SEEK_CUR)) == -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5405 return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5406 } else if ((end = ::lseek64(fd, 0L, SEEK_END)) == -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5407 return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5408 } else if (::lseek64(fd, cur, SEEK_SET) == -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5409 return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5410 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5411 *bytes = end - cur;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5412 return 1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5413 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5414
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5415 // Map a block of memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
5416 char* os::map_memory(int fd, const char* file_name, size_t file_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5417 char *addr, size_t bytes, bool read_only,
a61af66fc99e Initial load
duke
parents:
diff changeset
5418 bool allow_exec) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5419 int prot;
a61af66fc99e Initial load
duke
parents:
diff changeset
5420 int flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
5421
a61af66fc99e Initial load
duke
parents:
diff changeset
5422 if (read_only) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5423 prot = PROT_READ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5424 flags = MAP_SHARED;
a61af66fc99e Initial load
duke
parents:
diff changeset
5425 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5426 prot = PROT_READ | PROT_WRITE;
a61af66fc99e Initial load
duke
parents:
diff changeset
5427 flags = MAP_PRIVATE;
a61af66fc99e Initial load
duke
parents:
diff changeset
5428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5429
a61af66fc99e Initial load
duke
parents:
diff changeset
5430 if (allow_exec) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5431 prot |= PROT_EXEC;
a61af66fc99e Initial load
duke
parents:
diff changeset
5432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5433
a61af66fc99e Initial load
duke
parents:
diff changeset
5434 if (addr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5435 flags |= MAP_FIXED;
a61af66fc99e Initial load
duke
parents:
diff changeset
5436 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5437
a61af66fc99e Initial load
duke
parents:
diff changeset
5438 char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags,
a61af66fc99e Initial load
duke
parents:
diff changeset
5439 fd, file_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
5440 if (mapped_address == MAP_FAILED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5441 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5443 return mapped_address;
a61af66fc99e Initial load
duke
parents:
diff changeset
5444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5445
a61af66fc99e Initial load
duke
parents:
diff changeset
5446
a61af66fc99e Initial load
duke
parents:
diff changeset
5447 // Remap a block of memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
5448 char* os::remap_memory(int fd, const char* file_name, size_t file_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
5449 char *addr, size_t bytes, bool read_only,
a61af66fc99e Initial load
duke
parents:
diff changeset
5450 bool allow_exec) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5451 // same as map_memory() on this OS
a61af66fc99e Initial load
duke
parents:
diff changeset
5452 return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,
a61af66fc99e Initial load
duke
parents:
diff changeset
5453 allow_exec);
a61af66fc99e Initial load
duke
parents:
diff changeset
5454 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5455
a61af66fc99e Initial load
duke
parents:
diff changeset
5456
a61af66fc99e Initial load
duke
parents:
diff changeset
5457 // Unmap a block of memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
5458 bool os::unmap_memory(char* addr, size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5459 return munmap(addr, bytes) == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5461
a61af66fc99e Initial load
duke
parents:
diff changeset
5462 void os::pause() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5463 char filename[MAX_PATH];
a61af66fc99e Initial load
duke
parents:
diff changeset
5464 if (PauseAtStartupFile && PauseAtStartupFile[0]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5465 jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
a61af66fc99e Initial load
duke
parents:
diff changeset
5466 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5467 jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
5468 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5469
a61af66fc99e Initial load
duke
parents:
diff changeset
5470 int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
a61af66fc99e Initial load
duke
parents:
diff changeset
5471 if (fd != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5472 struct stat buf;
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5473 ::close(fd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5474 while (::stat(filename, &buf) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5475 (void)::poll(NULL, 0, 100);
a61af66fc99e Initial load
duke
parents:
diff changeset
5476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5477 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5478 jio_fprintf(stderr,
a61af66fc99e Initial load
duke
parents:
diff changeset
5479 "Could not open pause file '%s', continuing immediately.\n", filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
5480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5482
a61af66fc99e Initial load
duke
parents:
diff changeset
5483 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
5484 #ifdef INTERPOSE_ON_SYSTEM_SYNCH_FUNCTIONS
a61af66fc99e Initial load
duke
parents:
diff changeset
5485 // Turn this on if you need to trace synch operations.
a61af66fc99e Initial load
duke
parents:
diff changeset
5486 // Set RECORD_SYNCH_LIMIT to a large-enough value,
a61af66fc99e Initial load
duke
parents:
diff changeset
5487 // and call record_synch_enable and record_synch_disable
a61af66fc99e Initial load
duke
parents:
diff changeset
5488 // around the computation of interest.
a61af66fc99e Initial load
duke
parents:
diff changeset
5489
a61af66fc99e Initial load
duke
parents:
diff changeset
5490 void record_synch(char* name, bool returning); // defined below
a61af66fc99e Initial load
duke
parents:
diff changeset
5491
a61af66fc99e Initial load
duke
parents:
diff changeset
5492 class RecordSynch {
a61af66fc99e Initial load
duke
parents:
diff changeset
5493 char* _name;
a61af66fc99e Initial load
duke
parents:
diff changeset
5494 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
5495 RecordSynch(char* name) :_name(name)
a61af66fc99e Initial load
duke
parents:
diff changeset
5496 { record_synch(_name, false); }
a61af66fc99e Initial load
duke
parents:
diff changeset
5497 ~RecordSynch() { record_synch(_name, true); }
a61af66fc99e Initial load
duke
parents:
diff changeset
5498 };
a61af66fc99e Initial load
duke
parents:
diff changeset
5499
a61af66fc99e Initial load
duke
parents:
diff changeset
5500 #define CHECK_SYNCH_OP(ret, name, params, args, inner) \
a61af66fc99e Initial load
duke
parents:
diff changeset
5501 extern "C" ret name params { \
a61af66fc99e Initial load
duke
parents:
diff changeset
5502 typedef ret name##_t params; \
a61af66fc99e Initial load
duke
parents:
diff changeset
5503 static name##_t* implem = NULL; \
a61af66fc99e Initial load
duke
parents:
diff changeset
5504 static int callcount = 0; \
a61af66fc99e Initial load
duke
parents:
diff changeset
5505 if (implem == NULL) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
5506 implem = (name##_t*) dlsym(RTLD_NEXT, #name); \
a61af66fc99e Initial load
duke
parents:
diff changeset
5507 if (implem == NULL) fatal(dlerror()); \
a61af66fc99e Initial load
duke
parents:
diff changeset
5508 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
5509 ++callcount; \
a61af66fc99e Initial load
duke
parents:
diff changeset
5510 RecordSynch _rs(#name); \
a61af66fc99e Initial load
duke
parents:
diff changeset
5511 inner; \
a61af66fc99e Initial load
duke
parents:
diff changeset
5512 return implem args; \
a61af66fc99e Initial load
duke
parents:
diff changeset
5513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5514 // in dbx, examine callcounts this way:
a61af66fc99e Initial load
duke
parents:
diff changeset
5515 // for n in $(eval whereis callcount | awk '{print $2}'); do print $n; done
a61af66fc99e Initial load
duke
parents:
diff changeset
5516
a61af66fc99e Initial load
duke
parents:
diff changeset
5517 #define CHECK_POINTER_OK(p) \
a61af66fc99e Initial load
duke
parents:
diff changeset
5518 (Universe::perm_gen() == NULL || !Universe::is_reserved_heap((oop)(p)))
a61af66fc99e Initial load
duke
parents:
diff changeset
5519 #define CHECK_MU \
a61af66fc99e Initial load
duke
parents:
diff changeset
5520 if (!CHECK_POINTER_OK(mu)) fatal("Mutex must be in C heap only.");
a61af66fc99e Initial load
duke
parents:
diff changeset
5521 #define CHECK_CV \
a61af66fc99e Initial load
duke
parents:
diff changeset
5522 if (!CHECK_POINTER_OK(cv)) fatal("Condvar must be in C heap only.");
a61af66fc99e Initial load
duke
parents:
diff changeset
5523 #define CHECK_P(p) \
a61af66fc99e Initial load
duke
parents:
diff changeset
5524 if (!CHECK_POINTER_OK(p)) fatal(false, "Pointer must be in C heap only.");
a61af66fc99e Initial load
duke
parents:
diff changeset
5525
a61af66fc99e Initial load
duke
parents:
diff changeset
5526 #define CHECK_MUTEX(mutex_op) \
a61af66fc99e Initial load
duke
parents:
diff changeset
5527 CHECK_SYNCH_OP(int, mutex_op, (mutex_t *mu), (mu), CHECK_MU);
a61af66fc99e Initial load
duke
parents:
diff changeset
5528
a61af66fc99e Initial load
duke
parents:
diff changeset
5529 CHECK_MUTEX( mutex_lock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5530 CHECK_MUTEX( _mutex_lock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5531 CHECK_MUTEX( mutex_unlock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5532 CHECK_MUTEX(_mutex_unlock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5533 CHECK_MUTEX( mutex_trylock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5534 CHECK_MUTEX(_mutex_trylock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5535
a61af66fc99e Initial load
duke
parents:
diff changeset
5536 #define CHECK_COND(cond_op) \
a61af66fc99e Initial load
duke
parents:
diff changeset
5537 CHECK_SYNCH_OP(int, cond_op, (cond_t *cv, mutex_t *mu), (cv, mu), CHECK_MU;CHECK_CV);
a61af66fc99e Initial load
duke
parents:
diff changeset
5538
a61af66fc99e Initial load
duke
parents:
diff changeset
5539 CHECK_COND( cond_wait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5540 CHECK_COND(_cond_wait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5541 CHECK_COND(_cond_wait_cancel);
a61af66fc99e Initial load
duke
parents:
diff changeset
5542
a61af66fc99e Initial load
duke
parents:
diff changeset
5543 #define CHECK_COND2(cond_op) \
a61af66fc99e Initial load
duke
parents:
diff changeset
5544 CHECK_SYNCH_OP(int, cond_op, (cond_t *cv, mutex_t *mu, timestruc_t* ts), (cv, mu, ts), CHECK_MU;CHECK_CV);
a61af66fc99e Initial load
duke
parents:
diff changeset
5545
a61af66fc99e Initial load
duke
parents:
diff changeset
5546 CHECK_COND2( cond_timedwait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5547 CHECK_COND2(_cond_timedwait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5548 CHECK_COND2(_cond_timedwait_cancel);
a61af66fc99e Initial load
duke
parents:
diff changeset
5549
a61af66fc99e Initial load
duke
parents:
diff changeset
5550 // do the _lwp_* versions too
a61af66fc99e Initial load
duke
parents:
diff changeset
5551 #define mutex_t lwp_mutex_t
a61af66fc99e Initial load
duke
parents:
diff changeset
5552 #define cond_t lwp_cond_t
a61af66fc99e Initial load
duke
parents:
diff changeset
5553 CHECK_MUTEX( _lwp_mutex_lock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5554 CHECK_MUTEX( _lwp_mutex_unlock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5555 CHECK_MUTEX( _lwp_mutex_trylock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5556 CHECK_MUTEX( __lwp_mutex_lock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5557 CHECK_MUTEX( __lwp_mutex_unlock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5558 CHECK_MUTEX( __lwp_mutex_trylock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5559 CHECK_MUTEX(___lwp_mutex_lock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5560 CHECK_MUTEX(___lwp_mutex_unlock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5561
a61af66fc99e Initial load
duke
parents:
diff changeset
5562 CHECK_COND( _lwp_cond_wait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5563 CHECK_COND( __lwp_cond_wait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5564 CHECK_COND(___lwp_cond_wait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5565
a61af66fc99e Initial load
duke
parents:
diff changeset
5566 CHECK_COND2( _lwp_cond_timedwait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5567 CHECK_COND2( __lwp_cond_timedwait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5568 #undef mutex_t
a61af66fc99e Initial load
duke
parents:
diff changeset
5569 #undef cond_t
a61af66fc99e Initial load
duke
parents:
diff changeset
5570
a61af66fc99e Initial load
duke
parents:
diff changeset
5571 CHECK_SYNCH_OP(int, _lwp_suspend2, (int lwp, int *n), (lwp, n), 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5572 CHECK_SYNCH_OP(int,__lwp_suspend2, (int lwp, int *n), (lwp, n), 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5573 CHECK_SYNCH_OP(int, _lwp_kill, (int lwp, int n), (lwp, n), 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5574 CHECK_SYNCH_OP(int,__lwp_kill, (int lwp, int n), (lwp, n), 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5575 CHECK_SYNCH_OP(int, _lwp_sema_wait, (lwp_sema_t* p), (p), CHECK_P(p));
a61af66fc99e Initial load
duke
parents:
diff changeset
5576 CHECK_SYNCH_OP(int,__lwp_sema_wait, (lwp_sema_t* p), (p), CHECK_P(p));
a61af66fc99e Initial load
duke
parents:
diff changeset
5577 CHECK_SYNCH_OP(int, _lwp_cond_broadcast, (lwp_cond_t* cv), (cv), CHECK_CV);
a61af66fc99e Initial load
duke
parents:
diff changeset
5578 CHECK_SYNCH_OP(int,__lwp_cond_broadcast, (lwp_cond_t* cv), (cv), CHECK_CV);
a61af66fc99e Initial load
duke
parents:
diff changeset
5579
a61af66fc99e Initial load
duke
parents:
diff changeset
5580
a61af66fc99e Initial load
duke
parents:
diff changeset
5581 // recording machinery:
a61af66fc99e Initial load
duke
parents:
diff changeset
5582
a61af66fc99e Initial load
duke
parents:
diff changeset
5583 enum { RECORD_SYNCH_LIMIT = 200 };
a61af66fc99e Initial load
duke
parents:
diff changeset
5584 char* record_synch_name[RECORD_SYNCH_LIMIT];
a61af66fc99e Initial load
duke
parents:
diff changeset
5585 void* record_synch_arg0ptr[RECORD_SYNCH_LIMIT];
a61af66fc99e Initial load
duke
parents:
diff changeset
5586 bool record_synch_returning[RECORD_SYNCH_LIMIT];
a61af66fc99e Initial load
duke
parents:
diff changeset
5587 thread_t record_synch_thread[RECORD_SYNCH_LIMIT];
a61af66fc99e Initial load
duke
parents:
diff changeset
5588 int record_synch_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5589 bool record_synch_enabled = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5590
a61af66fc99e Initial load
duke
parents:
diff changeset
5591 // in dbx, examine recorded data this way:
a61af66fc99e Initial load
duke
parents:
diff changeset
5592 // for n in name arg0ptr returning thread; do print record_synch_$n[0..record_synch_count-1]; done
a61af66fc99e Initial load
duke
parents:
diff changeset
5593
a61af66fc99e Initial load
duke
parents:
diff changeset
5594 void record_synch(char* name, bool returning) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5595 if (record_synch_enabled) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5596 if (record_synch_count < RECORD_SYNCH_LIMIT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5597 record_synch_name[record_synch_count] = name;
a61af66fc99e Initial load
duke
parents:
diff changeset
5598 record_synch_returning[record_synch_count] = returning;
a61af66fc99e Initial load
duke
parents:
diff changeset
5599 record_synch_thread[record_synch_count] = thr_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
5600 record_synch_arg0ptr[record_synch_count] = &name;
a61af66fc99e Initial load
duke
parents:
diff changeset
5601 record_synch_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
5602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5603 // put more checking code here:
a61af66fc99e Initial load
duke
parents:
diff changeset
5604 // ...
a61af66fc99e Initial load
duke
parents:
diff changeset
5605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5606 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5607
a61af66fc99e Initial load
duke
parents:
diff changeset
5608 void record_synch_enable() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5609 // start collecting trace data, if not already doing so
a61af66fc99e Initial load
duke
parents:
diff changeset
5610 if (!record_synch_enabled) record_synch_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5611 record_synch_enabled = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5613
a61af66fc99e Initial load
duke
parents:
diff changeset
5614 void record_synch_disable() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5615 // stop collecting trace data
a61af66fc99e Initial load
duke
parents:
diff changeset
5616 record_synch_enabled = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5617 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5618
a61af66fc99e Initial load
duke
parents:
diff changeset
5619 #endif // INTERPOSE_ON_SYSTEM_SYNCH_FUNCTIONS
a61af66fc99e Initial load
duke
parents:
diff changeset
5620 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
5621
a61af66fc99e Initial load
duke
parents:
diff changeset
5622 const intptr_t thr_time_off = (intptr_t)(&((prusage_t *)(NULL))->pr_utime);
a61af66fc99e Initial load
duke
parents:
diff changeset
5623 const intptr_t thr_time_size = (intptr_t)(&((prusage_t *)(NULL))->pr_ttime) -
a61af66fc99e Initial load
duke
parents:
diff changeset
5624 (intptr_t)(&((prusage_t *)(NULL))->pr_utime);
a61af66fc99e Initial load
duke
parents:
diff changeset
5625
a61af66fc99e Initial load
duke
parents:
diff changeset
5626
a61af66fc99e Initial load
duke
parents:
diff changeset
5627 // JVMTI & JVM monitoring and management support
a61af66fc99e Initial load
duke
parents:
diff changeset
5628 // The thread_cpu_time() and current_thread_cpu_time() are only
a61af66fc99e Initial load
duke
parents:
diff changeset
5629 // supported if is_thread_cpu_time_supported() returns true.
a61af66fc99e Initial load
duke
parents:
diff changeset
5630 // They are not supported on Solaris T1.
a61af66fc99e Initial load
duke
parents:
diff changeset
5631
a61af66fc99e Initial load
duke
parents:
diff changeset
5632 // current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
a61af66fc99e Initial load
duke
parents:
diff changeset
5633 // are used by JVM M&M and JVMTI to get user+sys or user CPU time
a61af66fc99e Initial load
duke
parents:
diff changeset
5634 // of a thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
5635 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5636 // current_thread_cpu_time() and thread_cpu_time(Thread *)
a61af66fc99e Initial load
duke
parents:
diff changeset
5637 // returns the fast estimate available on the platform.
a61af66fc99e Initial load
duke
parents:
diff changeset
5638
a61af66fc99e Initial load
duke
parents:
diff changeset
5639 // hrtime_t gethrvtime() return value includes
a61af66fc99e Initial load
duke
parents:
diff changeset
5640 // user time but does not include system time
a61af66fc99e Initial load
duke
parents:
diff changeset
5641 jlong os::current_thread_cpu_time() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5642 return (jlong) gethrvtime();
a61af66fc99e Initial load
duke
parents:
diff changeset
5643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5644
a61af66fc99e Initial load
duke
parents:
diff changeset
5645 jlong os::thread_cpu_time(Thread *thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5646 // return user level CPU time only to be consistent with
a61af66fc99e Initial load
duke
parents:
diff changeset
5647 // what current_thread_cpu_time returns.
a61af66fc99e Initial load
duke
parents:
diff changeset
5648 // thread_cpu_time_info() must be changed if this changes
a61af66fc99e Initial load
duke
parents:
diff changeset
5649 return os::thread_cpu_time(thread, false /* user time only */);
a61af66fc99e Initial load
duke
parents:
diff changeset
5650 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5651
a61af66fc99e Initial load
duke
parents:
diff changeset
5652 jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5653 if (user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5654 return os::thread_cpu_time(Thread::current(), user_sys_cpu_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
5655 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5656 return os::current_thread_cpu_time();
a61af66fc99e Initial load
duke
parents:
diff changeset
5657 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5658 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5659
a61af66fc99e Initial load
duke
parents:
diff changeset
5660 jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5661 char proc_name[64];
a61af66fc99e Initial load
duke
parents:
diff changeset
5662 int count;
a61af66fc99e Initial load
duke
parents:
diff changeset
5663 prusage_t prusage;
a61af66fc99e Initial load
duke
parents:
diff changeset
5664 jlong lwp_time;
a61af66fc99e Initial load
duke
parents:
diff changeset
5665 int fd;
a61af66fc99e Initial load
duke
parents:
diff changeset
5666
a61af66fc99e Initial load
duke
parents:
diff changeset
5667 sprintf(proc_name, "/proc/%d/lwp/%d/lwpusage",
a61af66fc99e Initial load
duke
parents:
diff changeset
5668 getpid(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5669 thread->osthread()->lwp_id());
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5670 fd = ::open(proc_name, O_RDONLY);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5671 if ( fd == -1 ) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5672
a61af66fc99e Initial load
duke
parents:
diff changeset
5673 do {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5674 count = ::pread(fd,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5675 (void *)&prusage.pr_utime,
a61af66fc99e Initial load
duke
parents:
diff changeset
5676 thr_time_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
5677 thr_time_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5678 } while (count < 0 && errno == EINTR);
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5679 ::close(fd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5680 if ( count < 0 ) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5681
a61af66fc99e Initial load
duke
parents:
diff changeset
5682 if (user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5683 // user + system CPU time
a61af66fc99e Initial load
duke
parents:
diff changeset
5684 lwp_time = (((jlong)prusage.pr_stime.tv_sec +
a61af66fc99e Initial load
duke
parents:
diff changeset
5685 (jlong)prusage.pr_utime.tv_sec) * (jlong)1000000000) +
a61af66fc99e Initial load
duke
parents:
diff changeset
5686 (jlong)prusage.pr_stime.tv_nsec +
a61af66fc99e Initial load
duke
parents:
diff changeset
5687 (jlong)prusage.pr_utime.tv_nsec;
a61af66fc99e Initial load
duke
parents:
diff changeset
5688 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5689 // user level CPU time only
a61af66fc99e Initial load
duke
parents:
diff changeset
5690 lwp_time = ((jlong)prusage.pr_utime.tv_sec * (jlong)1000000000) +
a61af66fc99e Initial load
duke
parents:
diff changeset
5691 (jlong)prusage.pr_utime.tv_nsec;
a61af66fc99e Initial load
duke
parents:
diff changeset
5692 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5693
a61af66fc99e Initial load
duke
parents:
diff changeset
5694 return(lwp_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
5695 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5696
a61af66fc99e Initial load
duke
parents:
diff changeset
5697 void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5698 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits
a61af66fc99e Initial load
duke
parents:
diff changeset
5699 info_ptr->may_skip_backward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
5700 info_ptr->may_skip_forward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
5701 info_ptr->kind = JVMTI_TIMER_USER_CPU; // only user time is returned
a61af66fc99e Initial load
duke
parents:
diff changeset
5702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5703
a61af66fc99e Initial load
duke
parents:
diff changeset
5704 void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5705 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits
a61af66fc99e Initial load
duke
parents:
diff changeset
5706 info_ptr->may_skip_backward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
5707 info_ptr->may_skip_forward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
5708 info_ptr->kind = JVMTI_TIMER_USER_CPU; // only user time is returned
a61af66fc99e Initial load
duke
parents:
diff changeset
5709 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5710
a61af66fc99e Initial load
duke
parents:
diff changeset
5711 bool os::is_thread_cpu_time_supported() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5712 if ( os::Solaris::T2_libthread() || UseBoundThreads ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5713 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5714 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5715 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5716 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5717 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5718
a61af66fc99e Initial load
duke
parents:
diff changeset
5719 // System loadavg support. Returns -1 if load average cannot be obtained.
a61af66fc99e Initial load
duke
parents:
diff changeset
5720 // Return the load average for our processor set if the primitive exists
a61af66fc99e Initial load
duke
parents:
diff changeset
5721 // (Solaris 9 and later). Otherwise just return system wide loadavg.
a61af66fc99e Initial load
duke
parents:
diff changeset
5722 int os::loadavg(double loadavg[], int nelem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5723 if (pset_getloadavg_ptr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5724 return (*pset_getloadavg_ptr)(PS_MYID, loadavg, nelem);
a61af66fc99e Initial load
duke
parents:
diff changeset
5725 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5726 return ::getloadavg(loadavg, nelem);
a61af66fc99e Initial load
duke
parents:
diff changeset
5727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5728 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5729
a61af66fc99e Initial load
duke
parents:
diff changeset
5730 //---------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5731
a61af66fc99e Initial load
duke
parents:
diff changeset
5732 static address same_page(address x, address y) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5733 intptr_t page_bits = -os::vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
5734 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits))
a61af66fc99e Initial load
duke
parents:
diff changeset
5735 return x;
a61af66fc99e Initial load
duke
parents:
diff changeset
5736 else if (x > y)
a61af66fc99e Initial load
duke
parents:
diff changeset
5737 return (address)(intptr_t(y) | ~page_bits) + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5738 else
a61af66fc99e Initial load
duke
parents:
diff changeset
5739 return (address)(intptr_t(y) & page_bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
5740 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5741
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5742 bool os::find(address addr, outputStream* st) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5743 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
5744 memset(&dlinfo, 0, sizeof(dlinfo));
a61af66fc99e Initial load
duke
parents:
diff changeset
5745 if (dladdr(addr, &dlinfo)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5746 #ifdef _LP64
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5747 st->print("0x%016lx: ", addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5748 #else
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5749 st->print("0x%08x: ", addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5750 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
5751 if (dlinfo.dli_sname != NULL)
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5752 st->print("%s+%#lx", dlinfo.dli_sname, addr-(intptr_t)dlinfo.dli_saddr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5753 else if (dlinfo.dli_fname)
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5754 st->print("<offset %#lx>", addr-(intptr_t)dlinfo.dli_fbase);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5755 else
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5756 st->print("<absolute address>");
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5757 if (dlinfo.dli_fname) st->print(" in %s", dlinfo.dli_fname);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5758 #ifdef _LP64
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5759 if (dlinfo.dli_fbase) st->print(" at 0x%016lx", dlinfo.dli_fbase);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5760 #else
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5761 if (dlinfo.dli_fbase) st->print(" at 0x%08x", dlinfo.dli_fbase);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5762 #endif
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5763 st->cr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5764
a61af66fc99e Initial load
duke
parents:
diff changeset
5765 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5766 // decode some bytes around the PC
a61af66fc99e Initial load
duke
parents:
diff changeset
5767 address begin = same_page(addr-40, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
5768 address end = same_page(addr+40, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
5769 address lowest = (address) dlinfo.dli_sname;
a61af66fc99e Initial load
duke
parents:
diff changeset
5770 if (!lowest) lowest = (address) dlinfo.dli_fbase;
a61af66fc99e Initial load
duke
parents:
diff changeset
5771 if (begin < lowest) begin = lowest;
a61af66fc99e Initial load
duke
parents:
diff changeset
5772 Dl_info dlinfo2;
a61af66fc99e Initial load
duke
parents:
diff changeset
5773 if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr
a61af66fc99e Initial load
duke
parents:
diff changeset
5774 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
a61af66fc99e Initial load
duke
parents:
diff changeset
5775 end = (address) dlinfo2.dli_saddr;
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5776 Disassembler::decode(begin, end, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5778 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5779 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5780 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5782
a61af66fc99e Initial load
duke
parents:
diff changeset
5783 // Following function has been added to support HotSparc's libjvm.so running
a61af66fc99e Initial load
duke
parents:
diff changeset
5784 // under Solaris production JDK 1.2.2 / 1.3.0. These came from
a61af66fc99e Initial load
duke
parents:
diff changeset
5785 // src/solaris/hpi/native_threads in the EVM codebase.
a61af66fc99e Initial load
duke
parents:
diff changeset
5786 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5787 // NOTE: This is no longer needed in the 1.3.1 and 1.4 production release
a61af66fc99e Initial load
duke
parents:
diff changeset
5788 // libraries and should thus be removed. We will leave it behind for a while
a61af66fc99e Initial load
duke
parents:
diff changeset
5789 // until we no longer want to able to run on top of 1.3.0 Solaris production
a61af66fc99e Initial load
duke
parents:
diff changeset
5790 // JDK. See 4341971.
a61af66fc99e Initial load
duke
parents:
diff changeset
5791
a61af66fc99e Initial load
duke
parents:
diff changeset
5792 #define STACK_SLACK 0x800
a61af66fc99e Initial load
duke
parents:
diff changeset
5793
a61af66fc99e Initial load
duke
parents:
diff changeset
5794 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
5795 intptr_t sysThreadAvailableStackWithSlack() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5796 stack_t st;
a61af66fc99e Initial load
duke
parents:
diff changeset
5797 intptr_t retval, stack_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
5798 retval = thr_stksegment(&st);
a61af66fc99e Initial load
duke
parents:
diff changeset
5799 assert(retval == 0, "incorrect return value from thr_stksegment");
a61af66fc99e Initial load
duke
parents:
diff changeset
5800 assert((address)&st < (address)st.ss_sp, "Invalid stack base returned");
a61af66fc99e Initial load
duke
parents:
diff changeset
5801 assert((address)&st > (address)st.ss_sp-st.ss_size, "Invalid stack size returned");
a61af66fc99e Initial load
duke
parents:
diff changeset
5802 stack_top=(intptr_t)st.ss_sp-st.ss_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
5803 return ((intptr_t)&stack_top - stack_top - STACK_SLACK);
a61af66fc99e Initial load
duke
parents:
diff changeset
5804 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5805 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5806
a61af66fc99e Initial load
duke
parents:
diff changeset
5807 // Just to get the Kernel build to link on solaris for testing.
a61af66fc99e Initial load
duke
parents:
diff changeset
5808
a61af66fc99e Initial load
duke
parents:
diff changeset
5809 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
5810 class ASGCT_CallTrace;
a61af66fc99e Initial load
duke
parents:
diff changeset
5811 void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext)
a61af66fc99e Initial load
duke
parents:
diff changeset
5812 KERNEL_RETURN;
a61af66fc99e Initial load
duke
parents:
diff changeset
5813 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5814
a61af66fc99e Initial load
duke
parents:
diff changeset
5815
a61af66fc99e Initial load
duke
parents:
diff changeset
5816 // ObjectMonitor park-unpark infrastructure ...
a61af66fc99e Initial load
duke
parents:
diff changeset
5817 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5818 // We implement Solaris and Linux PlatformEvents with the
a61af66fc99e Initial load
duke
parents:
diff changeset
5819 // obvious condvar-mutex-flag triple.
a61af66fc99e Initial load
duke
parents:
diff changeset
5820 // Another alternative that works quite well is pipes:
a61af66fc99e Initial load
duke
parents:
diff changeset
5821 // Each PlatformEvent consists of a pipe-pair.
a61af66fc99e Initial load
duke
parents:
diff changeset
5822 // The thread associated with the PlatformEvent
a61af66fc99e Initial load
duke
parents:
diff changeset
5823 // calls park(), which reads from the input end of the pipe.
a61af66fc99e Initial load
duke
parents:
diff changeset
5824 // Unpark() writes into the other end of the pipe.
a61af66fc99e Initial load
duke
parents:
diff changeset
5825 // The write-side of the pipe must be set NDELAY.
a61af66fc99e Initial load
duke
parents:
diff changeset
5826 // Unfortunately pipes consume a large # of handles.
a61af66fc99e Initial load
duke
parents:
diff changeset
5827 // Native solaris lwp_park() and lwp_unpark() work nicely, too.
a61af66fc99e Initial load
duke
parents:
diff changeset
5828 // Using pipes for the 1st few threads might be workable, however.
a61af66fc99e Initial load
duke
parents:
diff changeset
5829 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5830 // park() is permitted to return spuriously.
a61af66fc99e Initial load
duke
parents:
diff changeset
5831 // Callers of park() should wrap the call to park() in
a61af66fc99e Initial load
duke
parents:
diff changeset
5832 // an appropriate loop. A litmus test for the correct
a61af66fc99e Initial load
duke
parents:
diff changeset
5833 // usage of park is the following: if park() were modified
a61af66fc99e Initial load
duke
parents:
diff changeset
5834 // to immediately return 0 your code should still work,
a61af66fc99e Initial load
duke
parents:
diff changeset
5835 // albeit degenerating to a spin loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
5836 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5837 // An interesting optimization for park() is to use a trylock()
a61af66fc99e Initial load
duke
parents:
diff changeset
5838 // to attempt to acquire the mutex. If the trylock() fails
a61af66fc99e Initial load
duke
parents:
diff changeset
5839 // then we know that a concurrent unpark() operation is in-progress.
a61af66fc99e Initial load
duke
parents:
diff changeset
5840 // in that case the park() code could simply set _count to 0
a61af66fc99e Initial load
duke
parents:
diff changeset
5841 // and return immediately. The subsequent park() operation *might*
a61af66fc99e Initial load
duke
parents:
diff changeset
5842 // return immediately. That's harmless as the caller of park() is
a61af66fc99e Initial load
duke
parents:
diff changeset
5843 // expected to loop. By using trylock() we will have avoided a
a61af66fc99e Initial load
duke
parents:
diff changeset
5844 // avoided a context switch caused by contention on the per-thread mutex.
a61af66fc99e Initial load
duke
parents:
diff changeset
5845 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5846 // TODO-FIXME:
a61af66fc99e Initial load
duke
parents:
diff changeset
5847 // 1. Reconcile Doug's JSR166 j.u.c park-unpark with the
a61af66fc99e Initial load
duke
parents:
diff changeset
5848 // objectmonitor implementation.
a61af66fc99e Initial load
duke
parents:
diff changeset
5849 // 2. Collapse the JSR166 parker event, and the
a61af66fc99e Initial load
duke
parents:
diff changeset
5850 // objectmonitor ParkEvent into a single "Event" construct.
a61af66fc99e Initial load
duke
parents:
diff changeset
5851 // 3. In park() and unpark() add:
a61af66fc99e Initial load
duke
parents:
diff changeset
5852 // assert (Thread::current() == AssociatedWith).
a61af66fc99e Initial load
duke
parents:
diff changeset
5853 // 4. add spurious wakeup injection on a -XX:EarlyParkReturn=N switch.
a61af66fc99e Initial load
duke
parents:
diff changeset
5854 // 1-out-of-N park() operations will return immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
5855 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5856 // _Event transitions in park()
a61af66fc99e Initial load
duke
parents:
diff changeset
5857 // -1 => -1 : illegal
a61af66fc99e Initial load
duke
parents:
diff changeset
5858 // 1 => 0 : pass - return immediately
a61af66fc99e Initial load
duke
parents:
diff changeset
5859 // 0 => -1 : block
a61af66fc99e Initial load
duke
parents:
diff changeset
5860 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5861 // _Event serves as a restricted-range semaphore.
a61af66fc99e Initial load
duke
parents:
diff changeset
5862 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5863 // Another possible encoding of _Event would be with
a61af66fc99e Initial load
duke
parents:
diff changeset
5864 // explicit "PARKED" == 01b and "SIGNALED" == 10b bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
5865 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5866 // TODO-FIXME: add DTRACE probes for:
a61af66fc99e Initial load
duke
parents:
diff changeset
5867 // 1. Tx parks
a61af66fc99e Initial load
duke
parents:
diff changeset
5868 // 2. Ty unparks Tx
a61af66fc99e Initial load
duke
parents:
diff changeset
5869 // 3. Tx resumes from park
a61af66fc99e Initial load
duke
parents:
diff changeset
5870
a61af66fc99e Initial load
duke
parents:
diff changeset
5871
a61af66fc99e Initial load
duke
parents:
diff changeset
5872 // value determined through experimentation
a61af66fc99e Initial load
duke
parents:
diff changeset
5873 #define ROUNDINGFIX 11
a61af66fc99e Initial load
duke
parents:
diff changeset
5874
a61af66fc99e Initial load
duke
parents:
diff changeset
5875 // utility to compute the abstime argument to timedwait.
a61af66fc99e Initial load
duke
parents:
diff changeset
5876 // TODO-FIXME: switch from compute_abstime() to unpackTime().
a61af66fc99e Initial load
duke
parents:
diff changeset
5877
a61af66fc99e Initial load
duke
parents:
diff changeset
5878 static timestruc_t* compute_abstime(timestruc_t* abstime, jlong millis) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5879 // millis is the relative timeout time
a61af66fc99e Initial load
duke
parents:
diff changeset
5880 // abstime will be the absolute timeout time
a61af66fc99e Initial load
duke
parents:
diff changeset
5881 if (millis < 0) millis = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5882 struct timeval now;
a61af66fc99e Initial load
duke
parents:
diff changeset
5883 int status = gettimeofday(&now, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
5884 assert(status == 0, "gettimeofday");
a61af66fc99e Initial load
duke
parents:
diff changeset
5885 jlong seconds = millis / 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
5886 jlong max_wait_period;
a61af66fc99e Initial load
duke
parents:
diff changeset
5887
a61af66fc99e Initial load
duke
parents:
diff changeset
5888 if (UseLWPSynchronization) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5889 // forward port of fix for 4275818 (not sleeping long enough)
a61af66fc99e Initial load
duke
parents:
diff changeset
5890 // There was a bug in Solaris 6, 7 and pre-patch 5 of 8 where
a61af66fc99e Initial load
duke
parents:
diff changeset
5891 // _lwp_cond_timedwait() used a round_down algorithm rather
a61af66fc99e Initial load
duke
parents:
diff changeset
5892 // than a round_up. For millis less than our roundfactor
a61af66fc99e Initial load
duke
parents:
diff changeset
5893 // it rounded down to 0 which doesn't meet the spec.
a61af66fc99e Initial load
duke
parents:
diff changeset
5894 // For millis > roundfactor we may return a bit sooner, but
a61af66fc99e Initial load
duke
parents:
diff changeset
5895 // since we can not accurately identify the patch level and
a61af66fc99e Initial load
duke
parents:
diff changeset
5896 // this has already been fixed in Solaris 9 and 8 we will
a61af66fc99e Initial load
duke
parents:
diff changeset
5897 // leave it alone rather than always rounding down.
a61af66fc99e Initial load
duke
parents:
diff changeset
5898
a61af66fc99e Initial load
duke
parents:
diff changeset
5899 if (millis > 0 && millis < ROUNDINGFIX) millis = ROUNDINGFIX;
a61af66fc99e Initial load
duke
parents:
diff changeset
5900 // It appears that when we go directly through Solaris _lwp_cond_timedwait()
a61af66fc99e Initial load
duke
parents:
diff changeset
5901 // the acceptable max time threshold is smaller than for libthread on 2.5.1 and 2.6
a61af66fc99e Initial load
duke
parents:
diff changeset
5902 max_wait_period = 21000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
5903 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5904 max_wait_period = 50000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
5905 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5906 millis %= 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
5907 if (seconds > max_wait_period) { // see man cond_timedwait(3T)
a61af66fc99e Initial load
duke
parents:
diff changeset
5908 seconds = max_wait_period;
a61af66fc99e Initial load
duke
parents:
diff changeset
5909 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5910 abstime->tv_sec = now.tv_sec + seconds;
a61af66fc99e Initial load
duke
parents:
diff changeset
5911 long usec = now.tv_usec + millis * 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
5912 if (usec >= 1000000) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5913 abstime->tv_sec += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5914 usec -= 1000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
5915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5916 abstime->tv_nsec = usec * 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
5917 return abstime;
a61af66fc99e Initial load
duke
parents:
diff changeset
5918 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5919
a61af66fc99e Initial load
duke
parents:
diff changeset
5920 // Test-and-clear _Event, always leaves _Event set to 0, returns immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
5921 // Conceptually TryPark() should be equivalent to park(0).
a61af66fc99e Initial load
duke
parents:
diff changeset
5922
a61af66fc99e Initial load
duke
parents:
diff changeset
5923 int os::PlatformEvent::TryPark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5924 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5925 const int v = _Event ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5926 guarantee ((v == 0) || (v == 1), "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5927 if (Atomic::cmpxchg (0, &_Event, v) == v) return v ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5928 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5929 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5930
a61af66fc99e Initial load
duke
parents:
diff changeset
5931 void os::PlatformEvent::park() { // AKA: down()
a61af66fc99e Initial load
duke
parents:
diff changeset
5932 // Invariant: Only the thread associated with the Event/PlatformEvent
a61af66fc99e Initial load
duke
parents:
diff changeset
5933 // may call park().
a61af66fc99e Initial load
duke
parents:
diff changeset
5934 int v ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5935 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5936 v = _Event ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5937 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5939 guarantee (v >= 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5940 if (v == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5941 // Do this the hard way by blocking ...
a61af66fc99e Initial load
duke
parents:
diff changeset
5942 // See http://monaco.sfbay/detail.jsf?cr=5094058.
a61af66fc99e Initial load
duke
parents:
diff changeset
5943 // TODO-FIXME: for Solaris SPARC set fprs.FEF=0 prior to parking.
a61af66fc99e Initial load
duke
parents:
diff changeset
5944 // Only for SPARC >= V8PlusA
a61af66fc99e Initial load
duke
parents:
diff changeset
5945 #if defined(__sparc) && defined(COMPILER2)
a61af66fc99e Initial load
duke
parents:
diff changeset
5946 if (ClearFPUAtPark) { _mark_fpu_nosave() ; }
a61af66fc99e Initial load
duke
parents:
diff changeset
5947 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
5948 int status = os::Solaris::mutex_lock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5949 assert_status(status == 0, status, "mutex_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
5950 guarantee (_nParked == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5951 ++ _nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5952 while (_Event < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5953 // for some reason, under 2.7 lwp_cond_wait() may return ETIME ...
a61af66fc99e Initial load
duke
parents:
diff changeset
5954 // Treat this the same as if the wait was interrupted
a61af66fc99e Initial load
duke
parents:
diff changeset
5955 // With usr/lib/lwp going to kernel, always handle ETIME
a61af66fc99e Initial load
duke
parents:
diff changeset
5956 status = os::Solaris::cond_wait(_cond, _mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5957 if (status == ETIME) status = EINTR ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5958 assert_status(status == 0 || status == EINTR, status, "cond_wait");
a61af66fc99e Initial load
duke
parents:
diff changeset
5959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5960 -- _nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5961 _Event = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5962 status = os::Solaris::mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5963 assert_status(status == 0, status, "mutex_unlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
5964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5966
a61af66fc99e Initial load
duke
parents:
diff changeset
5967 int os::PlatformEvent::park(jlong millis) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5968 guarantee (_nParked == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5969 int v ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5970 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5971 v = _Event ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5972 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5973 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5974 guarantee (v >= 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5975 if (v != 0) return OS_OK ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5976
a61af66fc99e Initial load
duke
parents:
diff changeset
5977 int ret = OS_TIMEOUT;
a61af66fc99e Initial load
duke
parents:
diff changeset
5978 timestruc_t abst;
a61af66fc99e Initial load
duke
parents:
diff changeset
5979 compute_abstime (&abst, millis);
a61af66fc99e Initial load
duke
parents:
diff changeset
5980
a61af66fc99e Initial load
duke
parents:
diff changeset
5981 // See http://monaco.sfbay/detail.jsf?cr=5094058.
a61af66fc99e Initial load
duke
parents:
diff changeset
5982 // For Solaris SPARC set fprs.FEF=0 prior to parking.
a61af66fc99e Initial load
duke
parents:
diff changeset
5983 // Only for SPARC >= V8PlusA
a61af66fc99e Initial load
duke
parents:
diff changeset
5984 #if defined(__sparc) && defined(COMPILER2)
a61af66fc99e Initial load
duke
parents:
diff changeset
5985 if (ClearFPUAtPark) { _mark_fpu_nosave() ; }
a61af66fc99e Initial load
duke
parents:
diff changeset
5986 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
5987 int status = os::Solaris::mutex_lock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5988 assert_status(status == 0, status, "mutex_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
5989 guarantee (_nParked == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5990 ++ _nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5991 while (_Event < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5992 int status = os::Solaris::cond_timedwait(_cond, _mutex, &abst);
a61af66fc99e Initial load
duke
parents:
diff changeset
5993 assert_status(status == 0 || status == EINTR ||
a61af66fc99e Initial load
duke
parents:
diff changeset
5994 status == ETIME || status == ETIMEDOUT,
a61af66fc99e Initial load
duke
parents:
diff changeset
5995 status, "cond_timedwait");
a61af66fc99e Initial load
duke
parents:
diff changeset
5996 if (!FilterSpuriousWakeups) break ; // previous semantics
a61af66fc99e Initial load
duke
parents:
diff changeset
5997 if (status == ETIME || status == ETIMEDOUT) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5998 // We consume and ignore EINTR and spurious wakeups.
a61af66fc99e Initial load
duke
parents:
diff changeset
5999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6000 -- _nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6001 if (_Event >= 0) ret = OS_OK ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6002 _Event = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6003 status = os::Solaris::mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
6004 assert_status(status == 0, status, "mutex_unlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
6005 return ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
6006 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6007
a61af66fc99e Initial load
duke
parents:
diff changeset
6008 void os::PlatformEvent::unpark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
6009 int v, AnyWaiters;
a61af66fc99e Initial load
duke
parents:
diff changeset
6010
a61af66fc99e Initial load
duke
parents:
diff changeset
6011 // Increment _Event.
a61af66fc99e Initial load
duke
parents:
diff changeset
6012 // Another acceptable implementation would be to simply swap 1
a61af66fc99e Initial load
duke
parents:
diff changeset
6013 // into _Event:
a61af66fc99e Initial load
duke
parents:
diff changeset
6014 // if (Swap (&_Event, 1) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6015 // mutex_lock (_mutex) ; AnyWaiters = nParked; mutex_unlock (_mutex) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6016 // if (AnyWaiters) cond_signal (_cond) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6017 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
6018
a61af66fc99e Initial load
duke
parents:
diff changeset
6019 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6020 v = _Event ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6021 if (v > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6022 // The LD of _Event could have reordered or be satisfied
a61af66fc99e Initial load
duke
parents:
diff changeset
6023 // by a read-aside from this processor's write buffer.
a61af66fc99e Initial load
duke
parents:
diff changeset
6024 // To avoid problems execute a barrier and then
a61af66fc99e Initial load
duke
parents:
diff changeset
6025 // ratify the value. A degenerate CAS() would also work.
a61af66fc99e Initial load
duke
parents:
diff changeset
6026 // Viz., CAS (v+0, &_Event, v) == v).
a61af66fc99e Initial load
duke
parents:
diff changeset
6027 OrderAccess::fence() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6028 if (_Event == v) return ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6029 continue ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6031 if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6032 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6033
a61af66fc99e Initial load
duke
parents:
diff changeset
6034 // If the thread associated with the event was parked, wake it.
a61af66fc99e Initial load
duke
parents:
diff changeset
6035 if (v < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6036 int status ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6037 // Wait for the thread assoc with the PlatformEvent to vacate.
a61af66fc99e Initial load
duke
parents:
diff changeset
6038 status = os::Solaris::mutex_lock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
6039 assert_status(status == 0, status, "mutex_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
6040 AnyWaiters = _nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6041 status = os::Solaris::mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
6042 assert_status(status == 0, status, "mutex_unlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
6043 guarantee (AnyWaiters == 0 || AnyWaiters == 1, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6044 if (AnyWaiters != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6045 // We intentional signal *after* dropping the lock
a61af66fc99e Initial load
duke
parents:
diff changeset
6046 // to avoid a common class of futile wakeups.
a61af66fc99e Initial load
duke
parents:
diff changeset
6047 status = os::Solaris::cond_signal(_cond);
a61af66fc99e Initial load
duke
parents:
diff changeset
6048 assert_status(status == 0, status, "cond_signal");
a61af66fc99e Initial load
duke
parents:
diff changeset
6049 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6050 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6051 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6052
a61af66fc99e Initial load
duke
parents:
diff changeset
6053 // JSR166
a61af66fc99e Initial load
duke
parents:
diff changeset
6054 // -------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
6055
a61af66fc99e Initial load
duke
parents:
diff changeset
6056 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
6057 * The solaris and linux implementations of park/unpark are fairly
a61af66fc99e Initial load
duke
parents:
diff changeset
6058 * conservative for now, but can be improved. They currently use a
a61af66fc99e Initial load
duke
parents:
diff changeset
6059 * mutex/condvar pair, plus _counter.
a61af66fc99e Initial load
duke
parents:
diff changeset
6060 * Park decrements _counter if > 0, else does a condvar wait. Unpark
a61af66fc99e Initial load
duke
parents:
diff changeset
6061 * sets count to 1 and signals condvar. Only one thread ever waits
a61af66fc99e Initial load
duke
parents:
diff changeset
6062 * on the condvar. Contention seen when trying to park implies that someone
a61af66fc99e Initial load
duke
parents:
diff changeset
6063 * is unparking you, so don't wait. And spurious returns are fine, so there
a61af66fc99e Initial load
duke
parents:
diff changeset
6064 * is no need to track notifications.
a61af66fc99e Initial load
duke
parents:
diff changeset
6065 */
a61af66fc99e Initial load
duke
parents:
diff changeset
6066
a61af66fc99e Initial load
duke
parents:
diff changeset
6067 #define NANOSECS_PER_SEC 1000000000
a61af66fc99e Initial load
duke
parents:
diff changeset
6068 #define NANOSECS_PER_MILLISEC 1000000
a61af66fc99e Initial load
duke
parents:
diff changeset
6069 #define MAX_SECS 100000000
a61af66fc99e Initial load
duke
parents:
diff changeset
6070
a61af66fc99e Initial load
duke
parents:
diff changeset
6071 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
6072 * This code is common to linux and solaris and will be moved to a
a61af66fc99e Initial load
duke
parents:
diff changeset
6073 * common place in dolphin.
a61af66fc99e Initial load
duke
parents:
diff changeset
6074 *
a61af66fc99e Initial load
duke
parents:
diff changeset
6075 * The passed in time value is either a relative time in nanoseconds
a61af66fc99e Initial load
duke
parents:
diff changeset
6076 * or an absolute time in milliseconds. Either way it has to be unpacked
a61af66fc99e Initial load
duke
parents:
diff changeset
6077 * into suitable seconds and nanoseconds components and stored in the
a61af66fc99e Initial load
duke
parents:
diff changeset
6078 * given timespec structure.
a61af66fc99e Initial load
duke
parents:
diff changeset
6079 * Given time is a 64-bit value and the time_t used in the timespec is only
a61af66fc99e Initial load
duke
parents:
diff changeset
6080 * a signed-32-bit value (except on 64-bit Linux) we have to watch for
a61af66fc99e Initial load
duke
parents:
diff changeset
6081 * overflow if times way in the future are given. Further on Solaris versions
a61af66fc99e Initial load
duke
parents:
diff changeset
6082 * prior to 10 there is a restriction (see cond_timedwait) that the specified
a61af66fc99e Initial load
duke
parents:
diff changeset
6083 * number of seconds, in abstime, is less than current_time + 100,000,000.
a61af66fc99e Initial load
duke
parents:
diff changeset
6084 * As it will be 28 years before "now + 100000000" will overflow we can
a61af66fc99e Initial load
duke
parents:
diff changeset
6085 * ignore overflow and just impose a hard-limit on seconds using the value
a61af66fc99e Initial load
duke
parents:
diff changeset
6086 * of "now + 100,000,000". This places a limit on the timeout of about 3.17
a61af66fc99e Initial load
duke
parents:
diff changeset
6087 * years from "now".
a61af66fc99e Initial load
duke
parents:
diff changeset
6088 */
a61af66fc99e Initial load
duke
parents:
diff changeset
6089 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6090 assert (time > 0, "convertTime");
a61af66fc99e Initial load
duke
parents:
diff changeset
6091
a61af66fc99e Initial load
duke
parents:
diff changeset
6092 struct timeval now;
a61af66fc99e Initial load
duke
parents:
diff changeset
6093 int status = gettimeofday(&now, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
6094 assert(status == 0, "gettimeofday");
a61af66fc99e Initial load
duke
parents:
diff changeset
6095
a61af66fc99e Initial load
duke
parents:
diff changeset
6096 time_t max_secs = now.tv_sec + MAX_SECS;
a61af66fc99e Initial load
duke
parents:
diff changeset
6097
a61af66fc99e Initial load
duke
parents:
diff changeset
6098 if (isAbsolute) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6099 jlong secs = time / 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
6100 if (secs > max_secs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6101 absTime->tv_sec = max_secs;
a61af66fc99e Initial load
duke
parents:
diff changeset
6102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6103 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6104 absTime->tv_sec = secs;
a61af66fc99e Initial load
duke
parents:
diff changeset
6105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6106 absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC;
a61af66fc99e Initial load
duke
parents:
diff changeset
6107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6108 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6109 jlong secs = time / NANOSECS_PER_SEC;
a61af66fc99e Initial load
duke
parents:
diff changeset
6110 if (secs >= MAX_SECS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6111 absTime->tv_sec = max_secs;
a61af66fc99e Initial load
duke
parents:
diff changeset
6112 absTime->tv_nsec = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
6113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6114 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6115 absTime->tv_sec = now.tv_sec + secs;
a61af66fc99e Initial load
duke
parents:
diff changeset
6116 absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
6117 if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6118 absTime->tv_nsec -= NANOSECS_PER_SEC;
a61af66fc99e Initial load
duke
parents:
diff changeset
6119 ++absTime->tv_sec; // note: this must be <= max_secs
a61af66fc99e Initial load
duke
parents:
diff changeset
6120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6123 assert(absTime->tv_sec >= 0, "tv_sec < 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
6124 assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs");
a61af66fc99e Initial load
duke
parents:
diff changeset
6125 assert(absTime->tv_nsec >= 0, "tv_nsec < 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
6126 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");
a61af66fc99e Initial load
duke
parents:
diff changeset
6127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6128
a61af66fc99e Initial load
duke
parents:
diff changeset
6129 void Parker::park(bool isAbsolute, jlong time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6130
a61af66fc99e Initial load
duke
parents:
diff changeset
6131 // Optional fast-path check:
a61af66fc99e Initial load
duke
parents:
diff changeset
6132 // Return immediately if a permit is available.
a61af66fc99e Initial load
duke
parents:
diff changeset
6133 if (_counter > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6134 _counter = 0 ;
1117
95e9083cf4a7 6822370: ReentrantReadWriteLock: threads hung when there are no threads holding onto the lock (Netra x4450)
dholmes
parents: 894
diff changeset
6135 OrderAccess::fence();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6136 return ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6138
a61af66fc99e Initial load
duke
parents:
diff changeset
6139 // Optional fast-exit: Check interrupt before trying to wait
a61af66fc99e Initial load
duke
parents:
diff changeset
6140 Thread* thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
6141 assert(thread->is_Java_thread(), "Must be JavaThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
6142 JavaThread *jt = (JavaThread *)thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
6143 if (Thread::is_interrupted(thread, false)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6144 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
6145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6146
a61af66fc99e Initial load
duke
parents:
diff changeset
6147 // First, demultiplex/decode time arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
6148 timespec absTime;
1865
1c352af0135d 6763959: java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
acorn
parents: 1681
diff changeset
6149 if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6150 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
6151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6152 if (time > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6153 // Warning: this code might be exposed to the old Solaris time
a61af66fc99e Initial load
duke
parents:
diff changeset
6154 // round-down bugs. Grep "roundingFix" for details.
a61af66fc99e Initial load
duke
parents:
diff changeset
6155 unpackTime(&absTime, isAbsolute, time);
a61af66fc99e Initial load
duke
parents:
diff changeset
6156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6157
a61af66fc99e Initial load
duke
parents:
diff changeset
6158 // Enter safepoint region
a61af66fc99e Initial load
duke
parents:
diff changeset
6159 // Beware of deadlocks such as 6317397.
a61af66fc99e Initial load
duke
parents:
diff changeset
6160 // The per-thread Parker:: _mutex is a classic leaf-lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
6161 // In particular a thread must never block on the Threads_lock while
a61af66fc99e Initial load
duke
parents:
diff changeset
6162 // holding the Parker:: mutex. If safepoints are pending both the
a61af66fc99e Initial load
duke
parents:
diff changeset
6163 // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
6164 ThreadBlockInVM tbivm(jt);
a61af66fc99e Initial load
duke
parents:
diff changeset
6165
a61af66fc99e Initial load
duke
parents:
diff changeset
6166 // Don't wait if cannot get lock since interference arises from
a61af66fc99e Initial load
duke
parents:
diff changeset
6167 // unblocking. Also. check interrupt before trying wait
a61af66fc99e Initial load
duke
parents:
diff changeset
6168 if (Thread::is_interrupted(thread, false) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
6169 os::Solaris::mutex_trylock(_mutex) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6170 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
6171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6172
a61af66fc99e Initial load
duke
parents:
diff changeset
6173 int status ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6174
a61af66fc99e Initial load
duke
parents:
diff changeset
6175 if (_counter > 0) { // no wait needed
a61af66fc99e Initial load
duke
parents:
diff changeset
6176 _counter = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
6177 status = os::Solaris::mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
6178 assert (status == 0, "invariant") ;
1117
95e9083cf4a7 6822370: ReentrantReadWriteLock: threads hung when there are no threads holding onto the lock (Netra x4450)
dholmes
parents: 894
diff changeset
6179 OrderAccess::fence();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6180 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
6181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6182
a61af66fc99e Initial load
duke
parents:
diff changeset
6183 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
6184 // Don't catch signals while blocked; let the running threads have the signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
6185 // (This allows a debugger to break into the running thread.)
a61af66fc99e Initial load
duke
parents:
diff changeset
6186 sigset_t oldsigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
6187 sigset_t* allowdebug_blocked = os::Solaris::allowdebug_blocked_signals();
a61af66fc99e Initial load
duke
parents:
diff changeset
6188 thr_sigsetmask(SIG_BLOCK, allowdebug_blocked, &oldsigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
6189 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
6190
a61af66fc99e Initial load
duke
parents:
diff changeset
6191 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
a61af66fc99e Initial load
duke
parents:
diff changeset
6192 jt->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
6193 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
a61af66fc99e Initial load
duke
parents:
diff changeset
6194
a61af66fc99e Initial load
duke
parents:
diff changeset
6195 // Do this the hard way by blocking ...
a61af66fc99e Initial load
duke
parents:
diff changeset
6196 // See http://monaco.sfbay/detail.jsf?cr=5094058.
a61af66fc99e Initial load
duke
parents:
diff changeset
6197 // TODO-FIXME: for Solaris SPARC set fprs.FEF=0 prior to parking.
a61af66fc99e Initial load
duke
parents:
diff changeset
6198 // Only for SPARC >= V8PlusA
a61af66fc99e Initial load
duke
parents:
diff changeset
6199 #if defined(__sparc) && defined(COMPILER2)
a61af66fc99e Initial load
duke
parents:
diff changeset
6200 if (ClearFPUAtPark) { _mark_fpu_nosave() ; }
a61af66fc99e Initial load
duke
parents:
diff changeset
6201 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
6202
a61af66fc99e Initial load
duke
parents:
diff changeset
6203 if (time == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6204 status = os::Solaris::cond_wait (_cond, _mutex) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6205 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6206 status = os::Solaris::cond_timedwait (_cond, _mutex, &absTime);
a61af66fc99e Initial load
duke
parents:
diff changeset
6207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6208 // Note that an untimed cond_wait() can sometimes return ETIME on older
a61af66fc99e Initial load
duke
parents:
diff changeset
6209 // versions of the Solaris.
a61af66fc99e Initial load
duke
parents:
diff changeset
6210 assert_status(status == 0 || status == EINTR ||
a61af66fc99e Initial load
duke
parents:
diff changeset
6211 status == ETIME || status == ETIMEDOUT,
a61af66fc99e Initial load
duke
parents:
diff changeset
6212 status, "cond_timedwait");
a61af66fc99e Initial load
duke
parents:
diff changeset
6213
a61af66fc99e Initial load
duke
parents:
diff changeset
6214 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
6215 thr_sigsetmask(SIG_SETMASK, &oldsigs, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
6216 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
6217 _counter = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6218 status = os::Solaris::mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
6219 assert_status(status == 0, status, "mutex_unlock") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6220
a61af66fc99e Initial load
duke
parents:
diff changeset
6221 // If externally suspended while waiting, re-suspend
a61af66fc99e Initial load
duke
parents:
diff changeset
6222 if (jt->handle_special_suspend_equivalent_condition()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6223 jt->java_suspend_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
6224 }
1117
95e9083cf4a7 6822370: ReentrantReadWriteLock: threads hung when there are no threads holding onto the lock (Netra x4450)
dholmes
parents: 894
diff changeset
6225 OrderAccess::fence();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6227
a61af66fc99e Initial load
duke
parents:
diff changeset
6228 void Parker::unpark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
6229 int s, status ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6230 status = os::Solaris::mutex_lock (_mutex) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6231 assert (status == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6232 s = _counter;
a61af66fc99e Initial load
duke
parents:
diff changeset
6233 _counter = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
6234 status = os::Solaris::mutex_unlock (_mutex) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6235 assert (status == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6236
a61af66fc99e Initial load
duke
parents:
diff changeset
6237 if (s < 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6238 status = os::Solaris::cond_signal (_cond) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6239 assert (status == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6242
a61af66fc99e Initial load
duke
parents:
diff changeset
6243 extern char** environ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6244
a61af66fc99e Initial load
duke
parents:
diff changeset
6245 // Run the specified command in a separate process. Return its exit value,
a61af66fc99e Initial load
duke
parents:
diff changeset
6246 // or -1 on failure (e.g. can't fork a new process).
a61af66fc99e Initial load
duke
parents:
diff changeset
6247 // Unlike system(), this function can be called from signal handler. It
a61af66fc99e Initial load
duke
parents:
diff changeset
6248 // doesn't block SIGINT et al.
a61af66fc99e Initial load
duke
parents:
diff changeset
6249 int os::fork_and_exec(char* cmd) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6250 char * argv[4];
a61af66fc99e Initial load
duke
parents:
diff changeset
6251 argv[0] = (char *)"sh";
a61af66fc99e Initial load
duke
parents:
diff changeset
6252 argv[1] = (char *)"-c";
a61af66fc99e Initial load
duke
parents:
diff changeset
6253 argv[2] = cmd;
a61af66fc99e Initial load
duke
parents:
diff changeset
6254 argv[3] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
6255
a61af66fc99e Initial load
duke
parents:
diff changeset
6256 // fork is async-safe, fork1 is not so can't use in signal handler
a61af66fc99e Initial load
duke
parents:
diff changeset
6257 pid_t pid;
a61af66fc99e Initial load
duke
parents:
diff changeset
6258 Thread* t = ThreadLocalStorage::get_thread_slow();
a61af66fc99e Initial load
duke
parents:
diff changeset
6259 if (t != NULL && t->is_inside_signal_handler()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6260 pid = fork();
a61af66fc99e Initial load
duke
parents:
diff changeset
6261 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6262 pid = fork1();
a61af66fc99e Initial load
duke
parents:
diff changeset
6263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6264
a61af66fc99e Initial load
duke
parents:
diff changeset
6265 if (pid < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6266 // fork failed
a61af66fc99e Initial load
duke
parents:
diff changeset
6267 warning("fork failed: %s", strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
6268 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
6269
a61af66fc99e Initial load
duke
parents:
diff changeset
6270 } else if (pid == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6271 // child process
a61af66fc99e Initial load
duke
parents:
diff changeset
6272
a61af66fc99e Initial load
duke
parents:
diff changeset
6273 // try to be consistent with system(), which uses "/usr/bin/sh" on Solaris
a61af66fc99e Initial load
duke
parents:
diff changeset
6274 execve("/usr/bin/sh", argv, environ);
a61af66fc99e Initial load
duke
parents:
diff changeset
6275
a61af66fc99e Initial load
duke
parents:
diff changeset
6276 // execve failed
a61af66fc99e Initial load
duke
parents:
diff changeset
6277 _exit(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
6278
a61af66fc99e Initial load
duke
parents:
diff changeset
6279 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6280 // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
6281 // care about the actual exit code, for now.
a61af66fc99e Initial load
duke
parents:
diff changeset
6282
a61af66fc99e Initial load
duke
parents:
diff changeset
6283 int status;
a61af66fc99e Initial load
duke
parents:
diff changeset
6284
a61af66fc99e Initial load
duke
parents:
diff changeset
6285 // Wait for the child process to exit. This returns immediately if
a61af66fc99e Initial load
duke
parents:
diff changeset
6286 // the child has already exited. */
a61af66fc99e Initial load
duke
parents:
diff changeset
6287 while (waitpid(pid, &status, 0) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6288 switch (errno) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6289 case ECHILD: return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
6290 case EINTR: break;
a61af66fc99e Initial load
duke
parents:
diff changeset
6291 default: return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
6292 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6294
a61af66fc99e Initial load
duke
parents:
diff changeset
6295 if (WIFEXITED(status)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6296 // The child exited normally; get its exit code.
a61af66fc99e Initial load
duke
parents:
diff changeset
6297 return WEXITSTATUS(status);
a61af66fc99e Initial load
duke
parents:
diff changeset
6298 } else if (WIFSIGNALED(status)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6299 // The child exited because of a signal
a61af66fc99e Initial load
duke
parents:
diff changeset
6300 // The best value to return is 0x80 + signal number,
a61af66fc99e Initial load
duke
parents:
diff changeset
6301 // because that is what all Unix shells do, and because
a61af66fc99e Initial load
duke
parents:
diff changeset
6302 // it allows callers to distinguish between process exit and
a61af66fc99e Initial load
duke
parents:
diff changeset
6303 // process death by signal.
a61af66fc99e Initial load
duke
parents:
diff changeset
6304 return 0x80 + WTERMSIG(status);
a61af66fc99e Initial load
duke
parents:
diff changeset
6305 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6306 // Unknown exit code; pass it through
a61af66fc99e Initial load
duke
parents:
diff changeset
6307 return status;
a61af66fc99e Initial load
duke
parents:
diff changeset
6308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6310 }
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6311
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6312 // is_headless_jre()
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6313 //
4082
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6314 // Test for the existence of xawt/libmawt.so or libawt_xawt.so
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6315 // in order to report if we are running in a headless jre
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6316 //
4082
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6317 // Since JDK8 xawt/libmawt.so was moved into the same directory
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6318 // as libawt.so, and renamed libawt_xawt.so
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6319 //
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6320 bool os::is_headless_jre() {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6321 struct stat statbuf;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6322 char buf[MAXPATHLEN];
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6323 char libmawtpath[MAXPATHLEN];
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6324 const char *xawtstr = "/xawt/libmawt.so";
4082
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6325 const char *new_xawtstr = "/libawt_xawt.so";
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6326 char *p;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6327
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6328 // Get path to libjvm.so
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6329 os::jvm_path(buf, sizeof(buf));
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6330
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6331 // Get rid of libjvm.so
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6332 p = strrchr(buf, '/');
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6333 if (p == NULL) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6334 else *p = '\0';
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6335
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6336 // Get rid of client or server
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6337 p = strrchr(buf, '/');
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6338 if (p == NULL) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6339 else *p = '\0';
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6340
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6341 // check xawt/libmawt.so
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6342 strcpy(libmawtpath, buf);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6343 strcat(libmawtpath, xawtstr);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6344 if (::stat(libmawtpath, &statbuf) == 0) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6345
4082
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6346 // check libawt_xawt.so
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6347 strcpy(libmawtpath, buf);
4082
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6348 strcat(libmawtpath, new_xawtstr);
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6349 if (::stat(libmawtpath, &statbuf) == 0) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6350
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6351 return true;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6352 }
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6353
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6354 size_t os::write(int fd, const void *buf, unsigned int nBytes) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6355 INTERRUPTIBLE_RETURN_INT(::write(fd, buf, nBytes), os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6356 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6357
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6358 int os::close(int fd) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6359 RESTARTABLE_RETURN_INT(::close(fd));
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6360 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6361
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6362 int os::socket_close(int fd) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6363 RESTARTABLE_RETURN_INT(::close(fd));
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6364 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6365
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6366 int os::recv(int fd, char *buf, int nBytes, int flags) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6367 INTERRUPTIBLE_RETURN_INT(::recv(fd, buf, nBytes, flags), os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6368 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6369
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6370
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6371 int os::send(int fd, char *buf, int nBytes, int flags) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6372 INTERRUPTIBLE_RETURN_INT(::send(fd, buf, nBytes, flags), os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6373 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6374
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6375 int os::raw_send(int fd, char *buf, int nBytes, int flags) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6376 RESTARTABLE_RETURN_INT(::send(fd, buf, nBytes, flags));
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6377 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6378
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6379 // As both poll and select can be interrupted by signals, we have to be
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6380 // prepared to restart the system call after updating the timeout, unless
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6381 // a poll() is done with timeout == -1, in which case we repeat with this
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6382 // "wait forever" value.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6383
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6384 int os::timeout(int fd, long timeout) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6385 int res;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6386 struct timeval t;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6387 julong prevtime, newtime;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6388 static const char* aNull = 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6389 struct pollfd pfd;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6390 pfd.fd = fd;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6391 pfd.events = POLLIN;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6392
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6393 gettimeofday(&t, &aNull);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6394 prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6395
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6396 for(;;) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6397 INTERRUPTIBLE_NORESTART(::poll(&pfd, 1, timeout), res, os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6398 if(res == OS_ERR && errno == EINTR) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6399 if(timeout != -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6400 gettimeofday(&t, &aNull);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6401 newtime = ((julong)t.tv_sec * 1000) + t.tv_usec /1000;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6402 timeout -= newtime - prevtime;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6403 if(timeout <= 0)
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6404 return OS_OK;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6405 prevtime = newtime;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6406 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6407 } else return res;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6408 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6409 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6410
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6411 int os::connect(int fd, struct sockaddr *him, int len) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6412 int _result;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6413 INTERRUPTIBLE_NORESTART(::connect(fd, him, len), _result,
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6414 os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6415
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6416 // Depending on when thread interruption is reset, _result could be
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6417 // one of two values when errno == EINTR
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6418
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6419 if (((_result == OS_INTRPT) || (_result == OS_ERR))
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6420 && (errno == EINTR)) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6421 /* restarting a connect() changes its errno semantics */
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6422 INTERRUPTIBLE(::connect(fd, him, len), _result,
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6423 os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6424 /* undo these changes */
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6425 if (_result == OS_ERR) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6426 if (errno == EALREADY) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6427 errno = EINPROGRESS; /* fall through */
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6428 } else if (errno == EISCONN) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6429 errno = 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6430 return OS_OK;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6431 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6432 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6433 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6434 return _result;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6435 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6436
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6437 int os::accept(int fd, struct sockaddr *him, int *len) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6438 if (fd < 0)
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6439 return OS_ERR;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6440 INTERRUPTIBLE_RETURN_INT((int)::accept(fd, him,\
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6441 (socklen_t*) len), os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6442 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6443
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6444 int os::recvfrom(int fd, char *buf, int nBytes, int flags,
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6445 sockaddr *from, int *fromlen) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6446 //%%note jvm_r11
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6447 INTERRUPTIBLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes,\
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6448 flags, from, fromlen), os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6449 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6450
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6451 int os::sendto(int fd, char *buf, int len, int flags,
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6452 struct sockaddr *to, int tolen) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6453 //%%note jvm_r11
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6454 INTERRUPTIBLE_RETURN_INT((int)::sendto(fd, buf, len, flags,\
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6455 to, tolen), os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6456 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6457
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6458 int os::socket_available(int fd, jint *pbytes) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6459 if (fd < 0)
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6460 return OS_OK;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6461
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6462 int ret;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6463
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6464 RESTARTABLE(::ioctl(fd, FIONREAD, pbytes), ret);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6465
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6466 //%% note ioctl can return 0 when successful, JVM_SocketAvailable
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6467 // is expected to return 0 on failure and 1 on success to the jdk.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6468
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6469 return (ret == OS_ERR) ? 0 : 1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6470 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6471
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6472
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6473 int os::bind(int fd, struct sockaddr *him, int len) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6474 INTERRUPTIBLE_RETURN_INT_NORESTART(::bind(fd, him, len),\
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6475 os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6476 }