--- a/src/hotspot/os/bsd/os_bsd.cpp Thu Oct 17 20:27:44 2019 +0100
+++ b/src/hotspot/os/bsd/os_bsd.cpp Thu Oct 17 20:53:35 2019 +0100
@@ -136,8 +136,6 @@
static sigset_t check_signal_done;
static bool check_signals = true;
-static pid_t _initial_pid = 0;
-
// Signal number used to suspend/resume a thread
// do not use any signal number less than SIGSEGV, see 4355769
@@ -337,7 +335,7 @@
const size_t bufsize =
MAX2((size_t)MAXPATHLEN, // For dll_dir & friends.
(size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + sizeof(SYS_EXT_DIR) + sizeof(EXTENSIONS_DIR)); // extensions dir
- char *buf = (char *)NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
+ char *buf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
// sysclasspath, java_home, dll_dir
{
@@ -387,10 +385,10 @@
const char *v_colon = ":";
if (v == NULL) { v = ""; v_colon = ""; }
// That's +1 for the colon and +1 for the trailing '\0'.
- char *ld_library_path = (char *)NEW_C_HEAP_ARRAY(char,
- strlen(v) + 1 +
- sizeof(SYS_EXT_DIR) + sizeof("/lib/") + strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH) + 1,
- mtInternal);
+ char *ld_library_path = NEW_C_HEAP_ARRAY(char,
+ strlen(v) + 1 +
+ sizeof(SYS_EXT_DIR) + sizeof("/lib/") + strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH) + 1,
+ mtInternal);
sprintf(ld_library_path, "%s%s" SYS_EXT_DIR "/lib/%s:" DEFAULT_LIBPATH, v, v_colon, cpu_arch);
Arguments::set_library_path(ld_library_path);
FREE_C_HEAP_ARRAY(char, ld_library_path);
@@ -418,7 +416,7 @@
const size_t bufsize =
MAX2((size_t)MAXPATHLEN, // for dll_dir & friends.
(size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + system_ext_size); // extensions dir
- char *buf = (char *)NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
+ char *buf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
// sysclasspath, java_home, dll_dir
{
@@ -480,10 +478,10 @@
// could cause a change in behavior, but Apple's Java6 behavior
// can be achieved by putting "." at the beginning of the
// JAVA_LIBRARY_PATH environment variable.
- char *ld_library_path = (char *)NEW_C_HEAP_ARRAY(char,
- strlen(v) + 1 + strlen(l) + 1 +
- system_ext_size + 3,
- mtInternal);
+ char *ld_library_path = NEW_C_HEAP_ARRAY(char,
+ strlen(v) + 1 + strlen(l) + 1 +
+ system_ext_size + 3,
+ mtInternal);
sprintf(ld_library_path, "%s%s%s%s%s" SYS_EXTENSIONS_DIR ":" SYS_EXTENSIONS_DIRS ":.",
v, v_colon, l, l_colon, user_home_dir);
Arguments::set_library_path(ld_library_path);
@@ -879,8 +877,6 @@
}
bool os::supports_vtime() { return true; }
-bool os::enable_vtime() { return false; }
-bool os::vtime_enabled() { return false; }
double os::elapsedVTime() {
// better than nothing, but not much
@@ -1073,9 +1069,16 @@
}
// Die immediately, no exit hook, no abort hook, no cleanup.
+// Dump a core file, if possible, for debugging.
void os::die() {
- // _exit() on BsdThreads only kills current thread
- ::abort();
+ if (TestUnresponsiveErrorHandler && !CreateCoredumpOnCrash) {
+ // For TimeoutInErrorHandlingTest.java, we just kill the VM
+ // and don't take the time to generate a core file.
+ os::signal_raise(SIGKILL);
+ } else {
+ // _exit() on BsdThreads only kills current thread
+ ::abort();
+ }
}
// Information of current thread in variety of formats
@@ -1117,24 +1120,7 @@
}
int os::current_process_id() {
-
- // Under the old bsd thread library, bsd gives each thread
- // its own process id. Because of this each thread will return
- // a different pid if this method were to return the result
- // of getpid(2). Bsd provides no api that returns the pid
- // of the launcher thread for the vm. This implementation
- // returns a unique pid, the pid of the launcher thread
- // that starts the vm 'process'.
-
- // Under the NPTL, getpid() returns the same pid as the
- // launcher thread rather than a unique pid per thread.
- // Use gettid() if you want the old pre NPTL behaviour.
-
- // if you are looking for the result of a call to getpid() that
- // returns a unique pid for the calling thread, then look at the
- // OSThread::thread_id() method in osThread_bsd.hpp file
-
- return (int)(_initial_pid ? _initial_pid : getpid());
+ return (int)(getpid());
}
// DLL functions
@@ -1256,15 +1242,27 @@
#ifdef STATIC_BUILD
return os::get_default_process_handle();
#else
+ log_info(os)("attempting shared library load of %s", filename);
+
void * result= ::dlopen(filename, RTLD_LAZY);
if (result != NULL) {
+ Events::log(NULL, "Loaded shared library %s", filename);
// Successful loading
+ log_info(os)("shared library load of %s was successful", filename);
return result;
}
- // Read system error message into ebuf
- ::strncpy(ebuf, ::dlerror(), ebuflen-1);
- ebuf[ebuflen-1]='\0';
+ const char* error_report = ::dlerror();
+ if (error_report == NULL) {
+ error_report = "dlerror returned no error description";
+ }
+ if (ebuf != NULL && ebuflen > 0) {
+ // Read system error message into ebuf
+ ::strncpy(ebuf, error_report, ebuflen-1);
+ ebuf[ebuflen-1]='\0';
+ }
+ Events::log(NULL, "Loading shared library %s failed, %s", filename, error_report);
+ log_info(os)("shared library load of %s failed, %s", filename, error_report);
return NULL;
#endif // STATIC_BUILD
@@ -1274,18 +1272,29 @@
#ifdef STATIC_BUILD
return os::get_default_process_handle();
#else
+ log_info(os)("attempting shared library load of %s", filename);
void * result= ::dlopen(filename, RTLD_LAZY);
if (result != NULL) {
+ Events::log(NULL, "Loaded shared library %s", filename);
// Successful loading
+ log_info(os)("shared library load of %s was successful", filename);
return result;
}
Elf32_Ehdr elf_head;
- // Read system error message into ebuf
- // It may or may not be overwritten below
- ::strncpy(ebuf, ::dlerror(), ebuflen-1);
- ebuf[ebuflen-1]='\0';
+ const char* const error_report = ::dlerror();
+ if (error_report == NULL) {
+ error_report = "dlerror returned no error description";
+ }
+ if (ebuf != NULL && ebuflen > 0) {
+ // Read system error message into ebuf
+ ::strncpy(ebuf, error_report, ebuflen-1);
+ ebuf[ebuflen-1]='\0';
+ }
+ Events::log(NULL, "Loading shared library %s failed, %s", filename, error_report);
+ log_info(os)("shared library load of %s failed, %s", filename, error_report);
+
int diag_msg_max_length=ebuflen-strlen(ebuf);
char* diag_msg_buf=ebuf+strlen(ebuf);
@@ -1752,16 +1761,7 @@
////////////////////////////////////////////////////////////////////////////////
// sun.misc.Signal support
-static volatile jint sigint_count = 0;
-
static void UserHandler(int sig, void *siginfo, void *context) {
- // 4511530 - sem_post is serialized and handled by the manager thread. When
- // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We
- // don't want to flood the manager thread with sem_post requests.
- if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1) {
- return;
- }
-
// Ctrl-C is pressed during error reporting, likely because the error
// handler fails to abort. Let VM die immediately.
if (sig == SIGINT && VMError::is_error_reported()) {
@@ -1831,7 +1831,6 @@
}
static int check_pending_signals() {
- Atomic::store(0, &sigint_count);
for (;;) {
for (int i = 0; i < NSIG + 1; i++) {
jint n = pending_signals[i];
@@ -2166,11 +2165,6 @@
// available (and not reserved for something else).
char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
- const int max_tries = 10;
- char* base[max_tries];
- size_t size[max_tries];
- const size_t gap = 0x000000;
-
// Assert only that the size is a multiple of the page size, since
// that's all that mmap requires, and since that's all we really know
// about at this low abstraction level. If we need higher alignment,
@@ -2193,50 +2187,7 @@
anon_munmap(addr, bytes);
}
- int i;
- for (i = 0; i < max_tries; ++i) {
- base[i] = reserve_memory(bytes);
-
- if (base[i] != NULL) {
- // Is this the block we wanted?
- if (base[i] == requested_addr) {
- size[i] = bytes;
- break;
- }
-
- // Does this overlap the block we wanted? Give back the overlapped
- // parts and try again.
-
- size_t top_overlap = requested_addr + (bytes + gap) - base[i];
- if (top_overlap >= 0 && top_overlap < bytes) {
- unmap_memory(base[i], top_overlap);
- base[i] += top_overlap;
- size[i] = bytes - top_overlap;
- } else {
- size_t bottom_overlap = base[i] + bytes - requested_addr;
- if (bottom_overlap >= 0 && bottom_overlap < bytes) {
- unmap_memory(requested_addr, bottom_overlap);
- size[i] = bytes - bottom_overlap;
- } else {
- size[i] = bytes;
- }
- }
- }
- }
-
- // Give back the unused reserved pieces.
-
- for (int j = 0; j < i; ++j) {
- if (base[j] != NULL) {
- unmap_memory(base[j], size[j]);
- }
- }
-
- if (i < max_tries) {
- return requested_addr;
- } else {
- return NULL;
- }
+ return NULL;
}
// Sleep forever; naked call to OS-specific sleep; use with CAUTION
@@ -3115,16 +3066,6 @@
void os::init(void) {
char dummy; // used to get a guess on initial stack address
- // With BsdThreads the JavaMain thread pid (primordial thread)
- // is different than the pid of the java launcher thread.
- // So, on Bsd, the launcher thread pid is passed to the VM
- // via the sun.java.launcher.pid property.
- // Use this property instead of getpid() if it was correctly passed.
- // See bug 6351349.
- pid_t java_launcher_pid = (pid_t) Arguments::sun_java_launcher_pid();
-
- _initial_pid = (java_launcher_pid > 0) ? java_launcher_pid : getpid();
-
clock_tics_per_sec = CLK_TCK;
init_random(1234567);
@@ -3263,6 +3204,70 @@
return _processor_count;
}
+#ifdef __APPLE__
+uint os::processor_id() {
+ static volatile int* volatile apic_to_cpu_mapping = NULL;
+ static volatile int next_cpu_id = 0;
+
+ volatile int* mapping = OrderAccess::load_acquire(&apic_to_cpu_mapping);
+ if (mapping == NULL) {
+ // Calculate possible number space for APIC ids. This space is not necessarily
+ // in the range [0, number_of_cpus).
+ uint total_bits = 0;
+ for (uint i = 0;; ++i) {
+ uint eax = 0xb; // Query topology leaf
+ uint ebx;
+ uint ecx = i;
+ uint edx;
+
+ __asm__ ("cpuid\n\t" : "+a" (eax), "+b" (ebx), "+c" (ecx), "+d" (edx) : );
+
+ uint level_type = (ecx >> 8) & 0xFF;
+ if (level_type == 0) {
+ // Invalid level; end of topology
+ break;
+ }
+ uint level_apic_id_shift = eax & ((1u << 5) - 1);
+ total_bits += level_apic_id_shift;
+ }
+
+ uint max_apic_ids = 1u << total_bits;
+ mapping = NEW_C_HEAP_ARRAY(int, max_apic_ids, mtInternal);
+
+ for (uint i = 0; i < max_apic_ids; ++i) {
+ mapping[i] = -1;
+ }
+
+ if (!Atomic::replace_if_null(mapping, &apic_to_cpu_mapping)) {
+ FREE_C_HEAP_ARRAY(int, mapping);
+ mapping = OrderAccess::load_acquire(&apic_to_cpu_mapping);
+ }
+ }
+
+ uint eax = 0xb;
+ uint ebx;
+ uint ecx = 0;
+ uint edx;
+
+ asm ("cpuid\n\t" : "+a" (eax), "+b" (ebx), "+c" (ecx), "+d" (edx) : );
+
+ // Map from APIC id to a unique logical processor ID in the expected
+ // [0, num_processors) range.
+
+ uint apic_id = edx;
+ int cpu_id = Atomic::load(&mapping[apic_id]);
+
+ while (cpu_id < 0) {
+ if (Atomic::cmpxchg(-2, &mapping[apic_id], -1)) {
+ Atomic::store(Atomic::add(1, &next_cpu_id) - 1, &mapping[apic_id]);
+ }
+ cpu_id = Atomic::load(&mapping[apic_id]);
+ }
+
+ return (uint)cpu_id;
+}
+#endif
+
void os::set_native_thread_name(const char *name) {
#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5
// This is only supported in Snow Leopard and beyond
@@ -3275,11 +3280,6 @@
#endif
}
-bool os::distribute_processes(uint length, uint* distribution) {
- // Not yet implemented.
- return false;
-}
-
bool os::bind_to_processor(uint processor_id) {
// Not yet implemented.
return false;
@@ -3664,7 +3664,7 @@
void os::pause() {
char filename[MAX_PATH];
if (PauseAtStartupFile && PauseAtStartupFile[0]) {
- jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
+ jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);
} else {
jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
}
@@ -3767,6 +3767,10 @@
return n;
}
+bool os::supports_map_sync() {
+ return false;
+}
+
#ifndef PRODUCT
void TestReserveMemorySpecial_test() {
// No tests available for this platform