Allow sysconf to return CPU cache information
* include/sys/unistd.h (_SC_LEVEL*): Add cache-related variables as on Linux. * fhandler_proc.cc (format_proc_cpuinfo): Fetch cache information from new cache functions in sysconf.cc, get_cpu_cache_intel and get_cpu_cache_amd. * sysconf.cc (__nt_query_system): New local helper. (get_nproc_values): Utilize __nt_query_system on pre-Windows 7 systems. Use GetLogicalProcessorInformationEx otherwise to handle more than 64 CPUs. Only handle _SC_NPROCESSORS_CONF and _SC_NPROCESSORS_ONLN. (get_phys_pages): New helper to handle _SC_PHYS_PAGES. (cpuid2_cache_descriptor): New array to map Intel CPUID 2 descriptor values to cache type, cache size, associativity and linesize. (cpuid2_cache_desc_compar): Comparision function for bsearch over cpuid2_cache_descriptor. (get_cpu_cache_intel_cpuid2): New function to fetch cache info from Intel CPUID 2. (get_cpu_cache_intel_cpuid4): Ditto from Intel CPUID 4. (get_cpu_cache_intel): New function as CPU-specific entry point. (assoc): New array to map associativity values from AMD CPUID 0x80000006. (get_cpu_cache_amd): New function to fetch cache info from AMD CPUIDs 0x80000005 and 0x80000006. (get_cpu_cache): New function to fetch cache info. (sca): Call get_phys_pages if _SC_PHYS_PAGES is requested. Call get_cpu_cache for new _SC_* cache requests. (SC_MAX): Set to _SC_LEVEL4_CACHE_LINESIZE. (get_phys_pages(void)): Call get_phys_pages(int). * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump. * new-features.xml (ov-new2.3): Document sysconf cache addition. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
@ -758,47 +758,46 @@ format_proc_cpuinfo (void *, char *&destbuf)
|
||||
cache_alignment = clflush * 2;
|
||||
if (is_intel)
|
||||
{
|
||||
uint32_t cache_level = 0;
|
||||
uint32_t info, layout, sets;
|
||||
extern long get_cpu_cache_intel (int sysc, uint32_t maxf);
|
||||
long cs;
|
||||
|
||||
for (int idx = 0; ; ++idx)
|
||||
/* As on Linux, don't check for L3 cache. */
|
||||
cs = get_cpu_cache_intel (_SC_LEVEL2_CACHE_SIZE, maxf);
|
||||
if (cs == -1)
|
||||
{
|
||||
cpuid (&info, &layout, &sets, &unused, 0x00000004, idx);
|
||||
uint32_t cache_type = (info & 0x1f);
|
||||
if (cache_type == 0)
|
||||
break;
|
||||
uint32_t cur_level = ((info >> 5) & 0x7);
|
||||
uint32_t ways = ((layout >> 22) & 0x3ff) + 1;
|
||||
uint32_t part = ((layout >> 12) & 0x3ff) + 1;
|
||||
uint32_t line = (layout & 0xfff) + 1;
|
||||
sets++;
|
||||
if (cur_level == cache_level)
|
||||
cache_size += ways * part * line * sets;
|
||||
else if (cur_level > cache_level)
|
||||
{
|
||||
cache_size = ways * part * line * sets;
|
||||
cache_level = cur_level;
|
||||
}
|
||||
cs = get_cpu_cache_intel (_SC_LEVEL1_ICACHE_SIZE, maxf);
|
||||
if (cs != -1)
|
||||
cache_size = cs;
|
||||
cs = get_cpu_cache_intel (_SC_LEVEL1_DCACHE_SIZE, maxf);
|
||||
if (cs != -1)
|
||||
cache_size += cs;
|
||||
}
|
||||
else
|
||||
cache_size = cs;
|
||||
if (cache_size != -1)
|
||||
cache_size >>= 10;
|
||||
}
|
||||
/* L2 Cache and L2 TLB Identifiers. */
|
||||
if (cache_size == -1 && maxe >= 0x80000006)
|
||||
else if (is_amd)
|
||||
{
|
||||
uint32_t l2;
|
||||
cpuid (&unused, &unused, &l2, &unused, 0x80000006);
|
||||
extern long get_cpu_cache_amd (int sysc, uint32_t maxe);
|
||||
long cs;
|
||||
|
||||
cache_size = l2 >> 16;
|
||||
}
|
||||
/* L1 Cache and TLB Identifiers. */
|
||||
if (cache_size == -1 && maxe >= 0x80000005)
|
||||
{
|
||||
uint32_t data_cache, inst_cache;
|
||||
cpuid (&unused, &unused, &data_cache, &inst_cache,
|
||||
0x80000005);
|
||||
|
||||
cache_size = (inst_cache >> 24) + (data_cache >> 24);
|
||||
cs = get_cpu_cache_amd (_SC_LEVEL3_CACHE_SIZE, maxe);
|
||||
if (cs == -1)
|
||||
cs = get_cpu_cache_amd (_SC_LEVEL2_CACHE_SIZE, maxe);
|
||||
if (cs == -1)
|
||||
{
|
||||
cs = get_cpu_cache_amd (_SC_LEVEL1_ICACHE_SIZE, maxe);
|
||||
if (cs != -1)
|
||||
cache_size = cs;
|
||||
cs = get_cpu_cache_amd (_SC_LEVEL1_DCACHE_SIZE, maxe);
|
||||
if (cs != -1)
|
||||
cache_size += cs;
|
||||
}
|
||||
else
|
||||
cache_size = cs;
|
||||
if (cache_size != -1)
|
||||
cache_size >>= 10;
|
||||
}
|
||||
bufptr += __small_sprintf (bufptr, "cpu family\t: %d\n"
|
||||
"model\t\t: %d\n"
|
||||
|
Reference in New Issue
Block a user