Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 1 | /* |
Jonathan Peyton | de4749b | 2016-12-14 23:01:24 +0000 | [diff] [blame] | 2 | * kmp_utility.cpp -- Utility routines for the OpenMP support library. |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 3 | */ |
| 4 | |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 5 | //===----------------------------------------------------------------------===// |
| 6 | // |
| 7 | // The LLVM Compiler Infrastructure |
| 8 | // |
| 9 | // This file is dual licensed under the MIT and the University of Illinois Open |
| 10 | // Source Licenses. See LICENSE.txt for details. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 14 | #include "kmp.h" |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 15 | #include "kmp_i18n.h" |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 16 | #include "kmp_str.h" |
| 17 | #include "kmp_wrapper_getpid.h" |
| 18 | #include <float.h> |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 19 | |
| 20 | static const char *unknown = "unknown"; |
| 21 | |
| 22 | #if KMP_ARCH_X86 || KMP_ARCH_X86_64 |
| 23 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 24 | /* NOTE: If called before serial_initialize (i.e. from runtime_initialize), then |
| 25 | the debugging package has not been initialized yet, and only "0" will print |
| 26 | debugging output since the environment variables have not been read. */ |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 27 | |
Jonathan Peyton | 2321d57 | 2015-06-08 19:25:25 +0000 | [diff] [blame] | 28 | #ifdef KMP_DEBUG |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 29 | static int trace_level = 5; |
Jonathan Peyton | 2321d57 | 2015-06-08 19:25:25 +0000 | [diff] [blame] | 30 | #endif |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 31 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 32 | /* LOG_ID_BITS = ( 1 + floor( log_2( max( log_per_phy - 1, 1 )))) |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 33 | * APIC_ID = (PHY_ID << LOG_ID_BITS) | LOG_ID |
| 34 | * PHY_ID = APIC_ID >> LOG_ID_BITS |
| 35 | */ |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 36 | int __kmp_get_physical_id(int log_per_phy, int apic_id) { |
| 37 | int index_lsb, index_msb, temp; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 38 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 39 | if (log_per_phy > 1) { |
| 40 | index_lsb = 0; |
| 41 | index_msb = 31; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 42 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 43 | temp = log_per_phy; |
| 44 | while ((temp & 1) == 0) { |
| 45 | temp >>= 1; |
| 46 | index_lsb++; |
| 47 | } |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 48 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 49 | temp = log_per_phy; |
| 50 | while ((temp & 0x80000000) == 0) { |
| 51 | temp <<= 1; |
| 52 | index_msb--; |
| 53 | } |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 54 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 55 | /* If >1 bits were set in log_per_phy, choose next higher power of 2 */ |
| 56 | if (index_lsb != index_msb) |
| 57 | index_msb++; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 58 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 59 | return ((int)(apic_id >> index_msb)); |
| 60 | } |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 61 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 62 | return apic_id; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 63 | } |
| 64 | |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 65 | /* |
| 66 | * LOG_ID_BITS = ( 1 + floor( log_2( max( log_per_phy - 1, 1 )))) |
| 67 | * APIC_ID = (PHY_ID << LOG_ID_BITS) | LOG_ID |
| 68 | * LOG_ID = APIC_ID & (( 1 << LOG_ID_BITS ) - 1 ) |
| 69 | */ |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 70 | int __kmp_get_logical_id(int log_per_phy, int apic_id) { |
| 71 | unsigned current_bit; |
| 72 | int bits_seen; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 73 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 74 | if (log_per_phy <= 1) |
| 75 | return (0); |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 76 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 77 | bits_seen = 0; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 78 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 79 | for (current_bit = 1; log_per_phy != 0; current_bit <<= 1) { |
| 80 | if (log_per_phy & current_bit) { |
| 81 | log_per_phy &= ~current_bit; |
| 82 | bits_seen++; |
| 83 | } |
| 84 | } |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 85 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 86 | /* If exactly 1 bit was set in log_per_phy, choose next lower power of 2 */ |
| 87 | if (bits_seen == 1) { |
| 88 | current_bit >>= 1; |
| 89 | } |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 90 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 91 | return ((int)((current_bit - 1) & apic_id)); |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 92 | } |
| 93 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 94 | static kmp_uint64 __kmp_parse_frequency( // R: Frequency in Hz. |
| 95 | char const *frequency // I: Float number and unit: MHz, GHz, or TGz. |
| 96 | ) { |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 97 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 98 | double value = 0.0; |
Jonas Hahnfeld | e9b7c0a | 2017-11-09 15:52:29 +0000 | [diff] [blame] | 99 | char *unit = NULL; |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 100 | kmp_uint64 result = 0; /* Zero is a better unknown value than all ones. */ |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 101 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 102 | if (frequency == NULL) { |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 103 | return result; |
Jonathan Peyton | bd3a763 | 2017-09-27 20:36:27 +0000 | [diff] [blame] | 104 | } |
Jonas Hahnfeld | e9b7c0a | 2017-11-09 15:52:29 +0000 | [diff] [blame] | 105 | value = strtod(frequency, &unit); |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 106 | if (0 < value && |
| 107 | value <= DBL_MAX) { // Good value (not overflow, underflow, etc). |
| 108 | if (strcmp(unit, "MHz") == 0) { |
| 109 | value = value * 1.0E+6; |
| 110 | } else if (strcmp(unit, "GHz") == 0) { |
| 111 | value = value * 1.0E+9; |
| 112 | } else if (strcmp(unit, "THz") == 0) { |
| 113 | value = value * 1.0E+12; |
| 114 | } else { // Wrong unit. |
| 115 | return result; |
Jonathan Peyton | bd3a763 | 2017-09-27 20:36:27 +0000 | [diff] [blame] | 116 | } |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 117 | result = value; |
Jonathan Peyton | bd3a763 | 2017-09-27 20:36:27 +0000 | [diff] [blame] | 118 | } |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 119 | return result; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 120 | |
Jonathan Peyton | bd3a763 | 2017-09-27 20:36:27 +0000 | [diff] [blame] | 121 | } // func __kmp_parse_cpu_frequency |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 122 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 123 | void __kmp_query_cpuid(kmp_cpuinfo_t *p) { |
| 124 | struct kmp_cpuid buf; |
| 125 | int max_arg; |
| 126 | int log_per_phy; |
Jonathan Peyton | 2321d57 | 2015-06-08 19:25:25 +0000 | [diff] [blame] | 127 | #ifdef KMP_DEBUG |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 128 | int cflush_size; |
Jonathan Peyton | 2321d57 | 2015-06-08 19:25:25 +0000 | [diff] [blame] | 129 | #endif |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 130 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 131 | p->initialized = 1; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 132 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 133 | p->sse2 = 1; // Assume SSE2 by default. |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 134 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 135 | __kmp_x86_cpuid(0, 0, &buf); |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 136 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 137 | KA_TRACE(trace_level, |
| 138 | ("INFO: CPUID %d: EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n", 0, |
| 139 | buf.eax, buf.ebx, buf.ecx, buf.edx)); |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 140 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 141 | max_arg = buf.eax; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 142 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 143 | p->apic_id = -1; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 144 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 145 | if (max_arg >= 1) { |
| 146 | int i; |
| 147 | kmp_uint32 t, data[4]; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 148 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 149 | __kmp_x86_cpuid(1, 0, &buf); |
| 150 | KA_TRACE(trace_level, |
| 151 | ("INFO: CPUID %d: EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n", |
| 152 | 1, buf.eax, buf.ebx, buf.ecx, buf.edx)); |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 153 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 154 | { |
| 155 | #define get_value(reg, lo, mask) (((reg) >> (lo)) & (mask)) |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 156 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 157 | p->signature = buf.eax; |
| 158 | p->family = get_value(buf.eax, 20, 0xff) + get_value(buf.eax, 8, 0x0f); |
| 159 | p->model = |
| 160 | (get_value(buf.eax, 16, 0x0f) << 4) + get_value(buf.eax, 4, 0x0f); |
| 161 | p->stepping = get_value(buf.eax, 0, 0x0f); |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 162 | |
| 163 | #undef get_value |
| 164 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 165 | KA_TRACE(trace_level, (" family = %d, model = %d, stepping = %d\n", |
| 166 | p->family, p->model, p->stepping)); |
| 167 | } |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 168 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 169 | for (t = buf.ebx, i = 0; i < 4; t >>= 8, ++i) { |
| 170 | data[i] = (t & 0xff); |
Jonathan Peyton | bd3a763 | 2017-09-27 20:36:27 +0000 | [diff] [blame] | 171 | } |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 172 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 173 | p->sse2 = (buf.edx >> 26) & 1; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 174 | |
| 175 | #ifdef KMP_DEBUG |
| 176 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 177 | if ((buf.edx >> 4) & 1) { |
| 178 | /* TSC - Timestamp Counter Available */ |
| 179 | KA_TRACE(trace_level, (" TSC")); |
| 180 | } |
| 181 | if ((buf.edx >> 8) & 1) { |
| 182 | /* CX8 - CMPXCHG8B Instruction Available */ |
| 183 | KA_TRACE(trace_level, (" CX8")); |
| 184 | } |
| 185 | if ((buf.edx >> 9) & 1) { |
| 186 | /* APIC - Local APIC Present (multi-processor operation support */ |
| 187 | KA_TRACE(trace_level, (" APIC")); |
| 188 | } |
| 189 | if ((buf.edx >> 15) & 1) { |
| 190 | /* CMOV - Conditional MOVe Instruction Available */ |
| 191 | KA_TRACE(trace_level, (" CMOV")); |
| 192 | } |
| 193 | if ((buf.edx >> 18) & 1) { |
| 194 | /* PSN - Processor Serial Number Available */ |
| 195 | KA_TRACE(trace_level, (" PSN")); |
| 196 | } |
| 197 | if ((buf.edx >> 19) & 1) { |
| 198 | /* CLFULSH - Cache Flush Instruction Available */ |
| 199 | cflush_size = |
| 200 | data[1] * 8; /* Bits 15-08: CLFLUSH line size = 8 (64 bytes) */ |
| 201 | KA_TRACE(trace_level, (" CLFLUSH(%db)", cflush_size)); |
| 202 | } |
| 203 | if ((buf.edx >> 21) & 1) { |
| 204 | /* DTES - Debug Trace & EMON Store */ |
| 205 | KA_TRACE(trace_level, (" DTES")); |
| 206 | } |
| 207 | if ((buf.edx >> 22) & 1) { |
| 208 | /* ACPI - ACPI Support Available */ |
| 209 | KA_TRACE(trace_level, (" ACPI")); |
| 210 | } |
| 211 | if ((buf.edx >> 23) & 1) { |
| 212 | /* MMX - Multimedia Extensions */ |
| 213 | KA_TRACE(trace_level, (" MMX")); |
| 214 | } |
| 215 | if ((buf.edx >> 25) & 1) { |
| 216 | /* SSE - SSE Instructions */ |
| 217 | KA_TRACE(trace_level, (" SSE")); |
| 218 | } |
| 219 | if ((buf.edx >> 26) & 1) { |
| 220 | /* SSE2 - SSE2 Instructions */ |
| 221 | KA_TRACE(trace_level, (" SSE2")); |
| 222 | } |
| 223 | if ((buf.edx >> 27) & 1) { |
| 224 | /* SLFSNP - Self-Snooping Cache */ |
| 225 | KA_TRACE(trace_level, (" SLFSNP")); |
| 226 | } |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 227 | #endif /* KMP_DEBUG */ |
| 228 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 229 | if ((buf.edx >> 28) & 1) { |
| 230 | /* Bits 23-16: Logical Processors per Physical Processor (1 for P4) */ |
| 231 | log_per_phy = data[2]; |
| 232 | p->apic_id = data[3]; /* Bits 31-24: Processor Initial APIC ID (X) */ |
| 233 | KA_TRACE(trace_level, (" HT(%d TPUs)", log_per_phy)); |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 234 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 235 | if (log_per_phy > 1) { |
| 236 | /* default to 1k FOR JT-enabled processors (4k on OS X*) */ |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 237 | #if KMP_OS_DARWIN |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 238 | p->cpu_stackoffset = 4 * 1024; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 239 | #else |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 240 | p->cpu_stackoffset = 1 * 1024; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 241 | #endif |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 242 | } |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 243 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 244 | p->physical_id = __kmp_get_physical_id(log_per_phy, p->apic_id); |
| 245 | p->logical_id = __kmp_get_logical_id(log_per_phy, p->apic_id); |
| 246 | } |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 247 | #ifdef KMP_DEBUG |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 248 | if ((buf.edx >> 29) & 1) { |
| 249 | /* ATHROTL - Automatic Throttle Control */ |
| 250 | KA_TRACE(trace_level, (" ATHROTL")); |
| 251 | } |
| 252 | KA_TRACE(trace_level, (" ]\n")); |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 253 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 254 | for (i = 2; i <= max_arg; ++i) { |
| 255 | __kmp_x86_cpuid(i, 0, &buf); |
| 256 | KA_TRACE(trace_level, |
| 257 | ("INFO: CPUID %d: EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n", |
| 258 | i, buf.eax, buf.ebx, buf.ecx, buf.edx)); |
| 259 | } |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 260 | #endif |
| 261 | #if KMP_USE_ADAPTIVE_LOCKS |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 262 | p->rtm = 0; |
| 263 | if (max_arg > 7) { |
| 264 | /* RTM bit CPUID.07:EBX, bit 11 */ |
| 265 | __kmp_x86_cpuid(7, 0, &buf); |
| 266 | p->rtm = (buf.ebx >> 11) & 1; |
| 267 | KA_TRACE(trace_level, (" RTM")); |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 268 | } |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 269 | #endif |
Jonathan Peyton | bd3a763 | 2017-09-27 20:36:27 +0000 | [diff] [blame] | 270 | } |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 271 | |
| 272 | { // Parse CPU brand string for frequency, saving the string for later. |
| 273 | int i; |
| 274 | kmp_cpuid_t *base = (kmp_cpuid_t *)&p->name[0]; |
| 275 | |
| 276 | // Get CPU brand string. |
| 277 | for (i = 0; i < 3; ++i) { |
| 278 | __kmp_x86_cpuid(0x80000002 + i, 0, base + i); |
Jonathan Peyton | bd3a763 | 2017-09-27 20:36:27 +0000 | [diff] [blame] | 279 | } |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 280 | p->name[sizeof(p->name) - 1] = 0; // Just in case. ;-) |
| 281 | KA_TRACE(trace_level, ("cpu brand string: \"%s\"\n", &p->name[0])); |
| 282 | |
| 283 | // Parse frequency. |
| 284 | p->frequency = __kmp_parse_frequency(strrchr(&p->name[0], ' ')); |
| 285 | KA_TRACE(trace_level, |
| 286 | ("cpu frequency from brand string: %" KMP_UINT64_SPEC "\n", |
| 287 | p->frequency)); |
| 288 | } |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 289 | } |
| 290 | |
| 291 | #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */ |
| 292 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 293 | void __kmp_expand_host_name(char *buffer, size_t size) { |
| 294 | KMP_DEBUG_ASSERT(size >= sizeof(unknown)); |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 295 | #if KMP_OS_WINDOWS |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 296 | { |
| 297 | DWORD s = size; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 298 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 299 | if (!GetComputerNameA(buffer, &s)) |
| 300 | KMP_STRCPY_S(buffer, size, unknown); |
| 301 | } |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 302 | #else |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 303 | buffer[size - 2] = 0; |
| 304 | if (gethostname(buffer, size) || buffer[size - 2] != 0) |
| 305 | KMP_STRCPY_S(buffer, size, unknown); |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 306 | #endif |
| 307 | } |
| 308 | |
| 309 | /* Expand the meta characters in the filename: |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 310 | * Currently defined characters are: |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 311 | * %H the hostname |
| 312 | * %P the number of threads used. |
| 313 | * %I the unique identifier for this run. |
| 314 | */ |
| 315 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 316 | void __kmp_expand_file_name(char *result, size_t rlen, char *pattern) { |
| 317 | char *pos = result, *end = result + rlen - 1; |
| 318 | char buffer[256]; |
| 319 | int default_cpu_width = 1; |
| 320 | int snp_result; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 321 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 322 | KMP_DEBUG_ASSERT(rlen > 0); |
| 323 | *end = 0; |
| 324 | { |
| 325 | int i; |
| 326 | for (i = __kmp_xproc; i >= 10; i /= 10, ++default_cpu_width) |
| 327 | ; |
| 328 | } |
| 329 | |
| 330 | if (pattern != NULL) { |
| 331 | while (*pattern != '\0' && pos < end) { |
| 332 | if (*pattern != '%') { |
| 333 | *pos++ = *pattern++; |
| 334 | } else { |
| 335 | char *old_pattern = pattern; |
| 336 | int width = 1; |
| 337 | int cpu_width = default_cpu_width; |
| 338 | |
| 339 | ++pattern; |
| 340 | |
| 341 | if (*pattern >= '0' && *pattern <= '9') { |
| 342 | width = 0; |
| 343 | do { |
| 344 | width = (width * 10) + *pattern++ - '0'; |
| 345 | } while (*pattern >= '0' && *pattern <= '9'); |
| 346 | if (width < 0 || width > 1024) |
| 347 | width = 1; |
| 348 | |
| 349 | cpu_width = width; |
| 350 | } |
| 351 | |
| 352 | switch (*pattern) { |
| 353 | case 'H': |
| 354 | case 'h': { |
| 355 | __kmp_expand_host_name(buffer, sizeof(buffer)); |
| 356 | KMP_STRNCPY(pos, buffer, end - pos + 1); |
| 357 | if (*end == 0) { |
| 358 | while (*pos) |
| 359 | ++pos; |
| 360 | ++pattern; |
| 361 | } else |
| 362 | pos = end; |
| 363 | } break; |
| 364 | case 'P': |
| 365 | case 'p': { |
| 366 | snp_result = KMP_SNPRINTF(pos, end - pos + 1, "%0*d", cpu_width, |
| 367 | __kmp_dflt_team_nth); |
| 368 | if (snp_result >= 0 && snp_result <= end - pos) { |
| 369 | while (*pos) |
| 370 | ++pos; |
| 371 | ++pattern; |
| 372 | } else |
| 373 | pos = end; |
| 374 | } break; |
| 375 | case 'I': |
| 376 | case 'i': { |
| 377 | pid_t id = getpid(); |
| 378 | snp_result = KMP_SNPRINTF(pos, end - pos + 1, "%0*d", width, id); |
| 379 | if (snp_result >= 0 && snp_result <= end - pos) { |
| 380 | while (*pos) |
| 381 | ++pos; |
| 382 | ++pattern; |
| 383 | } else |
| 384 | pos = end; |
| 385 | break; |
| 386 | } |
| 387 | case '%': { |
| 388 | *pos++ = '%'; |
| 389 | ++pattern; |
| 390 | break; |
| 391 | } |
| 392 | default: { |
| 393 | *pos++ = '%'; |
| 394 | pattern = old_pattern + 1; |
| 395 | break; |
| 396 | } |
| 397 | } |
| 398 | } |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 399 | } |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 400 | /* TODO: How do we get rid of this? */ |
| 401 | if (*pattern != '\0') |
| 402 | KMP_FATAL(FileNameTooLong); |
| 403 | } |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 404 | |
Jonathan Peyton | 3041982 | 2017-05-12 18:01:32 +0000 | [diff] [blame] | 405 | *pos = '\0'; |
Jim Cownie | 5e8470a | 2013-09-27 10:38:44 +0000 | [diff] [blame] | 406 | } |