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
|