17 #include "kmp_wrapper_getpid.h" 25 static const char *unknown =
"unknown";
27 #if KMP_ARCH_X86 || KMP_ARCH_X86_64 34 static int trace_level = 5;
43 __kmp_get_physical_id(
int log_per_phy,
int apic_id )
45 int index_lsb, index_msb, temp;
47 if (log_per_phy > 1) {
52 while ( (temp & 1) == 0 ) {
58 while ( (temp & 0x80000000)==0 ) {
64 if (index_lsb != index_msb) index_msb++;
66 return ( (
int) (apic_id >> index_msb) );
79 __kmp_get_logical_id(
int log_per_phy,
int apic_id )
84 if (log_per_phy <= 1)
return ( 0 );
88 for (current_bit = 1; log_per_phy != 0; current_bit <<= 1) {
89 if ( log_per_phy & current_bit ) {
90 log_per_phy &= ~current_bit;
100 return ( (
int) ((current_bit - 1) & apic_id) );
106 __kmp_parse_frequency(
107 char const * frequency
111 char const * unit = NULL;
112 kmp_uint64 result = ~ 0;
114 if ( frequency == NULL ) {
117 value = strtod( frequency, (
char * *) & unit );
118 if ( 0 < value && value <= DBL_MAX ) {
119 if ( strcmp( unit,
"MHz" ) == 0 ) {
120 value = value * 1.0E+6;
121 }
else if ( strcmp( unit,
"GHz" ) == 0 ) {
122 value = value * 1.0E+9;
123 }
else if ( strcmp( unit,
"THz" ) == 0 ) {
124 value = value * 1.0E+12;
135 __kmp_query_cpuid( kmp_cpuinfo_t *p )
137 struct kmp_cpuid buf;
148 __kmp_x86_cpuid( 0, 0, &buf );
150 KA_TRACE( trace_level, (
"INFO: CPUID %d: EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n",
151 0, buf.eax, buf.ebx, buf.ecx, buf.edx ) );
159 kmp_uint32 t, data[ 4 ];
161 __kmp_x86_cpuid( 1, 0, &buf );
162 KA_TRACE( trace_level, (
"INFO: CPUID %d: EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n",
163 1, buf.eax, buf.ebx, buf.ecx, buf.edx ) );
166 #define get_value(reg,lo,mask) ( ( ( reg ) >> ( lo ) ) & ( mask ) ) 168 p->signature = buf.eax;
169 p->family = get_value( buf.eax, 20, 0xff ) + get_value( buf.eax, 8, 0x0f );
170 p->model = ( get_value( buf.eax, 16, 0x0f ) << 4 ) + get_value( buf.eax, 4, 0x0f );
171 p->stepping = get_value( buf.eax, 0, 0x0f );
175 KA_TRACE( trace_level, (
" family = %d, model = %d, stepping = %d\n", p->family, p->model, p->stepping ) );
178 for ( t = buf.ebx, i = 0; i < 4; t >>= 8, ++i ) {
179 data[ i ] = (t & 0xff);
182 p->sse2 = ( buf.edx >> 26 ) & 1;
186 if ( (buf.edx >> 4) & 1 ) {
188 KA_TRACE( trace_level, (
" TSC" ) );
190 if ( (buf.edx >> 8) & 1 ) {
192 KA_TRACE( trace_level, (
" CX8" ) );
194 if ( (buf.edx >> 9) & 1 ) {
196 KA_TRACE( trace_level, (
" APIC" ) );
198 if ( (buf.edx >> 15) & 1 ) {
200 KA_TRACE( trace_level, (
" CMOV" ) );
202 if ( (buf.edx >> 18) & 1 ) {
204 KA_TRACE( trace_level, (
" PSN" ) );
206 if ( (buf.edx >> 19) & 1 ) {
208 cflush_size = data[ 1 ] * 8;
209 KA_TRACE( trace_level, (
" CLFLUSH(%db)", cflush_size ) );
212 if ( (buf.edx >> 21) & 1 ) {
214 KA_TRACE( trace_level, (
" DTES" ) );
216 if ( (buf.edx >> 22) & 1 ) {
218 KA_TRACE( trace_level, (
" ACPI" ) );
220 if ( (buf.edx >> 23) & 1 ) {
222 KA_TRACE( trace_level, (
" MMX" ) );
224 if ( (buf.edx >> 25) & 1 ) {
226 KA_TRACE( trace_level, (
" SSE" ) );
228 if ( (buf.edx >> 26) & 1 ) {
230 KA_TRACE( trace_level, (
" SSE2" ) );
232 if ( (buf.edx >> 27) & 1 ) {
234 KA_TRACE( trace_level, (
" SLFSNP" ) );
238 if ( (buf.edx >> 28) & 1 ) {
240 log_per_phy = data[ 2 ];
241 p->apic_id = data[ 3 ];
242 KA_TRACE( trace_level, (
" HT(%d TPUs)", log_per_phy ) );
244 if( log_per_phy > 1 ) {
247 p->cpu_stackoffset = 4 * 1024;
249 p->cpu_stackoffset = 1 * 1024;
253 p->physical_id = __kmp_get_physical_id( log_per_phy, p->apic_id );
254 p->logical_id = __kmp_get_logical_id( log_per_phy, p->apic_id );
257 if ( (buf.edx >> 29) & 1 ) {
259 KA_TRACE( trace_level, (
" ATHROTL" ) );
261 KA_TRACE( trace_level, (
" ]\n" ) );
263 for (i = 2; i <= max_arg; ++i) {
264 __kmp_x86_cpuid( i, 0, &buf );
265 KA_TRACE( trace_level,
266 (
"INFO: CPUID %d: EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n",
267 i, buf.eax, buf.ebx, buf.ecx, buf.edx ) );
270 #if KMP_USE_ADAPTIVE_LOCKS 275 __kmp_x86_cpuid(7, 0, &buf);
276 p->rtm = (buf.ebx >> 11) & 1;
277 KA_TRACE( trace_level, (
" RTM" ) );
284 union kmp_cpu_brand_string {
285 struct kmp_cpuid buf[ 3 ];
286 char string[
sizeof(
struct kmp_cpuid ) * 3 + 1 ];
288 union kmp_cpu_brand_string brand;
294 for ( i = 0; i < 3; ++ i ) {
295 __kmp_x86_cpuid( 0x80000002 + i, 0, &brand.buf[ i ] );
297 brand.string[
sizeof( brand.string ) - 1 ] = 0;
298 KA_TRACE( trace_level, (
"cpu brand string: \"%s\"\n", brand.string ) );
301 p->frequency = __kmp_parse_frequency( strrchr( brand.string,
' ' ) );
302 KA_TRACE( trace_level, (
"cpu frequency from brand string: %" KMP_UINT64_SPEC
"\n", p->frequency ) );
312 __kmp_expand_host_name(
char *buffer,
size_t size )
314 KMP_DEBUG_ASSERT(size >=
sizeof(unknown));
319 if (! GetComputerNameA( buffer, & s ))
320 KMP_STRCPY_S( buffer, size, unknown );
323 buffer[size - 2] = 0;
324 if (gethostname( buffer, size ) || buffer[size - 2] != 0)
325 KMP_STRCPY_S( buffer, size, unknown );
339 __kmp_expand_file_name(
char *result,
size_t rlen,
char *pattern )
341 char *pos = result, *end = result + rlen - 1;
343 int default_cpu_width = 1;
346 KMP_DEBUG_ASSERT(rlen > 0);
350 for(i = __kmp_xproc; i >= 10; i /= 10, ++default_cpu_width);
353 if (pattern != NULL) {
354 while (*pattern !=
'\0' && pos < end) {
355 if (*pattern !=
'%') {
358 char *old_pattern = pattern;
360 int cpu_width = default_cpu_width;
364 if (*pattern >=
'0' && *pattern <=
'9') {
367 width = (width * 10) + *pattern++ -
'0';
368 }
while (*pattern >=
'0' && *pattern <=
'9');
369 if (width < 0 || width > 1024)
379 __kmp_expand_host_name( buffer,
sizeof( buffer ) );
380 KMP_STRNCPY( pos, buffer, end - pos + 1);
392 snp_result = KMP_SNPRINTF( pos, end - pos + 1,
"%0*d", cpu_width, __kmp_dflt_team_nth );
393 if(snp_result >= 0 && snp_result <= end - pos) {
405 snp_result = KMP_SNPRINTF( pos, end - pos + 1,
"%0*d", width,
id );
406 if(snp_result >= 0 && snp_result <= end - pos) {
423 pattern = old_pattern + 1;
431 KMP_FATAL( FileNameTooLong );