move cpuid from os/linux to sigar_util for use on other platforms

This commit is contained in:
Doug MacEachern 2008-04-09 06:29:08 +00:00
parent 277cf2e68e
commit 2b9c8971e0
5 changed files with 118 additions and 104 deletions

View File

@ -137,6 +137,10 @@ typedef struct {
sigar_iodev_t *sigar_iodev_get(sigar_t *sigar, sigar_iodev_t *sigar_iodev_get(sigar_t *sigar,
const char *dirname); const char *dirname);
int sigar_cpu_core_count(sigar_t *sigar);
int sigar_cpu_core_rollup(sigar_t *sigar);
void sigar_cpu_model_adjust(sigar_t *sigar, sigar_cpu_info_t *info); void sigar_cpu_model_adjust(sigar_t *sigar, sigar_cpu_info_t *info);
int sigar_cpu_mhz_from_model(char *model); int sigar_cpu_mhz_from_model(char *model);

View File

@ -253,6 +253,7 @@ int sigar_os_open(sigar_t **sigar)
#endif #endif
(*sigar)->ncpu = ncpu; (*sigar)->ncpu = ncpu;
(*sigar)->lcpu = -1;
(*sigar)->boot_time = boottime.tv_sec; /* XXX seems off a bit */ (*sigar)->boot_time = boottime.tv_sec; /* XXX seems off a bit */
@ -2017,7 +2018,7 @@ int sigar_file_system_usage_get(sigar_t *sigar,
int sigar_cpu_info_list_get(sigar_t *sigar, int sigar_cpu_info_list_get(sigar_t *sigar,
sigar_cpu_info_list_t *cpu_infos) sigar_cpu_info_list_t *cpu_infos)
{ {
int i; int i, lcpu=1;
unsigned int mhz; unsigned int mhz;
int cache_size=SIGAR_FIELD_NOTIMPL; int cache_size=SIGAR_FIELD_NOTIMPL;
size_t size; size_t size;
@ -2025,6 +2026,10 @@ int sigar_cpu_info_list_get(sigar_t *sigar,
size = sizeof(mhz); size = sizeof(mhz);
#if defined(DARWIN)
lcpu = sigar_cpu_core_count(sigar);
#endif
#if defined(DARWIN) #if defined(DARWIN)
{ {
int mib[] = { CTL_HW, HW_CPU_FREQ }; int mib[] = { CTL_HW, HW_CPU_FREQ };
@ -2124,7 +2129,7 @@ int sigar_cpu_info_list_get(sigar_t *sigar,
info->mhz = mhz; info->mhz = mhz;
info->cache_size = cache_size; info->cache_size = cache_size;
info->total_cores = sigar->ncpu; info->total_cores = sigar->ncpu;
info->total_sockets = sigar->ncpu; info->total_sockets = sigar->ncpu / lcpu;
} }
return SIGAR_OK; return SIGAR_OK;

View File

@ -59,6 +59,7 @@ struct sigar_t {
time_t last_getprocs; time_t last_getprocs;
sigar_pid_t last_pid; sigar_pid_t last_pid;
bsd_pinfo_t *pinfo; bsd_pinfo_t *pinfo;
int lcpu;
#ifdef DARWIN #ifdef DARWIN
mach_port_t mach_port; mach_port_t mach_port;
void *libproc; void *libproc;

View File

@ -210,108 +210,6 @@ char *sigar_os_error_string(sigar_t *sigar, int err)
return NULL; return NULL;
} }
#define INTEL_ID 0x756e6547
#define AMD_ID 0x68747541
#if defined(__i386__)
#define SIGAR_HAS_CPUID
static void sigar_cpuid(sigar_uint32_t request,
sigar_uint32_t *eax,
sigar_uint32_t *ebx,
sigar_uint32_t *ecx,
sigar_uint32_t *edx)
{
#if 0
/* does not compile w/ -fPIC */
/* can't find a register in class `BREG' while reloading `asm' */
asm volatile ("cpuid" :
"=a" (*eax),
"=b" (*ebx),
"=c" (*ecx),
"=d" (*edx)
: "a" (request));
#else
/* derived from: */
/* http://svn.red-bean.com/repos/minor/trunk/gc/barriers-ia-32.c */
asm volatile ("mov %%ebx, %%esi\n\t"
"cpuid\n\t"
"xchgl %%ebx, %%esi"
: "=a" (*eax),
"=S" (*ebx),
"=c" (*ecx),
"=d" (*edx)
: "0" (request)
: "memory");
#endif
}
#elif defined(__amd64__)
#define SIGAR_HAS_CPUID
static void sigar_cpuid(unsigned int request,
unsigned int *eax,
unsigned int *ebx,
unsigned int *ecx,
unsigned int *edx)
{
/* http://svn.red-bean.com/repos/minor/trunk/gc/barriers-amd64.c */
asm volatile ("cpuid\n\t"
: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
: "0" (request)
: "memory");
}
#endif
#ifdef SIGAR_HAS_CPUID
static int sigar_cpu_core_count(sigar_t *sigar)
{
sigar_uint32_t eax, ebx, ecx, edx;
if (sigar->lcpu == -1) {
sigar->lcpu = 1;
sigar_cpuid(0, &eax, &ebx, &ecx, &edx);
if ((ebx == INTEL_ID) || (ebx == AMD_ID)) {
sigar_cpuid(1, &eax, &ebx, &ecx, &edx);
if (edx & (1<<28)) {
sigar->lcpu = (ebx & 0x00FF0000) >> 16;
}
}
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
"[cpu] %d cores per socket", sigar->lcpu);
}
return sigar->lcpu;
}
static int sigar_cpu_core_rollup(sigar_t *sigar)
{
(void)sigar_cpu_core_count(sigar);
if (sigar->cpu_list_cores) {
if (sigar->lcpu > 1) {
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
"[cpu] treating cores as-is");
}
}
else {
if (sigar->lcpu > 1) {
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
"[cpu] rolling up cores to sockets");
return 1;
}
}
return 0;
}
#else
#define sigar_cpu_core_rollup(sigar) 0
#define sigar_cpu_core_count(sigar) 1
#endif
static int sigar_cpu_total_count(sigar_t *sigar) static int sigar_cpu_total_count(sigar_t *sigar)
{ {
return (int)sysconf(_SC_NPROCESSORS_CONF); return (int)sysconf(_SC_NPROCESSORS_CONF);

View File

@ -483,6 +483,112 @@ double sigar_file_system_usage_calc_used(sigar_t *sigar,
return 0; return 0;
} }
#if defined(__linux__) || defined(DARWIN)
#define INTEL_ID 0x756e6547
#define AMD_ID 0x68747541
#if defined(__i386__)
#define SIGAR_HAS_CPUID
static void sigar_cpuid(sigar_uint32_t request,
sigar_uint32_t *eax,
sigar_uint32_t *ebx,
sigar_uint32_t *ecx,
sigar_uint32_t *edx)
{
#if 0
/* does not compile w/ -fPIC */
/* can't find a register in class `BREG' while reloading `asm' */
asm volatile ("cpuid" :
"=a" (*eax),
"=b" (*ebx),
"=c" (*ecx),
"=d" (*edx)
: "a" (request));
#else
/* derived from: */
/* http://svn.red-bean.com/repos/minor/trunk/gc/barriers-ia-32.c */
asm volatile ("mov %%ebx, %%esi\n\t"
"cpuid\n\t"
"xchgl %%ebx, %%esi"
: "=a" (*eax),
"=S" (*ebx),
"=c" (*ecx),
"=d" (*edx)
: "0" (request)
: "memory");
#endif
}
#elif defined(__amd64__)
#define SIGAR_HAS_CPUID
static void sigar_cpuid(unsigned int request,
unsigned int *eax,
unsigned int *ebx,
unsigned int *ecx,
unsigned int *edx)
{
/* http://svn.red-bean.com/repos/minor/trunk/gc/barriers-amd64.c */
asm volatile ("cpuid\n\t"
: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
: "0" (request)
: "memory");
}
#endif
int sigar_cpu_core_count(sigar_t *sigar)
{
#ifdef SIGAR_HAS_CPUID
sigar_uint32_t eax, ebx, ecx, edx;
if (sigar->lcpu == -1) {
sigar->lcpu = 1;
sigar_cpuid(0, &eax, &ebx, &ecx, &edx);
if ((ebx == INTEL_ID) || (ebx == AMD_ID)) {
sigar_cpuid(1, &eax, &ebx, &ecx, &edx);
if (edx & (1<<28)) {
sigar->lcpu = (ebx & 0x00FF0000) >> 16;
}
}
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
"[cpu] %d cores per socket", sigar->lcpu);
}
return sigar->lcpu;
#else
sigar->lcpu = 1;
return sigar->lcpu;
#endif
}
int sigar_cpu_core_rollup(sigar_t *sigar)
{
#ifdef SIGAR_HAS_CPUID
(void)sigar_cpu_core_count(sigar);
if (sigar->cpu_list_cores) {
if (sigar->lcpu > 1) {
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
"[cpu] treating cores as-is");
}
}
else {
if (sigar->lcpu > 1) {
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
"[cpu] rolling up cores to sockets");
return 1;
}
}
#endif
return 0;
}
#endif /* cpuid stuff */
#define IS_CPU_R(p) \ #define IS_CPU_R(p) \
((*p == '(') && (*(p+1) == 'R') && (*(p+2) == ')')) ((*p == '(') && (*(p+1) == 'R') && (*(p+2) == ')'))