mirror of
https://github.com/anrieff/libcpuid
synced 2024-12-16 16:35:45 +00:00
parent
23b6f5cf54
commit
737cc3d98e
2 changed files with 50 additions and 6 deletions
|
@ -103,6 +103,12 @@ static void apic_info_t_constructor(struct internal_apic_info_t* apic_info, logi
|
|||
apic_info->logical_cpu = logical_cpu;
|
||||
}
|
||||
|
||||
static void core_instances_t_constructor(struct internal_core_instances_t* data)
|
||||
{
|
||||
data->instances = 0;
|
||||
memset(data->htable, 0, sizeof(data->htable));
|
||||
}
|
||||
|
||||
static void cache_instances_t_constructor(struct internal_cache_instances_t* data)
|
||||
{
|
||||
memset(data->instances, 0, sizeof(data->instances));
|
||||
|
@ -1009,6 +1015,24 @@ int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
|||
return r;
|
||||
}
|
||||
|
||||
static void update_core_instances(struct internal_core_instances_t* cores,
|
||||
struct internal_apic_info_t* apic_info)
|
||||
{
|
||||
uint32_t core_id_index = 0;
|
||||
|
||||
core_id_index = apic_info->core_id % CORES_HTABLE_SIZE;
|
||||
if ((cores->htable[core_id_index].core_id == 0) || (cores->htable[core_id_index].core_id == apic_info->core_id)) {
|
||||
if (cores->htable[core_id_index].num_logical_cpu == 0)
|
||||
cores->instances++;
|
||||
cores->htable[core_id_index].core_id = apic_info->core_id;
|
||||
cores->htable[core_id_index].num_logical_cpu++;
|
||||
}
|
||||
else {
|
||||
warnf("update_core_instances: collision at index %u (core ID is %i, not %i)\n",
|
||||
core_id_index, cores->htable[core_id_index].core_id, apic_info->core_id);
|
||||
}
|
||||
}
|
||||
|
||||
static void update_cache_instances(struct internal_cache_instances_t* caches,
|
||||
struct internal_apic_info_t* apic_info,
|
||||
struct internal_id_info_t* id_info)
|
||||
|
@ -1059,6 +1083,7 @@ int cpu_identify_all(struct cpu_raw_data_array_t* raw_array, struct system_id_t*
|
|||
struct cpu_raw_data_array_t my_raw_array;
|
||||
struct internal_id_info_t id_info;
|
||||
struct internal_apic_info_t apic_info;
|
||||
struct internal_core_instances_t cores_type;
|
||||
struct internal_cache_instances_t caches_type, caches_all;
|
||||
|
||||
if (system == NULL)
|
||||
|
@ -1069,6 +1094,7 @@ int cpu_identify_all(struct cpu_raw_data_array_t* raw_array, struct system_id_t*
|
|||
raw_array = &my_raw_array;
|
||||
}
|
||||
system_id_t_constructor(system);
|
||||
core_instances_t_constructor(&cores_type);
|
||||
cache_instances_t_constructor(&caches_type);
|
||||
cache_instances_t_constructor(&caches_all);
|
||||
if (raw_array->with_affinity)
|
||||
|
@ -1104,6 +1130,7 @@ int cpu_identify_all(struct cpu_raw_data_array_t* raw_array, struct system_id_t*
|
|||
set_affinity_mask_bit(logical_cpu, &affinity_mask);
|
||||
num_logical_cpus++;
|
||||
if (is_apic_supported) {
|
||||
update_core_instances(&cores_type, &apic_info);
|
||||
update_cache_instances(&caches_type, &apic_info, &id_info);
|
||||
update_cache_instances(&caches_all, &apic_info, &id_info);
|
||||
}
|
||||
|
@ -1112,29 +1139,35 @@ int cpu_identify_all(struct cpu_raw_data_array_t* raw_array, struct system_id_t*
|
|||
/* Update logical and physical CPU counters in system->cpu_types on the last iteration or when purpose is different than previous core */
|
||||
if (raw_array->with_affinity && (is_last_item || (is_new_cpu_type && (system->num_cpu_types > 1)))) {
|
||||
cpu_type_index = is_new_cpu_type ? system->num_cpu_types - 2 : system->num_cpu_types - 1;
|
||||
is_smt_supported = (system->cpu_types[cpu_type_index].num_logical_cpus % system->cpu_types[cpu_type_index].num_cores) == 0;
|
||||
smt_divisor = is_smt_supported ? system->cpu_types[cpu_type_index].num_logical_cpus / system->cpu_types[cpu_type_index].num_cores : 1.0;
|
||||
/* Save current values in system->cpu_types[cpu_type_index] and reset values for the next purpose */
|
||||
system->cpu_types[cpu_type_index].num_cores = num_logical_cpus / smt_divisor;
|
||||
system->cpu_types[cpu_type_index].num_logical_cpus = num_logical_cpus;
|
||||
num_logical_cpus = 1;
|
||||
copy_affinity_mask(&system->cpu_types[cpu_type_index].affinity_mask, &affinity_mask);
|
||||
if (!is_last_item) {
|
||||
init_affinity_mask(&affinity_mask);
|
||||
set_affinity_mask_bit(logical_cpu, &affinity_mask);
|
||||
}
|
||||
if (is_apic_supported) {
|
||||
system->cpu_types[cpu_type_index].num_cores = cores_type.instances;
|
||||
system->cpu_types[cpu_type_index].l1_instruction_instances = caches_type.instances[L1I];
|
||||
system->cpu_types[cpu_type_index].l1_data_instances = caches_type.instances[L1D];
|
||||
system->cpu_types[cpu_type_index].l2_instances = caches_type.instances[L2];
|
||||
system->cpu_types[cpu_type_index].l3_instances = caches_type.instances[L3];
|
||||
system->cpu_types[cpu_type_index].l4_instances = caches_type.instances[L4];
|
||||
if (!is_last_item) {
|
||||
core_instances_t_constructor(&cores_type);
|
||||
cache_instances_t_constructor(&caches_type);
|
||||
update_core_instances(&cores_type, &apic_info);
|
||||
update_cache_instances(&caches_type, &apic_info, &id_info);
|
||||
update_cache_instances(&caches_all, &apic_info, &id_info);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Note: if SMT is disabled by BIOS, smt_divisor will no reflect the current state properly */
|
||||
is_smt_supported = (system->cpu_types[cpu_type_index].num_logical_cpus % system->cpu_types[cpu_type_index].num_cores) == 0;
|
||||
smt_divisor = is_smt_supported ? system->cpu_types[cpu_type_index].num_logical_cpus / system->cpu_types[cpu_type_index].num_cores : 1.0;
|
||||
system->cpu_types[cpu_type_index].num_cores = num_logical_cpus / smt_divisor;
|
||||
}
|
||||
/* Save current values in system->cpu_types[cpu_type_index] and reset values for the next purpose */
|
||||
system->cpu_types[cpu_type_index].num_logical_cpus = num_logical_cpus;
|
||||
num_logical_cpus = 1;
|
||||
}
|
||||
prev_package_id = cur_package_id;
|
||||
}
|
||||
|
|
|
@ -81,11 +81,22 @@ struct internal_apic_info_t {
|
|||
logical_cpu_t logical_cpu;
|
||||
};
|
||||
|
||||
struct internal_core_id_t {
|
||||
logical_cpu_t num_logical_cpu;
|
||||
int32_t core_id;
|
||||
};
|
||||
|
||||
struct internal_cache_id_t {
|
||||
logical_cpu_t num_logical_cpu;
|
||||
int32_t cache_id;
|
||||
};
|
||||
|
||||
#define CORES_HTABLE_SIZE 256
|
||||
struct internal_core_instances_t {
|
||||
uint8_t instances;
|
||||
struct internal_core_id_t htable[CORES_HTABLE_SIZE];
|
||||
};
|
||||
|
||||
#define CACHES_HTABLE_SIZE 256
|
||||
struct internal_cache_instances_t {
|
||||
uint8_t instances[NUM_CACHE_TYPES];
|
||||
|
|
Loading…
Reference in a new issue