3203 |
3203 |
3204 return _processor_count; |
3204 return _processor_count; |
3205 } |
3205 } |
3206 |
3206 |
3207 #ifdef __APPLE__ |
3207 #ifdef __APPLE__ |
3208 uint os::processor_id() { |
3208 static volatile int* volatile apic_to_processor_mapping = NULL; |
3209 static volatile int* volatile apic_to_cpu_mapping = NULL; |
3209 static volatile int next_processor_id = 0; |
3210 static volatile int next_cpu_id = 0; |
3210 |
3211 |
3211 static inline volatile int* get_apic_to_processor_mapping() { |
3212 volatile int* mapping = OrderAccess::load_acquire(&apic_to_cpu_mapping); |
3212 volatile int* mapping = OrderAccess::load_acquire(&apic_to_processor_mapping); |
3213 if (mapping == NULL) { |
3213 if (mapping == NULL) { |
3214 // Calculate possible number space for APIC ids. This space is not necessarily |
3214 // Calculate possible number space for APIC ids. This space is not necessarily |
3215 // in the range [0, number_of_cpus). |
3215 // in the range [0, number_of_processors). |
3216 uint total_bits = 0; |
3216 uint total_bits = 0; |
3217 for (uint i = 0;; ++i) { |
3217 for (uint i = 0;; ++i) { |
3218 uint eax = 0xb; // Query topology leaf |
3218 uint eax = 0xb; // Query topology leaf |
3219 uint ebx; |
3219 uint ebx; |
3220 uint ecx = i; |
3220 uint ecx = i; |
3236 |
3236 |
3237 for (uint i = 0; i < max_apic_ids; ++i) { |
3237 for (uint i = 0; i < max_apic_ids; ++i) { |
3238 mapping[i] = -1; |
3238 mapping[i] = -1; |
3239 } |
3239 } |
3240 |
3240 |
3241 if (!Atomic::replace_if_null(mapping, &apic_to_cpu_mapping)) { |
3241 if (!Atomic::replace_if_null(mapping, &apic_to_processor_mapping)) { |
3242 FREE_C_HEAP_ARRAY(int, mapping); |
3242 FREE_C_HEAP_ARRAY(int, mapping); |
3243 mapping = OrderAccess::load_acquire(&apic_to_cpu_mapping); |
3243 mapping = OrderAccess::load_acquire(&apic_to_processor_mapping); |
3244 } |
3244 } |
3245 } |
3245 } |
|
3246 |
|
3247 return mapping; |
|
3248 } |
|
3249 |
|
3250 uint os::processor_id() { |
|
3251 volatile int* mapping = get_apic_to_processor_mapping(); |
3246 |
3252 |
3247 uint eax = 0xb; |
3253 uint eax = 0xb; |
3248 uint ebx; |
3254 uint ebx; |
3249 uint ecx = 0; |
3255 uint ecx = 0; |
3250 uint edx; |
3256 uint edx; |
3251 |
3257 |
3252 asm ("cpuid\n\t" : "+a" (eax), "+b" (ebx), "+c" (ecx), "+d" (edx) : ); |
3258 __asm__ ("cpuid\n\t" : "+a" (eax), "+b" (ebx), "+c" (ecx), "+d" (edx) : ); |
3253 |
3259 |
3254 // Map from APIC id to a unique logical processor ID in the expected |
3260 // Map from APIC id to a unique logical processor ID in the expected |
3255 // [0, num_processors) range. |
3261 // [0, num_processors) range. |
3256 |
3262 |
3257 uint apic_id = edx; |
3263 uint apic_id = edx; |
3258 int cpu_id = Atomic::load(&mapping[apic_id]); |
3264 int processor_id = Atomic::load(&mapping[apic_id]); |
3259 |
3265 |
3260 while (cpu_id < 0) { |
3266 while (processor_id < 0) { |
3261 if (Atomic::cmpxchg(-2, &mapping[apic_id], -1)) { |
3267 if (Atomic::cmpxchg(-2, &mapping[apic_id], -1)) { |
3262 Atomic::store(Atomic::add(1, &next_cpu_id) - 1, &mapping[apic_id]); |
3268 Atomic::store(Atomic::add(1, &next_processor_id) - 1, &mapping[apic_id]); |
3263 } |
3269 } |
3264 cpu_id = Atomic::load(&mapping[apic_id]); |
3270 processor_id = Atomic::load(&mapping[apic_id]); |
3265 } |
3271 } |
3266 |
3272 |
3267 return (uint)cpu_id; |
3273 return (uint)processor_id; |
3268 } |
3274 } |
3269 #endif |
3275 #endif |
3270 |
3276 |
3271 void os::set_native_thread_name(const char *name) { |
3277 void os::set_native_thread_name(const char *name) { |
3272 #if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 |
3278 #if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 |