Mercurial > hg > truffle
comparison src/os/aix/vm/os_aix.cpp @ 20710:c5e86c5cd22e
8066964: ppc64: argument and return type profiling, fix problem with popframe
Reviewed-by: roland, kvn
author | goetz |
---|---|
date | Fri, 12 Dec 2014 08:48:56 +0100 |
parents | 03c5d509a811 |
children |
comparison
equal
deleted
inserted
replaced
20709:28f116adb50c | 20710:c5e86c5cd22e |
---|---|
112 tid64_t* IndexPointer, | 112 tid64_t* IndexPointer, |
113 int Count); | 113 int Count); |
114 } | 114 } |
115 #endif | 115 #endif |
116 | 116 |
117 // Excerpts from systemcfg.h definitions newer than AIX 5.3 | |
118 #ifndef PV_7 | |
119 # define PV_7 0x200000 // Power PC 7 | |
120 # define PV_7_Compat 0x208000 // Power PC 7 | |
121 #endif | |
122 | |
123 #define MAX_PATH (2 * K) | 117 #define MAX_PATH (2 * K) |
124 | 118 |
125 // for timer info max values which include all bits | 119 // for timer info max values which include all bits |
126 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) | 120 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) |
127 // for multipage initialization error analysis (in 'g_multipage_error') | 121 // for multipage initialization error analysis (in 'g_multipage_error') |
128 #define ERROR_MP_OS_TOO_OLD 100 | 122 #define ERROR_MP_OS_TOO_OLD 100 |
129 #define ERROR_MP_EXTSHM_ACTIVE 101 | 123 #define ERROR_MP_EXTSHM_ACTIVE 101 |
130 #define ERROR_MP_VMGETINFO_FAILED 102 | 124 #define ERROR_MP_VMGETINFO_FAILED 102 |
131 #define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103 | 125 #define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103 |
132 | 126 |
133 // the semantics in this file are thus that codeptr_t is a *real code ptr* | 127 // The semantics in this file are thus that codeptr_t is a *real code ptr*. |
134 // This means that any function taking codeptr_t as arguments will assume | 128 // This means that any function taking codeptr_t as arguments will assume |
135 // a real codeptr and won't handle function descriptors (eg getFuncName), | 129 // a real codeptr and won't handle function descriptors (eg getFuncName), |
136 // whereas functions taking address as args will deal with function | 130 // whereas functions taking address as args will deal with function |
137 // descriptors (eg os::dll_address_to_library_name) | 131 // descriptors (eg os::dll_address_to_library_name). |
138 typedef unsigned int* codeptr_t; | 132 typedef unsigned int* codeptr_t; |
139 | 133 |
140 // typedefs for stackslots, stack pointers, pointers to op codes | 134 // Typedefs for stackslots, stack pointers, pointers to op codes. |
141 typedef unsigned long stackslot_t; | 135 typedef unsigned long stackslot_t; |
142 typedef stackslot_t* stackptr_t; | 136 typedef stackslot_t* stackptr_t; |
137 | |
138 // Excerpts from systemcfg.h definitions newer than AIX 5.3. | |
139 #ifndef PV_7 | |
140 #define PV_7 0x200000 /* Power PC 7 */ | |
141 #define PV_7_Compat 0x208000 /* Power PC 7 */ | |
142 #endif | |
143 #ifndef PV_8 | |
144 #define PV_8 0x300000 /* Power PC 8 */ | |
145 #define PV_8_Compat 0x308000 /* Power PC 8 */ | |
146 #endif | |
147 | |
148 #define trcVerbose(fmt, ...) { /* PPC port */ \ | |
149 if (Verbose) { \ | |
150 fprintf(stderr, fmt, ##__VA_ARGS__); \ | |
151 fputc('\n', stderr); fflush(stderr); \ | |
152 } \ | |
153 } | |
154 #define trc(fmt, ...) /* PPC port */ | |
155 | |
156 #define ERRBYE(s) { \ | |
157 trcVerbose(s); \ | |
158 return -1; \ | |
159 } | |
143 | 160 |
144 // query dimensions of the stack of the calling thread | 161 // query dimensions of the stack of the calling thread |
145 static void query_stack_dimensions(address* p_stack_base, size_t* p_stack_size); | 162 static void query_stack_dimensions(address* p_stack_base, size_t* p_stack_size); |
146 | 163 |
147 // function to check a given stack pointer against given stack limits | 164 // function to check a given stack pointer against given stack limits |
170 return false; | 187 return false; |
171 } | 188 } |
172 return true; | 189 return true; |
173 } | 190 } |
174 | 191 |
175 // macro to check a given stack pointer against given stack limits and to die if test fails | 192 // Macro to check a given stack pointer against given stack limits and to die if test fails. |
176 #define CHECK_STACK_PTR(sp, stack_base, stack_size) { \ | 193 #define CHECK_STACK_PTR(sp, stack_base, stack_size) { \ |
177 guarantee(is_valid_stackpointer((stackptr_t)(sp), (stackptr_t)(stack_base), stack_size), "Stack Pointer Invalid"); \ | 194 guarantee(is_valid_stackpointer((stackptr_t)(sp), (stackptr_t)(stack_base), stack_size), "Stack Pointer Invalid"); \ |
178 } | 195 } |
179 | 196 |
180 // macro to check the current stack pointer against given stacklimits | 197 // Macro to check the current stack pointer against given stacklimits. |
181 #define CHECK_CURRENT_STACK_PTR(stack_base, stack_size) { \ | 198 #define CHECK_CURRENT_STACK_PTR(stack_base, stack_size) { \ |
182 address sp; \ | 199 address sp; \ |
183 sp = os::current_stack_pointer(); \ | 200 sp = os::current_stack_pointer(); \ |
184 CHECK_STACK_PTR(sp, stack_base, stack_size); \ | 201 CHECK_STACK_PTR(sp, stack_base, stack_size); \ |
185 } | 202 } |
209 static sigset_t check_signal_done; // For diagnostics to print a message once (see run_periodic_checks) | 226 static sigset_t check_signal_done; // For diagnostics to print a message once (see run_periodic_checks) |
210 static bool check_signals = true; | 227 static bool check_signals = true; |
211 static pid_t _initial_pid = 0; | 228 static pid_t _initial_pid = 0; |
212 static int SR_signum = SIGUSR2; // Signal used to suspend/resume a thread (must be > SIGSEGV, see 4355769) | 229 static int SR_signum = SIGUSR2; // Signal used to suspend/resume a thread (must be > SIGSEGV, see 4355769) |
213 static sigset_t SR_sigset; | 230 static sigset_t SR_sigset; |
214 static pthread_mutex_t dl_mutex; // Used to protect dlsym() calls */ | 231 static pthread_mutex_t dl_mutex; // Used to protect dlsym() calls. |
215 | 232 |
216 julong os::available_memory() { | 233 julong os::available_memory() { |
217 return Aix::available_memory(); | 234 return Aix::available_memory(); |
218 } | 235 } |
219 | 236 |
241 } | 258 } |
242 if (len > 0) buf[0] = 0; // return a null string | 259 if (len > 0) buf[0] = 0; // return a null string |
243 return false; | 260 return false; |
244 } | 261 } |
245 | 262 |
246 | |
247 // Return true if user is running as root. | 263 // Return true if user is running as root. |
248 | 264 |
249 bool os::have_special_privileges() { | 265 bool os::have_special_privileges() { |
250 static bool init = false; | 266 static bool init = false; |
251 static bool privileges = false; | 267 static bool privileges = false; |
272 | 288 |
273 char* p = addr; | 289 char* p = addr; |
274 | 290 |
275 for (int i = 0; i < numFullDisclaimsNeeded; i ++) { | 291 for (int i = 0; i < numFullDisclaimsNeeded; i ++) { |
276 if (::disclaim(p, maxDisclaimSize, DISCLAIM_ZEROMEM) != 0) { | 292 if (::disclaim(p, maxDisclaimSize, DISCLAIM_ZEROMEM) != 0) { |
277 //if (Verbose) | 293 trc("Cannot disclaim %p - %p (errno %d)\n", p, p + maxDisclaimSize, errno); |
278 fprintf(stderr, "Cannot disclaim %p - %p (errno %d)\n", p, p + maxDisclaimSize, errno); | |
279 return false; | 294 return false; |
280 } | 295 } |
281 p += maxDisclaimSize; | 296 p += maxDisclaimSize; |
282 } | 297 } |
283 | 298 |
284 if (lastDisclaimSize > 0) { | 299 if (lastDisclaimSize > 0) { |
285 if (::disclaim(p, lastDisclaimSize, DISCLAIM_ZEROMEM) != 0) { | 300 if (::disclaim(p, lastDisclaimSize, DISCLAIM_ZEROMEM) != 0) { |
286 //if (Verbose) | 301 trc("Cannot disclaim %p - %p (errno %d)\n", p, p + lastDisclaimSize, errno); |
287 fprintf(stderr, "Cannot disclaim %p - %p (errno %d)\n", p, p + lastDisclaimSize, errno); | |
288 return false; | 302 return false; |
289 } | 303 } |
290 } | 304 } |
291 | 305 |
292 return true; | 306 return true; |
322 return (pid_t) thread_self(); | 336 return (pid_t) thread_self(); |
323 } | 337 } |
324 | 338 |
325 void os::Aix::initialize_system_info() { | 339 void os::Aix::initialize_system_info() { |
326 | 340 |
327 // get the number of online(logical) cpus instead of configured | 341 // Get the number of online(logical) cpus instead of configured. |
328 os::_processor_count = sysconf(_SC_NPROCESSORS_ONLN); | 342 os::_processor_count = sysconf(_SC_NPROCESSORS_ONLN); |
329 assert(_processor_count > 0, "_processor_count must be > 0"); | 343 assert(_processor_count > 0, "_processor_count must be > 0"); |
330 | 344 |
331 // retrieve total physical storage | 345 // Retrieve total physical storage. |
332 os::Aix::meminfo_t mi; | 346 os::Aix::meminfo_t mi; |
333 if (!os::Aix::get_meminfo(&mi)) { | 347 if (!os::Aix::get_meminfo(&mi)) { |
334 fprintf(stderr, "os::Aix::get_meminfo failed.\n"); fflush(stderr); | 348 fprintf(stderr, "os::Aix::get_meminfo failed.\n"); fflush(stderr); |
335 assert(false, "os::Aix::get_meminfo failed."); | 349 assert(false, "os::Aix::get_meminfo failed."); |
336 } | 350 } |
501 fprintf(stderr, "Multipage error details: %d\n", g_multipage_error); | 515 fprintf(stderr, "Multipage error details: %d\n", g_multipage_error); |
502 } | 516 } |
503 | 517 |
504 } // end os::Aix::query_multipage_support() | 518 } // end os::Aix::query_multipage_support() |
505 | 519 |
506 // The code for this method was initially derived from the version in os_linux.cpp. | |
507 void os::init_system_properties_values() { | 520 void os::init_system_properties_values() { |
508 | 521 |
509 #define DEFAULT_LIBPATH "/usr/lib:/lib" | 522 #define DEFAULT_LIBPATH "/usr/lib:/lib" |
510 #define EXTENSIONS_DIR "/lib/ext" | 523 #define EXTENSIONS_DIR "/lib/ext" |
511 #define ENDORSED_DIR "/lib/endorsed" | 524 #define ENDORSED_DIR "/lib/endorsed" |
598 bool os::Aix::is_sig_ignored(int sig) { | 611 bool os::Aix::is_sig_ignored(int sig) { |
599 struct sigaction oact; | 612 struct sigaction oact; |
600 sigaction(sig, (struct sigaction*)NULL, &oact); | 613 sigaction(sig, (struct sigaction*)NULL, &oact); |
601 void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction) | 614 void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction) |
602 : CAST_FROM_FN_PTR(void*, oact.sa_handler); | 615 : CAST_FROM_FN_PTR(void*, oact.sa_handler); |
603 if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN)) | 616 if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN)) { |
604 return true; | 617 return true; |
605 else | 618 } else { |
606 return false; | 619 return false; |
620 } | |
607 } | 621 } |
608 | 622 |
609 void os::Aix::signal_sets_init() { | 623 void os::Aix::signal_sets_init() { |
610 // Should also have an assertion stating we are still single-threaded. | 624 // Should also have an assertion stating we are still single-threaded. |
611 assert(!signal_sets_initialized, "Already initialized"); | 625 assert(!signal_sets_initialized, "Already initialized"); |
775 pci->loadavg[i] = (double) psct.loadavg[i] / (1 << SBITS); | 789 pci->loadavg[i] = (double) psct.loadavg[i] / (1 << SBITS); |
776 } | 790 } |
777 | 791 |
778 // get the processor version from _system_configuration | 792 // get the processor version from _system_configuration |
779 switch (_system_configuration.version) { | 793 switch (_system_configuration.version) { |
794 case PV_8: | |
795 strcpy(pci->version, "Power PC 8"); | |
796 break; | |
780 case PV_7: | 797 case PV_7: |
781 strcpy(pci->version, "Power PC 7"); | 798 strcpy(pci->version, "Power PC 7"); |
782 break; | 799 break; |
783 case PV_6_1: | 800 case PV_6_1: |
784 strcpy(pci->version, "Power PC 6 DD1.x"); | 801 strcpy(pci->version, "Power PC 6 DD1.x"); |
802 strcpy(pci->version, "PV_6_Compat"); | 819 strcpy(pci->version, "PV_6_Compat"); |
803 break; | 820 break; |
804 case PV_7_Compat: | 821 case PV_7_Compat: |
805 strcpy(pci->version, "PV_7_Compat"); | 822 strcpy(pci->version, "PV_7_Compat"); |
806 break; | 823 break; |
824 case PV_8_Compat: | |
825 strcpy(pci->version, "PV_8_Compat"); | |
826 break; | |
807 default: | 827 default: |
808 strcpy(pci->version, "unknown"); | 828 strcpy(pci->version, "unknown"); |
809 } | 829 } |
810 | 830 |
811 return true; | 831 return true; |
937 pthread_t tid; | 957 pthread_t tid; |
938 int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread); | 958 int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread); |
939 | 959 |
940 pthread_attr_destroy(&attr); | 960 pthread_attr_destroy(&attr); |
941 | 961 |
942 if (ret != 0) { | 962 if (ret == 0) { |
963 // PPC port traceOsMisc(("Created New Thread : pthread-id %u", tid)); | |
964 } else { | |
943 if (PrintMiscellaneous && (Verbose || WizardMode)) { | 965 if (PrintMiscellaneous && (Verbose || WizardMode)) { |
944 perror("pthread_create()"); | 966 perror("pthread_create()"); |
945 } | 967 } |
946 // Need to clean up stuff we've allocated so far | 968 // Need to clean up stuff we've allocated so far |
947 thread->set_osthread(NULL); | 969 thread->set_osthread(NULL); |
1094 | 1116 |
1095 jlong os::javaTimeNanos() { | 1117 jlong os::javaTimeNanos() { |
1096 if (os::Aix::on_pase()) { | 1118 if (os::Aix::on_pase()) { |
1097 Unimplemented(); | 1119 Unimplemented(); |
1098 return 0; | 1120 return 0; |
1099 } | 1121 } else { |
1100 else { | |
1101 // On AIX use the precision of processors real time clock | 1122 // On AIX use the precision of processors real time clock |
1102 // or time base registers. | 1123 // or time base registers. |
1103 timebasestruct_t time; | 1124 timebasestruct_t time; |
1104 int rc; | 1125 int rc; |
1105 | 1126 |
1148 | 1169 |
1149 return true; | 1170 return true; |
1150 } | 1171 } |
1151 } | 1172 } |
1152 | 1173 |
1153 | |
1154 char * os::local_time_string(char *buf, size_t buflen) { | 1174 char * os::local_time_string(char *buf, size_t buflen) { |
1155 struct tm t; | 1175 struct tm t; |
1156 time_t long_time; | 1176 time_t long_time; |
1157 time(&long_time); | 1177 time(&long_time); |
1158 localtime_r(&long_time, &t); | 1178 localtime_r(&long_time, &t); |
1186 // Check for abort hook | 1206 // Check for abort hook |
1187 abort_hook_t abort_hook = Arguments::abort_hook(); | 1207 abort_hook_t abort_hook = Arguments::abort_hook(); |
1188 if (abort_hook != NULL) { | 1208 if (abort_hook != NULL) { |
1189 abort_hook(); | 1209 abort_hook(); |
1190 } | 1210 } |
1191 | |
1192 } | 1211 } |
1193 | 1212 |
1194 // Note: os::abort() might be called very early during initialization, or | 1213 // Note: os::abort() might be called very early during initialization, or |
1195 // called from signal handler. Before adding something to os::abort(), make | 1214 // called from signal handler. Before adding something to os::abort(), make |
1196 // sure it is async-safe and can handle partially initialized VM. | 1215 // sure it is async-safe and can handle partially initialized VM. |
1218 | 1237 |
1219 // This method is a copy of JDK's sysGetLastErrorString | 1238 // This method is a copy of JDK's sysGetLastErrorString |
1220 // from src/solaris/hpi/src/system_md.c | 1239 // from src/solaris/hpi/src/system_md.c |
1221 | 1240 |
1222 size_t os::lasterror(char *buf, size_t len) { | 1241 size_t os::lasterror(char *buf, size_t len) { |
1223 | 1242 if (errno == 0) return 0; |
1224 if (errno == 0) return 0; | |
1225 | 1243 |
1226 const char *s = ::strerror(errno); | 1244 const char *s = ::strerror(errno); |
1227 size_t n = ::strlen(s); | 1245 size_t n = ::strlen(s); |
1228 if (n >= len) { | 1246 if (n >= len) { |
1229 n = len - 1; | 1247 n = len - 1; |
1232 buf[n] = '\0'; | 1250 buf[n] = '\0'; |
1233 return n; | 1251 return n; |
1234 } | 1252 } |
1235 | 1253 |
1236 intx os::current_thread_id() { return (intx)pthread_self(); } | 1254 intx os::current_thread_id() { return (intx)pthread_self(); } |
1255 | |
1237 int os::current_process_id() { | 1256 int os::current_process_id() { |
1238 | 1257 |
1239 // This implementation returns a unique pid, the pid of the | 1258 // This implementation returns a unique pid, the pid of the |
1240 // launcher thread that starts the vm 'process'. | 1259 // launcher thread that starts the vm 'process'. |
1241 | 1260 |
1368 bool os::dll_address_to_function_name(address addr, char *buf, | 1387 bool os::dll_address_to_function_name(address addr, char *buf, |
1369 int buflen, int *offset) { | 1388 int buflen, int *offset) { |
1370 if (offset) { | 1389 if (offset) { |
1371 *offset = -1; | 1390 *offset = -1; |
1372 } | 1391 } |
1373 if (buf) { | 1392 // Buf is not optional, but offset is optional. |
1374 buf[0] = '\0'; | 1393 assert(buf != NULL, "sanity check"); |
1375 } | 1394 buf[0] = '\0'; |
1376 | 1395 |
1377 // Resolve function ptr literals first. | 1396 // Resolve function ptr literals first. |
1378 addr = resolve_function_descriptor_to_code_pointer(addr); | 1397 addr = resolve_function_descriptor_to_code_pointer(addr); |
1379 if (!addr) { | 1398 if (!addr) { |
1380 return false; | 1399 return false; |
1403 sprintf(p_name, "%.*s", namelen, lib->get_shortname()); | 1422 sprintf(p_name, "%.*s", namelen, lib->get_shortname()); |
1404 } | 1423 } |
1405 return 0; | 1424 return 0; |
1406 } | 1425 } |
1407 | 1426 |
1408 if (Verbose) { | 1427 trcVerbose("pc outside any module"); |
1409 fprintf(stderr, "pc outside any module"); | |
1410 } | |
1411 | 1428 |
1412 return -1; | 1429 return -1; |
1413 | |
1414 } | 1430 } |
1415 | 1431 |
1416 bool os::dll_address_to_library_name(address addr, char* buf, | 1432 bool os::dll_address_to_library_name(address addr, char* buf, |
1417 int buflen, int* offset) { | 1433 int buflen, int* offset) { |
1418 if (offset) { | 1434 if (offset) { |
1419 *offset = -1; | 1435 *offset = -1; |
1420 } | 1436 } |
1421 if (buf) { | 1437 // Buf is not optional, but offset is optional. |
1422 buf[0] = '\0'; | 1438 assert(buf != NULL, "sanity check"); |
1423 } | 1439 buf[0] = '\0'; |
1424 | 1440 |
1425 // Resolve function ptr literals first. | 1441 // Resolve function ptr literals first. |
1426 addr = resolve_function_descriptor_to_code_pointer(addr); | 1442 addr = resolve_function_descriptor_to_code_pointer(addr); |
1427 if (!addr) { | 1443 if (!addr) { |
1428 return false; | 1444 return false; |
1433 } | 1449 } |
1434 return false; | 1450 return false; |
1435 } | 1451 } |
1436 | 1452 |
1437 // Loads .dll/.so and in case of error it checks if .dll/.so was built | 1453 // Loads .dll/.so and in case of error it checks if .dll/.so was built |
1438 // for the same architecture as Hotspot is running on | 1454 // for the same architecture as Hotspot is running on. |
1439 void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { | 1455 void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { |
1440 | 1456 |
1441 if (ebuf && ebuflen > 0) { | 1457 if (ebuf && ebuflen > 0) { |
1442 ebuf[0] = '\0'; | 1458 ebuf[0] = '\0'; |
1443 ebuf[ebuflen - 1] = '\0'; | 1459 ebuf[ebuflen - 1] = '\0'; |
1596 // Use common posix version. | 1612 // Use common posix version. |
1597 os::Posix::print_siginfo_brief(st, (const siginfo_t*) siginfo); | 1613 os::Posix::print_siginfo_brief(st, (const siginfo_t*) siginfo); |
1598 st->cr(); | 1614 st->cr(); |
1599 } | 1615 } |
1600 | 1616 |
1601 | |
1602 static void print_signal_handler(outputStream* st, int sig, | 1617 static void print_signal_handler(outputStream* st, int sig, |
1603 char* buf, size_t buflen); | 1618 char* buf, size_t buflen); |
1604 | 1619 |
1605 void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) { | 1620 void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) { |
1606 st->print_cr("Signal Handlers:"); | 1621 st->print_cr("Signal Handlers:"); |
1620 print_signal_handler(st, SIGDANGER, buf, buflen); | 1635 print_signal_handler(st, SIGDANGER, buf, buflen); |
1621 } | 1636 } |
1622 | 1637 |
1623 static char saved_jvm_path[MAXPATHLEN] = {0}; | 1638 static char saved_jvm_path[MAXPATHLEN] = {0}; |
1624 | 1639 |
1625 // Find the full path to the current module, libjvm.so or libjvm_g.so | 1640 // Find the full path to the current module, libjvm.so. |
1626 void os::jvm_path(char *buf, jint buflen) { | 1641 void os::jvm_path(char *buf, jint buflen) { |
1627 // Error checking. | 1642 // Error checking. |
1628 if (buflen < MAXPATHLEN) { | 1643 if (buflen < MAXPATHLEN) { |
1629 assert(false, "must use a large-enough buffer"); | 1644 assert(false, "must use a large-enough buffer"); |
1630 buf[0] = '\0'; | 1645 buf[0] = '\0'; |
1690 sigfillset(&(sigAct.sa_mask)); | 1705 sigfillset(&(sigAct.sa_mask)); |
1691 | 1706 |
1692 // Do not block out synchronous signals in the signal handler. | 1707 // Do not block out synchronous signals in the signal handler. |
1693 // Blocking synchronous signals only makes sense if you can really | 1708 // Blocking synchronous signals only makes sense if you can really |
1694 // be sure that those signals won't happen during signal handling, | 1709 // be sure that those signals won't happen during signal handling, |
1695 // when the blocking applies. Normal signal handlers are lean and | 1710 // when the blocking applies. Normal signal handlers are lean and |
1696 // do not cause signals. But our signal handlers tend to be "risky" | 1711 // do not cause signals. But our signal handlers tend to be "risky" |
1697 // - secondary SIGSEGV, SIGILL, SIGBUS' may and do happen. | 1712 // - secondary SIGSEGV, SIGILL, SIGBUS' may and do happen. |
1698 // On AIX, PASE there was a case where a SIGSEGV happened, followed | 1713 // On AIX, PASE there was a case where a SIGSEGV happened, followed |
1699 // by a SIGILL, which was blocked due to the signal mask. The process | 1714 // by a SIGILL, which was blocked due to the signal mask. The process |
1700 // just hung forever. Better to crash from a secondary signal than to hang. | 1715 // just hung forever. Better to crash from a secondary signal than to hang. |
2965 int policy = SCHED_OTHER; | 2980 int policy = SCHED_OTHER; |
2966 struct sched_param param; | 2981 struct sched_param param; |
2967 param.sched_priority = newpri; | 2982 param.sched_priority = newpri; |
2968 int ret = pthread_setschedparam(thr, policy, ¶m); | 2983 int ret = pthread_setschedparam(thr, policy, ¶m); |
2969 | 2984 |
2970 if (Verbose) { | 2985 if (ret != 0) { |
2971 if (ret == 0) { | 2986 trcVerbose("Could not change priority for thread %d to %d (error %d, %s)", |
2972 fprintf(stderr, "changed priority of thread %d to %d\n", (int)thr, newpri); | 2987 (int)thr, newpri, ret, strerror(ret)); |
2973 } else { | |
2974 fprintf(stderr, "Could not changed priority for thread %d to %d (error %d, %s)\n", | |
2975 (int)thr, newpri, ret, strerror(ret)); | |
2976 } | |
2977 } | 2988 } |
2978 return (ret == 0) ? OS_OK : OS_ERR; | 2989 return (ret == 0) ? OS_OK : OS_ERR; |
2979 } | 2990 } |
2980 | 2991 |
2981 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) { | 2992 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) { |
3091 ShouldNotReachHere(); | 3102 ShouldNotReachHere(); |
3092 } | 3103 } |
3093 | 3104 |
3094 errno = old_errno; | 3105 errno = old_errno; |
3095 } | 3106 } |
3096 | |
3097 | 3107 |
3098 static int SR_initialize() { | 3108 static int SR_initialize() { |
3099 struct sigaction act; | 3109 struct sigaction act; |
3100 char *s; | 3110 char *s; |
3101 // Get signal number to use for suspend/resume | 3111 // Get signal number to use for suspend/resume |
3335 unblock_program_error_signals(); | 3345 unblock_program_error_signals(); |
3336 | 3346 |
3337 JVM_handle_aix_signal(sig, info, uc, true); | 3347 JVM_handle_aix_signal(sig, info, uc, true); |
3338 } | 3348 } |
3339 | 3349 |
3340 | |
3341 // This boolean allows users to forward their own non-matching signals | 3350 // This boolean allows users to forward their own non-matching signals |
3342 // to JVM_handle_aix_signal, harmlessly. | 3351 // to JVM_handle_aix_signal, harmlessly. |
3343 bool os::Aix::signal_handlers_are_installed = false; | 3352 bool os::Aix::signal_handlers_are_installed = false; |
3344 | 3353 |
3345 // For signal-chaining | 3354 // For signal-chaining |
3529 set_signal_handler(SIGTRAP, true); | 3538 set_signal_handler(SIGTRAP, true); |
3530 set_signal_handler(SIGXFSZ, true); | 3539 set_signal_handler(SIGXFSZ, true); |
3531 set_signal_handler(SIGDANGER, true); | 3540 set_signal_handler(SIGDANGER, true); |
3532 | 3541 |
3533 if (libjsig_is_loaded) { | 3542 if (libjsig_is_loaded) { |
3534 // Tell libjsig jvm finishes setting signal handlers | 3543 // Tell libjsig jvm finishes setting signal handlers. |
3535 (*end_signal_setting)(); | 3544 (*end_signal_setting)(); |
3536 } | 3545 } |
3537 | 3546 |
3538 // We don't activate signal checker if libjsig is in place, we trust ourselves | 3547 // We don't activate signal checker if libjsig is in place, we trust ourselves |
3539 // and if UserSignalHandler is installed all bets are off. | 3548 // and if UserSignalHandler is installed all bets are off. |
3545 } | 3554 } |
3546 if (AllowUserSignalHandlers) { | 3555 if (AllowUserSignalHandlers) { |
3547 tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled"); | 3556 tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled"); |
3548 check_signals = false; | 3557 check_signals = false; |
3549 } | 3558 } |
3550 // need to initialize check_signal_done | 3559 // Need to initialize check_signal_done. |
3551 ::sigemptyset(&check_signal_done); | 3560 ::sigemptyset(&check_signal_done); |
3552 } | 3561 } |
3553 } | 3562 } |
3554 } | 3563 } |
3555 | 3564 |
3619 } | 3628 } |
3620 } | 3629 } |
3621 st->cr(); | 3630 st->cr(); |
3622 } | 3631 } |
3623 | 3632 |
3624 | |
3625 #define DO_SIGNAL_CHECK(sig) \ | 3633 #define DO_SIGNAL_CHECK(sig) \ |
3626 if (!sigismember(&check_signal_done, sig)) \ | 3634 if (!sigismember(&check_signal_done, sig)) \ |
3627 os::Aix::check_signal_handler(sig) | 3635 os::Aix::check_signal_handler(sig) |
3628 | 3636 |
3629 // This method is a periodic task to check for misbehaving JNI applications | 3637 // This method is a periodic task to check for misbehaving JNI applications |
3680 | 3688 |
3681 address thisHandler = (act.sa_flags & SA_SIGINFO) | 3689 address thisHandler = (act.sa_flags & SA_SIGINFO) |
3682 ? CAST_FROM_FN_PTR(address, act.sa_sigaction) | 3690 ? CAST_FROM_FN_PTR(address, act.sa_sigaction) |
3683 : CAST_FROM_FN_PTR(address, act.sa_handler); | 3691 : CAST_FROM_FN_PTR(address, act.sa_handler); |
3684 | 3692 |
3685 | |
3686 switch(sig) { | 3693 switch(sig) { |
3687 case SIGSEGV: | 3694 case SIGSEGV: |
3688 case SIGBUS: | 3695 case SIGBUS: |
3689 case SIGFPE: | 3696 case SIGFPE: |
3690 case SIGPIPE: | 3697 case SIGPIPE: |
3828 | 3835 |
3829 initial_time_count = os::elapsed_counter(); | 3836 initial_time_count = os::elapsed_counter(); |
3830 pthread_mutex_init(&dl_mutex, NULL); | 3837 pthread_mutex_init(&dl_mutex, NULL); |
3831 } | 3838 } |
3832 | 3839 |
3833 // this is called _after_ the global arguments have been parsed | 3840 // This is called _after_ the global arguments have been parsed. |
3834 jint os::init_2(void) { | 3841 jint os::init_2(void) { |
3835 | 3842 |
3836 if (Verbose) { | 3843 trcVerbose("processor count: %d", os::_processor_count); |
3837 fprintf(stderr, "processor count: %d\n", os::_processor_count); | 3844 trcVerbose("physical memory: %lu", Aix::_physical_memory); |
3838 fprintf(stderr, "physical memory: %lu\n", Aix::_physical_memory); | 3845 |
3839 } | 3846 // Initially build up the loaded dll map. |
3840 | |
3841 // initially build up the loaded dll map | |
3842 LoadedLibraries::reload(); | 3847 LoadedLibraries::reload(); |
3843 | 3848 |
3844 const int page_size = Aix::page_size(); | 3849 const int page_size = Aix::page_size(); |
3845 const int map_size = page_size; | 3850 const int map_size = page_size; |
3846 | 3851 |
3886 // map succeeded and map_address is at wished address, exit loop. | 3891 // map succeeded and map_address is at wished address, exit loop. |
3887 break; | 3892 break; |
3888 } | 3893 } |
3889 | 3894 |
3890 if (map_address != (address) MAP_FAILED) { | 3895 if (map_address != (address) MAP_FAILED) { |
3891 // map succeeded, but polling_page is not at wished address, unmap and continue. | 3896 // Map succeeded, but polling_page is not at wished address, unmap and continue. |
3892 ::munmap(map_address, map_size); | 3897 ::munmap(map_address, map_size); |
3893 map_address = (address) MAP_FAILED; | 3898 map_address = (address) MAP_FAILED; |
3894 } | 3899 } |
3895 // map failed, continue loop. | 3900 // map failed, continue loop. |
3896 } | 3901 } |
3940 return JNI_ERR; | 3945 return JNI_ERR; |
3941 } | 3946 } |
3942 | 3947 |
3943 // Make the stack size a multiple of the page size so that | 3948 // Make the stack size a multiple of the page size so that |
3944 // the yellow/red zones can be guarded. | 3949 // the yellow/red zones can be guarded. |
3945 // note that this can be 0, if no default stacksize was set | 3950 // Note that this can be 0, if no default stacksize was set. |
3946 JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, vm_page_size())); | 3951 JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, vm_page_size())); |
3947 | 3952 |
3948 Aix::libpthread_init(); | 3953 Aix::libpthread_init(); |
3949 | 3954 |
3950 if (MaxFDLimit) { | 3955 if (MaxFDLimit) { |
4253 ::unlink(path); | 4258 ::unlink(path); |
4254 } | 4259 } |
4255 return fd; | 4260 return fd; |
4256 } | 4261 } |
4257 | 4262 |
4258 | |
4259 // create binary file, rewriting existing file if required | 4263 // create binary file, rewriting existing file if required |
4260 int os::create_binary_file(const char* path, bool rewrite_existing) { | 4264 int os::create_binary_file(const char* path, bool rewrite_existing) { |
4261 int oflags = O_WRONLY | O_CREAT; | 4265 int oflags = O_WRONLY | O_CREAT; |
4262 if (!rewrite_existing) { | 4266 if (!rewrite_existing) { |
4263 oflags |= O_EXCL; | 4267 oflags |= O_EXCL; |
4322 bool allow_exec) { | 4326 bool allow_exec) { |
4323 Unimplemented(); | 4327 Unimplemented(); |
4324 return NULL; | 4328 return NULL; |
4325 } | 4329 } |
4326 | 4330 |
4327 | |
4328 // Remap a block of memory. | 4331 // Remap a block of memory. |
4329 char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset, | 4332 char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset, |
4330 char *addr, size_t bytes, bool read_only, | 4333 char *addr, size_t bytes, bool read_only, |
4331 bool allow_exec) { | 4334 bool allow_exec) { |
4332 // same as map_memory() on this OS | 4335 // same as map_memory() on this OS |
4370 bool error = false; | 4373 bool error = false; |
4371 | 4374 |
4372 jlong sys_time = 0; | 4375 jlong sys_time = 0; |
4373 jlong user_time = 0; | 4376 jlong user_time = 0; |
4374 | 4377 |
4375 // reimplemented using getthrds64(). | 4378 // Reimplemented using getthrds64(). |
4376 // | 4379 // |
4377 // goes like this: | 4380 // Works like this: |
4378 // For the thread in question, get the kernel thread id. Then get the | 4381 // For the thread in question, get the kernel thread id. Then get the |
4379 // kernel thread statistics using that id. | 4382 // kernel thread statistics using that id. |
4380 // | 4383 // |
4381 // This only works of course when no pthread scheduling is used, | 4384 // This only works of course when no pthread scheduling is used, |
4382 // ie there is a 1:1 relationship to kernel threads. | 4385 // i.e. there is a 1:1 relationship to kernel threads. |
4383 // On AIX, see AIXTHREAD_SCOPE variable. | 4386 // On AIX, see AIXTHREAD_SCOPE variable. |
4384 | 4387 |
4385 pthread_t pthtid = thread->osthread()->pthread_id(); | 4388 pthread_t pthtid = thread->osthread()->pthread_id(); |
4386 | 4389 |
4387 // retrieve kernel thread id for the pthread: | 4390 // retrieve kernel thread id for the pthread: |
4524 | 4527 |
4525 struct utsname uts; | 4528 struct utsname uts; |
4526 memset(&uts, 0, sizeof(uts)); | 4529 memset(&uts, 0, sizeof(uts)); |
4527 strcpy(uts.sysname, "?"); | 4530 strcpy(uts.sysname, "?"); |
4528 if (::uname(&uts) == -1) { | 4531 if (::uname(&uts) == -1) { |
4529 fprintf(stderr, "uname failed (%d)\n", errno); | 4532 trc("uname failed (%d)", errno); |
4530 guarantee(0, "Could not determine whether we run on AIX or PASE"); | 4533 guarantee(0, "Could not determine whether we run on AIX or PASE"); |
4531 } else { | 4534 } else { |
4532 if (Verbose) { | 4535 trcVerbose("uname says: sysname \"%s\" version \"%s\" release \"%s\" " |
4533 fprintf(stderr,"uname says: sysname \"%s\" version \"%s\" release \"%s\" " | 4536 "node \"%s\" machine \"%s\"\n", |
4534 "node \"%s\" machine \"%s\"\n", | 4537 uts.sysname, uts.version, uts.release, uts.nodename, uts.machine); |
4535 uts.sysname, uts.version, uts.release, uts.nodename, uts.machine); | |
4536 } | |
4537 const int major = atoi(uts.version); | 4538 const int major = atoi(uts.version); |
4538 assert(major > 0, "invalid OS version"); | 4539 assert(major > 0, "invalid OS version"); |
4539 const int minor = atoi(uts.release); | 4540 const int minor = atoi(uts.release); |
4540 assert(minor > 0, "invalid OS release"); | 4541 assert(minor > 0, "invalid OS release"); |
4541 _os_version = (major << 8) | minor; | 4542 _os_version = (major << 8) | minor; |
4543 Unimplemented(); | 4544 Unimplemented(); |
4544 } else if (strcmp(uts.sysname, "AIX") == 0) { | 4545 } else if (strcmp(uts.sysname, "AIX") == 0) { |
4545 // We run on AIX. We do not support versions older than AIX 5.3. | 4546 // We run on AIX. We do not support versions older than AIX 5.3. |
4546 _on_pase = 0; | 4547 _on_pase = 0; |
4547 if (_os_version < 0x0503) { | 4548 if (_os_version < 0x0503) { |
4548 fprintf(stderr, "AIX release older than AIX 5.3 not supported.\n"); | 4549 trc("AIX release older than AIX 5.3 not supported."); |
4549 assert(false, "AIX release too old."); | 4550 assert(false, "AIX release too old."); |
4550 } else { | 4551 } else { |
4551 if (Verbose) { | 4552 trcVerbose("We run on AIX %d.%d\n", major, minor); |
4552 fprintf(stderr, "We run on AIX %d.%d\n", major, minor); | |
4553 } | |
4554 } | 4553 } |
4555 } else { | 4554 } else { |
4556 assert(false, "unknown OS"); | 4555 assert(false, "unknown OS"); |
4557 } | 4556 } |
4558 } | 4557 } |
4559 | 4558 |
4560 guarantee(_on_pase != -1 && _os_version, "Could not determine AIX/OS400 release"); | 4559 guarantee(_on_pase != -1 && _os_version, "Could not determine AIX/OS400 release"); |
4561 | |
4562 } // end: os::Aix::initialize_os_info() | 4560 } // end: os::Aix::initialize_os_info() |
4563 | 4561 |
4564 // Scan environment for important settings which might effect the VM. | 4562 // Scan environment for important settings which might effect the VM. |
4565 // Trace out settings. Warn about invalid settings and/or correct them. | 4563 // Trace out settings. Warn about invalid settings and/or correct them. |
4566 // | 4564 // |
4594 // get useful return codes for mprotect. | 4592 // get useful return codes for mprotect. |
4595 // | 4593 // |
4596 // Note: Setting XPG_SUS_ENV in the process is too late. Must be set earlier (before | 4594 // Note: Setting XPG_SUS_ENV in the process is too late. Must be set earlier (before |
4597 // exec() ? before loading the libjvm ? ....) | 4595 // exec() ? before loading the libjvm ? ....) |
4598 p = ::getenv("XPG_SUS_ENV"); | 4596 p = ::getenv("XPG_SUS_ENV"); |
4599 if (Verbose) { | 4597 trcVerbose("XPG_SUS_ENV=%s.", p ? p : "<unset>"); |
4600 fprintf(stderr, "XPG_SUS_ENV=%s.\n", p ? p : "<unset>"); | |
4601 } | |
4602 if (p && strcmp(p, "ON") == 0) { | 4598 if (p && strcmp(p, "ON") == 0) { |
4603 _xpg_sus_mode = 1; | 4599 _xpg_sus_mode = 1; |
4604 fprintf(stderr, "Unsupported setting: XPG_SUS_ENV=ON\n"); | 4600 trc("Unsupported setting: XPG_SUS_ENV=ON"); |
4605 // This is not supported. Worst of all, it changes behaviour of mmap MAP_FIXED to | 4601 // This is not supported. Worst of all, it changes behaviour of mmap MAP_FIXED to |
4606 // clobber address ranges. If we ever want to support that, we have to do some | 4602 // clobber address ranges. If we ever want to support that, we have to do some |
4607 // testing first. | 4603 // testing first. |
4608 guarantee(false, "XPG_SUS_ENV=ON not supported"); | 4604 guarantee(false, "XPG_SUS_ENV=ON not supported"); |
4609 } else { | 4605 } else { |
4611 } | 4607 } |
4612 | 4608 |
4613 // Switch off AIX internal (pthread) guard pages. This has | 4609 // Switch off AIX internal (pthread) guard pages. This has |
4614 // immediate effect for any pthread_create calls which follow. | 4610 // immediate effect for any pthread_create calls which follow. |
4615 p = ::getenv("AIXTHREAD_GUARDPAGES"); | 4611 p = ::getenv("AIXTHREAD_GUARDPAGES"); |
4616 if (Verbose) { | 4612 trcVerbose("AIXTHREAD_GUARDPAGES=%s.", p ? p : "<unset>"); |
4617 fprintf(stderr, "AIXTHREAD_GUARDPAGES=%s.\n", p ? p : "<unset>"); | |
4618 fprintf(stderr, "setting AIXTHREAD_GUARDPAGES=0.\n"); | |
4619 } | |
4620 rc = ::putenv("AIXTHREAD_GUARDPAGES=0"); | 4613 rc = ::putenv("AIXTHREAD_GUARDPAGES=0"); |
4621 guarantee(rc == 0, ""); | 4614 guarantee(rc == 0, ""); |
4622 | 4615 |
4623 } // end: os::Aix::scan_environment() | 4616 } // end: os::Aix::scan_environment() |
4624 | 4617 |
4632 void os::Aix::initialize_libperfstat() { | 4625 void os::Aix::initialize_libperfstat() { |
4633 | 4626 |
4634 assert(os::Aix::on_aix(), "AIX only"); | 4627 assert(os::Aix::on_aix(), "AIX only"); |
4635 | 4628 |
4636 if (!libperfstat::init()) { | 4629 if (!libperfstat::init()) { |
4637 fprintf(stderr, "libperfstat initialization failed.\n"); | 4630 trc("libperfstat initialization failed."); |
4638 assert(false, "libperfstat initialization failed"); | 4631 assert(false, "libperfstat initialization failed"); |
4639 } else { | 4632 } else { |
4640 if (Verbose) { | 4633 if (Verbose) { |
4641 fprintf(stderr, "libperfstat initialized.\n"); | 4634 fprintf(stderr, "libperfstat initialized.\n"); |
4642 } | 4635 } |
4804 } | 4797 } |
4805 abstime->tv_nsec = usec * 1000; | 4798 abstime->tv_nsec = usec * 1000; |
4806 return abstime; | 4799 return abstime; |
4807 } | 4800 } |
4808 | 4801 |
4809 | |
4810 // Test-and-clear _Event, always leaves _Event set to 0, returns immediately. | 4802 // Test-and-clear _Event, always leaves _Event set to 0, returns immediately. |
4811 // Conceptually TryPark() should be equivalent to park(0). | 4803 // Conceptually TryPark() should be equivalent to park(0). |
4812 | 4804 |
4813 int os::PlatformEvent::TryPark() { | 4805 int os::PlatformEvent::TryPark() { |
4814 for (;;) { | 4806 for (;;) { |
4887 // In that case, we should propagate the notify to another waiter. | 4879 // In that case, we should propagate the notify to another waiter. |
4888 | 4880 |
4889 while (_Event < 0) { | 4881 while (_Event < 0) { |
4890 status = pthread_cond_timedwait(_cond, _mutex, &abst); | 4882 status = pthread_cond_timedwait(_cond, _mutex, &abst); |
4891 assert_status(status == 0 || status == ETIMEDOUT, | 4883 assert_status(status == 0 || status == ETIMEDOUT, |
4892 status, "cond_timedwait"); | 4884 status, "cond_timedwait"); |
4893 if (!FilterSpuriousWakeups) break; // previous semantics | 4885 if (!FilterSpuriousWakeups) break; // previous semantics |
4894 if (status == ETIMEDOUT) break; | 4886 if (status == ETIMEDOUT) break; |
4895 // We consume and ignore EINTR and spurious wakeups. | 4887 // We consume and ignore EINTR and spurious wakeups. |
4896 } | 4888 } |
4897 --_nParked; | 4889 --_nParked; |
5021 | 5013 |
5022 void Parker::park(bool isAbsolute, jlong time) { | 5014 void Parker::park(bool isAbsolute, jlong time) { |
5023 // Optional fast-path check: | 5015 // Optional fast-path check: |
5024 // Return immediately if a permit is available. | 5016 // Return immediately if a permit is available. |
5025 if (_counter > 0) { | 5017 if (_counter > 0) { |
5026 _counter = 0; | 5018 _counter = 0; |
5027 OrderAccess::fence(); | 5019 OrderAccess::fence(); |
5028 return; | 5020 return; |
5029 } | 5021 } |
5030 | 5022 |
5031 Thread* thread = Thread::current(); | 5023 Thread* thread = Thread::current(); |
5032 assert(thread->is_Java_thread(), "Must be JavaThread"); | 5024 assert(thread->is_Java_thread(), "Must be JavaThread"); |
5033 JavaThread *jt = (JavaThread *)thread; | 5025 JavaThread *jt = (JavaThread *)thread; |
5044 return; | 5036 return; |
5045 } | 5037 } |
5046 if (time > 0) { | 5038 if (time > 0) { |
5047 unpackTime(&absTime, isAbsolute, time); | 5039 unpackTime(&absTime, isAbsolute, time); |
5048 } | 5040 } |
5049 | |
5050 | 5041 |
5051 // Enter safepoint region | 5042 // Enter safepoint region |
5052 // Beware of deadlocks such as 6317397. | 5043 // Beware of deadlocks such as 6317397. |
5053 // The per-thread Parker:: mutex is a classic leaf-lock. | 5044 // The per-thread Parker:: mutex is a classic leaf-lock. |
5054 // In particular a thread must never block on the Threads_lock while | 5045 // In particular a thread must never block on the Threads_lock while |
5133 pthread_mutex_unlock(_mutex); | 5124 pthread_mutex_unlock(_mutex); |
5134 assert (status == 0, "invariant"); | 5125 assert (status == 0, "invariant"); |
5135 } | 5126 } |
5136 } | 5127 } |
5137 | 5128 |
5138 | |
5139 extern char** environ; | 5129 extern char** environ; |
5140 | 5130 |
5141 // Run the specified command in a separate process. Return its exit value, | 5131 // Run the specified command in a separate process. Return its exit value, |
5142 // or -1 on failure (e.g. can't fork a new process). | 5132 // or -1 on failure (e.g. can't fork a new process). |
5143 // Unlike system(), this function can be called from signal handler. It | 5133 // Unlike system(), this function can be called from signal handler. It |
5152 return -1; | 5142 return -1; |
5153 | 5143 |
5154 } else if (pid == 0) { | 5144 } else if (pid == 0) { |
5155 // child process | 5145 // child process |
5156 | 5146 |
5157 // try to be consistent with system(), which uses "/usr/bin/sh" on AIX | 5147 // Try to be consistent with system(), which uses "/usr/bin/sh" on AIX. |
5158 execve("/usr/bin/sh", argv, environ); | 5148 execve("/usr/bin/sh", argv, environ); |
5159 | 5149 |
5160 // execve failed | 5150 // execve failed |
5161 _exit(-1); | 5151 _exit(-1); |
5162 | 5152 |
5163 } else { | 5153 } else { |
5164 // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't | 5154 // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't |
5165 // care about the actual exit code, for now. | 5155 // care about the actual exit code, for now. |
5166 | 5156 |
5167 int status; | 5157 int status; |
5168 | 5158 |
5169 // Wait for the child process to exit. This returns immediately if | 5159 // Wait for the child process to exit. This returns immediately if |
5170 // the child has already exited. */ | 5160 // the child has already exited. */ |
5171 while (waitpid(pid, &status, 0) < 0) { | 5161 while (waitpid(pid, &status, 0) < 0) { |
5172 switch (errno) { | 5162 switch (errno) { |
5173 case ECHILD: return 0; | 5163 case ECHILD: return 0; |
5174 case EINTR: break; | 5164 case EINTR: break; |
5175 default: return -1; | 5165 default: return -1; |
5176 } | 5166 } |
5177 } | 5167 } |
5178 | 5168 |
5179 if (WIFEXITED(status)) { | 5169 if (WIFEXITED(status)) { |
5180 // The child exited normally; get its exit code. | 5170 // The child exited normally; get its exit code. |
5181 return WEXITSTATUS(status); | 5171 return WEXITSTATUS(status); |
5182 } else if (WIFSIGNALED(status)) { | 5172 } else if (WIFSIGNALED(status)) { |
5183 // The child exited because of a signal | 5173 // The child exited because of a signal. |
5184 // The best value to return is 0x80 + signal number, | 5174 // The best value to return is 0x80 + signal number, |
5185 // because that is what all Unix shells do, and because | 5175 // because that is what all Unix shells do, and because |
5186 // it allows callers to distinguish between process exit and | 5176 // it allows callers to distinguish between process exit and |
5187 // process death by signal. | 5177 // process death by signal. |
5188 return 0x80 + WTERMSIG(status); | 5178 return 0x80 + WTERMSIG(status); |
5189 } else { | 5179 } else { |
5190 // Unknown exit code; pass it through | 5180 // Unknown exit code; pass it through. |
5191 return status; | 5181 return status; |
5192 } | 5182 } |
5193 } | 5183 } |
5194 // Remove warning. | |
5195 return -1; | 5184 return -1; |
5196 } | 5185 } |
5197 | 5186 |
5198 // is_headless_jre() | 5187 // is_headless_jre() |
5199 // | 5188 // |
5204 // as libawt.so, and renamed libawt_xawt.so | 5193 // as libawt.so, and renamed libawt_xawt.so |
5205 bool os::is_headless_jre() { | 5194 bool os::is_headless_jre() { |
5206 struct stat statbuf; | 5195 struct stat statbuf; |
5207 char buf[MAXPATHLEN]; | 5196 char buf[MAXPATHLEN]; |
5208 char libmawtpath[MAXPATHLEN]; | 5197 char libmawtpath[MAXPATHLEN]; |
5209 const char *xawtstr = "/xawt/libmawt.so"; | 5198 const char *xawtstr = "/xawt/libmawt.so"; |
5210 const char *new_xawtstr = "/libawt_xawt.so"; | 5199 const char *new_xawtstr = "/libawt_xawt.so"; |
5211 | 5200 |
5212 char *p; | 5201 char *p; |
5213 | 5202 |
5214 // Get path to libjvm.so | 5203 // Get path to libjvm.so |