OpenJDK / amber / amber
changeset 56536:fdddd05767ce
8224816: Provide os::processor_id() implementation for Mac OS
Reviewed-by: rehn, pliden, kbarrett, gziemski
author | eosterlund |
---|---|
date | Mon, 03 Jun 2019 13:35:08 +0200 |
parents | 47d928ba8733 |
children | 4ffd6a955e92 |
files | src/hotspot/os/bsd/os_bsd.cpp |
diffstat | 1 files changed, 64 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/hotspot/os/bsd/os_bsd.cpp Mon Jun 03 13:35:05 2019 +0200 +++ b/src/hotspot/os/bsd/os_bsd.cpp Mon Jun 03 13:35:08 2019 +0200 @@ -3263,6 +3263,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