38 #include "kmp_wrapper_getpid.h"
46 static const char *unknown =
"unknown";
48 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
54 static int trace_level = 5;
62 __kmp_get_physical_id(
int log_per_phy,
int apic_id )
64 int index_lsb, index_msb, temp;
66 if (log_per_phy > 1) {
71 while ( (temp & 1) == 0 ) {
77 while ( (temp & 0x80000000)==0 ) {
83 if (index_lsb != index_msb) index_msb++;
85 return ( (
int) (apic_id >> index_msb) );
98 __kmp_get_logical_id(
int log_per_phy,
int apic_id )
100 unsigned current_bit;
104 if (log_per_phy <= 1)
return ( 0 );
108 for (current_bit = 1; log_per_phy != 0; current_bit <<= 1) {
109 if ( log_per_phy & current_bit ) {
110 log_per_phy &= ~current_bit;
116 if (bits_seen == 1) {
120 return ( (
int) ((current_bit - 1) & apic_id) );
126 __kmp_parse_frequency(
127 char const * frequency
131 char const * unit = NULL;
132 kmp_uint64 result = ~ 0;
134 if ( frequency == NULL ) {
137 value = strtod( frequency, (
char * *) & unit );
138 if ( 0 < value && value <= DBL_MAX ) {
139 if ( strcmp( unit,
"MHz" ) == 0 ) {
140 value = value * 1.0E+6;
141 }
else if ( strcmp( unit,
"GHz" ) == 0 ) {
142 value = value * 1.0E+9;
143 }
else if ( strcmp( unit,
"THz" ) == 0 ) {
144 value = value * 1.0E+12;
155 __kmp_query_cpuid( kmp_cpuinfo_t *p )
157 struct kmp_cpuid buf;
166 __kmp_x86_cpuid( 0, 0, &buf );
168 KA_TRACE( trace_level, (
"INFO: CPUID %d: EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n",
169 0, buf.eax, buf.ebx, buf.ecx, buf.edx ) );
177 kmp_uint32 t, data[ 4 ];
179 __kmp_x86_cpuid( 1, 0, &buf );
180 KA_TRACE( trace_level, (
"INFO: CPUID %d: EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n",
181 1, buf.eax, buf.ebx, buf.ecx, buf.edx ) );
184 #define get_value(reg,lo,mask) ( ( ( reg ) >> ( lo ) ) & ( mask ) )
186 p->signature = buf.eax;
187 p->family = get_value( buf.eax, 20, 0xff ) + get_value( buf.eax, 8, 0x0f );
188 p->model = ( get_value( buf.eax, 16, 0x0f ) << 4 ) + get_value( buf.eax, 4, 0x0f );
189 p->stepping = get_value( buf.eax, 0, 0x0f );
193 KA_TRACE( trace_level, (
" family = %d, model = %d, stepping = %d\n", p->family, p->model, p->stepping ) );
196 for ( t = buf.ebx, i = 0; i < 4; t >>= 8, ++i ) {
197 data[ i ] = (t & 0xff);
200 p->sse2 = ( buf.edx >> 26 ) & 1;
204 if ( (buf.edx >> 4) & 1 ) {
206 KA_TRACE( trace_level, (
" TSC" ) );
208 if ( (buf.edx >> 8) & 1 ) {
210 KA_TRACE( trace_level, (
" CX8" ) );
212 if ( (buf.edx >> 9) & 1 ) {
214 KA_TRACE( trace_level, (
" APIC" ) );
216 if ( (buf.edx >> 15) & 1 ) {
218 KA_TRACE( trace_level, (
" CMOV" ) );
220 if ( (buf.edx >> 18) & 1 ) {
222 KA_TRACE( trace_level, (
" PSN" ) );
224 if ( (buf.edx >> 19) & 1 ) {
226 cflush_size = data[ 1 ] * 8;
227 KA_TRACE( trace_level, (
" CLFLUSH(%db)", cflush_size ) );
230 if ( (buf.edx >> 21) & 1 ) {
232 KA_TRACE( trace_level, (
" DTES" ) );
234 if ( (buf.edx >> 22) & 1 ) {
236 KA_TRACE( trace_level, (
" ACPI" ) );
238 if ( (buf.edx >> 23) & 1 ) {
240 KA_TRACE( trace_level, (
" MMX" ) );
242 if ( (buf.edx >> 25) & 1 ) {
244 KA_TRACE( trace_level, (
" SSE" ) );
246 if ( (buf.edx >> 26) & 1 ) {
248 KA_TRACE( trace_level, (
" SSE2" ) );
250 if ( (buf.edx >> 27) & 1 ) {
252 KA_TRACE( trace_level, (
" SLFSNP" ) );
256 __kmp_ht_capable = FALSE;
257 if ( (buf.edx >> 28) & 1 ) {
260 __kmp_ht_capable = TRUE;
263 log_per_phy = data[ 2 ];
264 __kmp_ht_log_per_phy = log_per_phy;
266 p->apic_id = data[ 3 ];
267 KA_TRACE( trace_level, (
" HT(%d TPUs)", log_per_phy ) );
269 if( log_per_phy > 1 ) {
272 p->cpu_stackoffset = 4 * 1024;
274 p->cpu_stackoffset = 1 * 1024;
278 p->physical_id = __kmp_get_physical_id( log_per_phy, p->apic_id );
279 p->logical_id = __kmp_get_logical_id( log_per_phy, p->apic_id );
282 if ( (buf.edx >> 29) & 1 ) {
284 KA_TRACE( trace_level, (
" ATHROTL" ) );
286 KA_TRACE( trace_level, (
" ]\n" ) );
288 for (i = 2; i <= max_arg; ++i) {
289 __kmp_x86_cpuid( i, 0, &buf );
290 KA_TRACE( trace_level,
291 (
"INFO: CPUID %d: EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n",
292 i, buf.eax, buf.ebx, buf.ecx, buf.edx ) );
295 #if KMP_USE_ADAPTIVE_LOCKS
300 __kmp_x86_cpuid(7, 0, &buf);
301 p->rtm = (buf.ebx >> 11) & 1;
302 KA_TRACE( trace_level, (
" RTM" ) );
309 union kmp_cpu_brand_string {
310 struct kmp_cpuid buf[ 3 ];
311 char string[
sizeof(
struct kmp_cpuid ) * 3 + 1 ];
313 union kmp_cpu_brand_string brand;
319 for ( i = 0; i < 3; ++ i ) {
320 __kmp_x86_cpuid( 0x80000002 + i, 0, &brand.buf[ i ] );
322 brand.string[
sizeof( brand.string ) - 1 ] = 0;
323 KA_TRACE( trace_level, (
"cpu brand string: \"%s\"\n", brand.string ) );
326 p->frequency = __kmp_parse_frequency( strrchr( brand.string,
' ' ) );
327 KA_TRACE( trace_level, (
"cpu frequency from brand string: %" KMP_UINT64_SPEC
"\n", p->frequency ) );
337 __kmp_expand_host_name(
char *buffer,
size_t size )
339 KMP_DEBUG_ASSERT(size >=
sizeof(unknown));
344 if (! GetComputerNameA( buffer, & s ))
345 strcpy( buffer, unknown );
348 buffer[size - 2] = 0;
349 if (gethostname( buffer, size ) || buffer[size - 2] != 0)
350 strcpy( buffer, unknown );
364 __kmp_expand_file_name(
char *result,
size_t rlen,
char *pattern )
366 char *pos = result, *end = result + rlen - 1;
368 int default_cpu_width = 1;
371 KMP_DEBUG_ASSERT(rlen > 0);
375 for(i = __kmp_xproc; i >= 10; i /= 10, ++default_cpu_width);
378 if (pattern != NULL) {
379 while (*pattern !=
'\0' && pos < end) {
380 if (*pattern !=
'%') {
383 char *old_pattern = pattern;
385 int cpu_width = default_cpu_width;
389 if (*pattern >=
'0' && *pattern <=
'9') {
392 width = (width * 10) + *pattern++ -
'0';
393 }
while (*pattern >=
'0' && *pattern <=
'9');
394 if (width < 0 || width > 1024)
404 __kmp_expand_host_name( buffer,
sizeof( buffer ) );
405 strncpy( pos, buffer, end - pos + 1);
417 snp_result = snprintf( pos, end - pos + 1,
"%0*d", cpu_width, __kmp_dflt_team_nth );
418 if(snp_result >= 0 && snp_result <= end - pos) {
430 snp_result = snprintf( pos, end - pos + 1,
"%0*d", width,
id );
431 if(snp_result >= 0 && snp_result <= end - pos) {
448 pattern = old_pattern + 1;
456 KMP_FATAL( FileNameTooLong );