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