< prev index next >

src/hotspot/os/bsd/os_bsd.cpp

Print this page
rev 57764 : 8241603: ZGC: java/lang/management/MemoryMXBean/MemoryTestZGC.sh crashes on macOS
Reviewed-by: eosterlund, clanger, mbaesken, azeller

*** 139,148 **** --- 139,155 ---- // do not use any signal number less than SIGSEGV, see 4355769 static int SR_signum = SIGUSR2; sigset_t SR_sigset; + #ifdef __APPLE__ + static const int processor_id_unassigned = -1; + static const int processor_id_assigning = -2; + static const int processor_id_map_size = 256; + static volatile int processor_id_map[processor_id_map_size]; + static volatile int processor_id_next = 0; + #endif //////////////////////////////////////////////////////////////////////////////// // utility functions static int SR_initialize();
*** 248,257 **** --- 255,271 ---- set_processor_count(cpu_val); } else { set_processor_count(1); // fallback } + #ifdef __APPLE__ + // initialize processor id map + for (int i = 0; i < processor_id_map_size; i++) { + processor_id_map[i] = processor_id_unassigned; + } + #endif + // get physical memory via hw.memsize sysctl (hw.memsize is used // since it returns a 64 bit value) mib[0] = CTL_HW; #if defined (HW_MEMSIZE) // Apple
*** 3220,3292 **** return _processor_count; } #ifdef __APPLE__ - static volatile int* volatile apic_to_processor_mapping = NULL; - static volatile int next_processor_id = 0; - - static inline volatile int* get_apic_to_processor_mapping() { - volatile int* mapping = Atomic::load_acquire(&apic_to_processor_mapping); - if (mapping == NULL) { - // Calculate possible number space for APIC ids. This space is not necessarily - // in the range [0, number_of_processors). - 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(&apic_to_processor_mapping, mapping)) { - FREE_C_HEAP_ARRAY(int, mapping); - mapping = Atomic::load_acquire(&apic_to_processor_mapping); - } - } - - return mapping; - } - uint os::processor_id() { ! volatile int* mapping = get_apic_to_processor_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 processor_id = Atomic::load(&mapping[apic_id]); while (processor_id < 0) { ! if (Atomic::cmpxchg(&mapping[apic_id], -1, -2) == -1) { ! Atomic::store(&mapping[apic_id], Atomic::add(&next_processor_id, 1) - 1); } - processor_id = Atomic::load(&mapping[apic_id]); } assert(processor_id >= 0 && processor_id < os::processor_count(), "invalid processor id"); return (uint)processor_id; --- 3234,3269 ---- return _processor_count; } #ifdef __APPLE__ uint os::processor_id() { ! // Get the initial APIC id and return the associated processor id. The initial APIC ! // id is limited to 8-bits, which means we can have at most 256 unique APIC ids. If ! // the system has more processors (or the initial APIC ids are discontiguous) the ! // APIC id will be truncated and more than one processor will potentially share the ! // same processor id. This is not optimal, but unlikely to happen in practice. Should ! // this become a real problem we could switch to using x2APIC ids, which are 32-bit ! // wide. However, note that x2APIC is Intel-specific, and the wider number space ! // would require a more complicated mapping approach. ! uint eax = 0x1; uint ebx; uint ecx = 0; uint edx; __asm__ ("cpuid\n\t" : "+a" (eax), "+b" (ebx), "+c" (ecx), "+d" (edx) : ); ! uint apic_id = (ebx >> 24) & (processor_id_map_size - 1); ! int processor_id = Atomic::load(&processor_id_map[apic_id]); while (processor_id < 0) { ! // Assign processor id to APIC id ! processor_id = Atomic::cmpxchg(&processor_id_map[apic_id], processor_id_unassigned, processor_id_assigning); ! if (processor_id == processor_id_unassigned) { ! processor_id = (Atomic::add(&processor_id_next, 1) - 1) % os::processor_count(); ! Atomic::store(&processor_id_map[apic_id], processor_id); } } assert(processor_id >= 0 && processor_id < os::processor_count(), "invalid processor id"); return (uint)processor_id;
< prev index next >