< 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


 124 #else
 125 int (*os::Bsd::_clock_gettime)(clockid_t, struct timespec *) = NULL;
 126 #endif
 127 pthread_t os::Bsd::_main_thread;
 128 int os::Bsd::_page_size = -1;
 129 
 130 static jlong initial_time_count=0;
 131 
 132 static int clock_tics_per_sec = 100;
 133 
 134 // For diagnostics to print a message once. see run_periodic_checks
 135 static sigset_t check_signal_done;
 136 static bool check_signals = true;
 137 
 138 // Signal number used to suspend/resume a thread
 139 
 140 // do not use any signal number less than SIGSEGV, see 4355769
 141 static int SR_signum = SIGUSR2;
 142 sigset_t SR_sigset;
 143 







 144 
 145 ////////////////////////////////////////////////////////////////////////////////
 146 // utility functions
 147 
 148 static int SR_initialize();
 149 
 150 julong os::available_memory() {
 151   return Bsd::available_memory();
 152 }
 153 
 154 // available here means free
 155 julong os::Bsd::available_memory() {
 156   uint64_t available = physical_memory() >> 2;
 157 #ifdef __APPLE__
 158   mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
 159   vm_statistics64_data_t vmstat;
 160   kern_return_t kerr = host_statistics64(mach_host_self(), HOST_VM_INFO64,
 161                                          (host_info64_t)&vmstat, &count);
 162   assert(kerr == KERN_SUCCESS,
 163          "host_statistics64 failed - check mach_host_self() and count");


 233 #endif
 234 
 235 
 236 void os::Bsd::initialize_system_info() {
 237   int mib[2];
 238   size_t len;
 239   int cpu_val;
 240   julong mem_val;
 241 
 242   // get processors count via hw.ncpus sysctl
 243   mib[0] = CTL_HW;
 244   mib[1] = HW_NCPU;
 245   len = sizeof(cpu_val);
 246   if (sysctl(mib, 2, &cpu_val, &len, NULL, 0) != -1 && cpu_val >= 1) {
 247     assert(len == sizeof(cpu_val), "unexpected data size");
 248     set_processor_count(cpu_val);
 249   } else {
 250     set_processor_count(1);   // fallback
 251   }
 252 







 253   // get physical memory via hw.memsize sysctl (hw.memsize is used
 254   // since it returns a 64 bit value)
 255   mib[0] = CTL_HW;
 256 
 257 #if defined (HW_MEMSIZE) // Apple
 258   mib[1] = HW_MEMSIZE;
 259 #elif defined(HW_PHYSMEM) // Most of BSD
 260   mib[1] = HW_PHYSMEM;
 261 #elif defined(HW_REALMEM) // Old FreeBSD
 262   mib[1] = HW_REALMEM;
 263 #else
 264   #error No ways to get physmem
 265 #endif
 266 
 267   len = sizeof(mem_val);
 268   if (sysctl(mib, 2, &mem_val, &len, NULL, 0) != -1) {
 269     assert(len == sizeof(mem_val), "unexpected data size");
 270     _physical_memory = mem_val;
 271   } else {
 272     _physical_memory = 256 * 1024 * 1024;       // fallback (XXXBSD?)


3205 // Mark the polling page as readable
3206 void os::make_polling_page_readable(void) {
3207   if (!bsd_mprotect((char *)_polling_page, Bsd::page_size(), PROT_READ)) {
3208     fatal("Could not enable polling page");
3209   }
3210 }
3211 
3212 int os::active_processor_count() {
3213   // User has overridden the number of active processors
3214   if (ActiveProcessorCount > 0) {
3215     log_trace(os)("active_processor_count: "
3216                   "active processor count set by user : %d",
3217                   ActiveProcessorCount);
3218     return ActiveProcessorCount;
3219   }
3220 
3221   return _processor_count;
3222 }
3223 
3224 #ifdef __APPLE__
3225 static volatile int* volatile apic_to_processor_mapping = NULL;
3226 static volatile int next_processor_id = 0;
3227 
3228 static inline volatile int* get_apic_to_processor_mapping() {
3229   volatile int* mapping = Atomic::load_acquire(&apic_to_processor_mapping);
3230   if (mapping == NULL) {
3231     // Calculate possible number space for APIC ids. This space is not necessarily
3232     // in the range [0, number_of_processors).
3233     uint total_bits = 0;
3234     for (uint i = 0;; ++i) {
3235       uint eax = 0xb; // Query topology leaf
3236       uint ebx;
3237       uint ecx = i;
3238       uint edx;
3239 
3240       __asm__ ("cpuid\n\t" : "+a" (eax), "+b" (ebx), "+c" (ecx), "+d" (edx) : );
3241 
3242       uint level_type = (ecx >> 8) & 0xFF;
3243       if (level_type == 0) {
3244         // Invalid level; end of topology
3245         break;
3246       }
3247       uint level_apic_id_shift = eax & ((1u << 5) - 1);
3248       total_bits += level_apic_id_shift;
3249     }
3250 
3251     uint max_apic_ids = 1u << total_bits;
3252     mapping = NEW_C_HEAP_ARRAY(int, max_apic_ids, mtInternal);
3253 
3254     for (uint i = 0; i < max_apic_ids; ++i) {
3255       mapping[i] = -1;
3256     }
3257 
3258     if (!Atomic::replace_if_null(&apic_to_processor_mapping, mapping)) {
3259       FREE_C_HEAP_ARRAY(int, mapping);
3260       mapping = Atomic::load_acquire(&apic_to_processor_mapping);
3261     }
3262   }
3263 
3264   return mapping;
3265 }
3266 
3267 uint os::processor_id() {
3268   volatile int* mapping = get_apic_to_processor_mapping();
3269 
3270   uint eax = 0xb;






3271   uint ebx;
3272   uint ecx = 0;
3273   uint edx;
3274 
3275   __asm__ ("cpuid\n\t" : "+a" (eax), "+b" (ebx), "+c" (ecx), "+d" (edx) : );
3276 
3277   // Map from APIC id to a unique logical processor ID in the expected
3278   // [0, num_processors) range.
3279 
3280   uint apic_id = edx;
3281   int processor_id = Atomic::load(&mapping[apic_id]);
3282 
3283   while (processor_id < 0) {
3284     if (Atomic::cmpxchg(&mapping[apic_id], -1, -2) == -1) {
3285       Atomic::store(&mapping[apic_id], Atomic::add(&next_processor_id, 1) - 1);



3286     }
3287     processor_id = Atomic::load(&mapping[apic_id]);
3288   }
3289 
3290   assert(processor_id >= 0 && processor_id < os::processor_count(), "invalid processor id");
3291 
3292   return (uint)processor_id;
3293 }
3294 #endif
3295 
3296 void os::set_native_thread_name(const char *name) {
3297 #if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5
3298   // This is only supported in Snow Leopard and beyond
3299   if (name != NULL) {
3300     // Add a "Java: " prefix to the name
3301     char buf[MAXTHREADNAMESIZE];
3302     snprintf(buf, sizeof(buf), "Java: %s", name);
3303     pthread_setname_np(buf);
3304   }
3305 #endif
3306 }
3307 




 124 #else
 125 int (*os::Bsd::_clock_gettime)(clockid_t, struct timespec *) = NULL;
 126 #endif
 127 pthread_t os::Bsd::_main_thread;
 128 int os::Bsd::_page_size = -1;
 129 
 130 static jlong initial_time_count=0;
 131 
 132 static int clock_tics_per_sec = 100;
 133 
 134 // For diagnostics to print a message once. see run_periodic_checks
 135 static sigset_t check_signal_done;
 136 static bool check_signals = true;
 137 
 138 // Signal number used to suspend/resume a thread
 139 
 140 // do not use any signal number less than SIGSEGV, see 4355769
 141 static int SR_signum = SIGUSR2;
 142 sigset_t SR_sigset;
 143 
 144 #ifdef __APPLE__
 145 static const int processor_id_unassigned = -1;
 146 static const int processor_id_assigning = -2;
 147 static const int processor_id_map_size = 256;
 148 static volatile int processor_id_map[processor_id_map_size];
 149 static volatile int processor_id_next = 0;
 150 #endif
 151 
 152 ////////////////////////////////////////////////////////////////////////////////
 153 // utility functions
 154 
 155 static int SR_initialize();
 156 
 157 julong os::available_memory() {
 158   return Bsd::available_memory();
 159 }
 160 
 161 // available here means free
 162 julong os::Bsd::available_memory() {
 163   uint64_t available = physical_memory() >> 2;
 164 #ifdef __APPLE__
 165   mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
 166   vm_statistics64_data_t vmstat;
 167   kern_return_t kerr = host_statistics64(mach_host_self(), HOST_VM_INFO64,
 168                                          (host_info64_t)&vmstat, &count);
 169   assert(kerr == KERN_SUCCESS,
 170          "host_statistics64 failed - check mach_host_self() and count");


 240 #endif
 241 
 242 
 243 void os::Bsd::initialize_system_info() {
 244   int mib[2];
 245   size_t len;
 246   int cpu_val;
 247   julong mem_val;
 248 
 249   // get processors count via hw.ncpus sysctl
 250   mib[0] = CTL_HW;
 251   mib[1] = HW_NCPU;
 252   len = sizeof(cpu_val);
 253   if (sysctl(mib, 2, &cpu_val, &len, NULL, 0) != -1 && cpu_val >= 1) {
 254     assert(len == sizeof(cpu_val), "unexpected data size");
 255     set_processor_count(cpu_val);
 256   } else {
 257     set_processor_count(1);   // fallback
 258   }
 259 
 260 #ifdef __APPLE__
 261   // initialize processor id map
 262   for (int i = 0; i < processor_id_map_size; i++) {
 263     processor_id_map[i] = processor_id_unassigned;
 264   }
 265 #endif
 266 
 267   // get physical memory via hw.memsize sysctl (hw.memsize is used
 268   // since it returns a 64 bit value)
 269   mib[0] = CTL_HW;
 270 
 271 #if defined (HW_MEMSIZE) // Apple
 272   mib[1] = HW_MEMSIZE;
 273 #elif defined(HW_PHYSMEM) // Most of BSD
 274   mib[1] = HW_PHYSMEM;
 275 #elif defined(HW_REALMEM) // Old FreeBSD
 276   mib[1] = HW_REALMEM;
 277 #else
 278   #error No ways to get physmem
 279 #endif
 280 
 281   len = sizeof(mem_val);
 282   if (sysctl(mib, 2, &mem_val, &len, NULL, 0) != -1) {
 283     assert(len == sizeof(mem_val), "unexpected data size");
 284     _physical_memory = mem_val;
 285   } else {
 286     _physical_memory = 256 * 1024 * 1024;       // fallback (XXXBSD?)


3219 // Mark the polling page as readable
3220 void os::make_polling_page_readable(void) {
3221   if (!bsd_mprotect((char *)_polling_page, Bsd::page_size(), PROT_READ)) {
3222     fatal("Could not enable polling page");
3223   }
3224 }
3225 
3226 int os::active_processor_count() {
3227   // User has overridden the number of active processors
3228   if (ActiveProcessorCount > 0) {
3229     log_trace(os)("active_processor_count: "
3230                   "active processor count set by user : %d",
3231                   ActiveProcessorCount);
3232     return ActiveProcessorCount;
3233   }
3234 
3235   return _processor_count;
3236 }
3237 
3238 #ifdef __APPLE__










































3239 uint os::processor_id() {
3240   // Get the initial APIC id and return the associated processor id. The initial APIC
3241   // id is limited to 8-bits, which means we can have at most 256 unique APIC ids. If
3242   // the system has more processors (or the initial APIC ids are discontiguous) the
3243   // APIC id will be truncated and more than one processor will potentially share the
3244   // same processor id. This is not optimal, but unlikely to happen in practice. Should
3245   // this become a real problem we could switch to using x2APIC ids, which are 32-bit
3246   // wide. However, note that x2APIC is Intel-specific, and the wider number space
3247   // would require a more complicated mapping approach.
3248   uint eax = 0x1;
3249   uint ebx;
3250   uint ecx = 0;
3251   uint edx;
3252 
3253   __asm__ ("cpuid\n\t" : "+a" (eax), "+b" (ebx), "+c" (ecx), "+d" (edx) : );
3254 
3255   uint apic_id = (ebx >> 24) & (processor_id_map_size - 1);
3256   int processor_id = Atomic::load(&processor_id_map[apic_id]);



3257 
3258   while (processor_id < 0) {
3259     // Assign processor id to APIC id
3260     processor_id = Atomic::cmpxchg(&processor_id_map[apic_id], processor_id_unassigned, processor_id_assigning);
3261     if (processor_id == processor_id_unassigned) {
3262       processor_id = (Atomic::add(&processor_id_next, 1) - 1) % os::processor_count();
3263       Atomic::store(&processor_id_map[apic_id], processor_id);
3264     }

3265   }
3266 
3267   assert(processor_id >= 0 && processor_id < os::processor_count(), "invalid processor id");
3268 
3269   return (uint)processor_id;
3270 }
3271 #endif
3272 
3273 void os::set_native_thread_name(const char *name) {
3274 #if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5
3275   // This is only supported in Snow Leopard and beyond
3276   if (name != NULL) {
3277     // Add a "Java: " prefix to the name
3278     char buf[MAXTHREADNAMESIZE];
3279     snprintf(buf, sizeof(buf), "Java: %s", name);
3280     pthread_setname_np(buf);
3281   }
3282 #endif
3283 }
3284 


< prev index next >