1
0
Fork 0
mirror of https://github.com/anrieff/libcpuid synced 2025-10-03 11:01:30 +00:00

Add cpu_identify_all function

This commit is contained in:
Xorg 2022-09-04 19:46:30 +02:00
commit b714dcb00d
No known key found for this signature in database
GPG key ID: 1E55EE2EFF18BC1A
4 changed files with 86 additions and 1 deletions

View file

@ -682,8 +682,77 @@ int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct
int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
{
int r;
struct internal_id_info_t throwaway;
return cpu_ident_internal(raw, data, &throwaway);
r = cpu_ident_internal(raw, data, &throwaway);
data->affinity_mask = (1 << data->num_logical_cpus) - 1;
return r;
}
int cpu_identify_all(struct cpu_raw_data_array_t *raw_array, struct system_id_t* system)
{
int cur_error = set_error(ERR_OK);
int ret_error = set_error(ERR_OK); bool is_new_cpu_type;
uint8_t logical_cpu;
uint8_t cpu_type_index = 0;
int32_t core_previous_id = -1;
int32_t num_cores = 1;
int32_t num_logical_cpus = 1;
uint32_t affinity_mask = 0x00000001;
struct cpu_raw_data_array_t my_raw_array;
struct internal_id_info_t throwaway;
if (!raw_array) {
if ((ret_error = cpuid_get_all_raw_data(&my_raw_array)) < 0)
return set_error(ret_error);
raw_array = &my_raw_array;
}
if (system == NULL)
return set_error(ERR_HANDLE);
system->num_cpu_types = 0;
/* Iterate over all RAW */
for (logical_cpu = 0; logical_cpu < raw_array->num_raw; logical_cpu++) {
debugf(2, "Identifying logical core %u...\n", logical_cpu);
is_new_cpu_type = false;
cur_error = cpu_ident_internal(&raw_array->raw[logical_cpu], &system->cpu_types[system->num_cpu_types], &throwaway);
if (ret_error == ERR_OK)
ret_error = cur_error;
/* Copy data to system->cpu_types on the first iteration or when purpose is different than previous core */
if ((system->num_cpu_types == 0) || (system->cpu_types[system->num_cpu_types].purpose != system->cpu_types[system->num_cpu_types - 1].purpose)) {
is_new_cpu_type = true;
system->num_cpu_types++;
}
/* Increment logical and physical CPU counters for current purpose */
else {
affinity_mask |= 1 << logical_cpu;
num_logical_cpus++;
if (core_previous_id != throwaway.core_id)
num_cores++;
}
/* Update logical and physical CPU counters in system->cpu_types on the last iteration or when purpose is different than previous core */
if ((logical_cpu + 1 == raw_array->num_raw) || (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;
/* Save current values in system->cpu_types[cpu_type_index] */
system->cpu_types[cpu_type_index].affinity_mask = affinity_mask;
if (core_previous_id > 0) {
system->cpu_types[cpu_type_index].num_cores = num_cores;
system->cpu_types[cpu_type_index].num_logical_cpus = num_logical_cpus;
}
/* Reset values for the next purpose */
affinity_mask = 1 << logical_cpu;
num_cores = 1;
num_logical_cpus = 1;
}
core_previous_id = throwaway.core_id;
}
/* Update the total_logical_cpus value for each purpose */
for (cpu_type_index = 0; cpu_type_index < system->num_cpu_types; cpu_type_index++)
system->cpu_types[cpu_type_index].total_logical_cpus = logical_cpu;
return ret_error;
}
const char* cpu_architecture_str(cpu_architecture_t architecture)

View file

@ -33,5 +33,6 @@ cpuid_get_vendor @29
cpu_rdmsr_range @30
cpuid_get_epc @31
msr_serialize_raw_data @32
cpu_identify_all @36
cpu_architecture_str @38
cpu_purpose_str @39

View file

@ -770,6 +770,20 @@ int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename
*/
int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data);
/**
* @brief Identifies all the CPUs
* @param raw_array - Input - a pointer to the array of raw CPUID data, which is obtained
* either by cpuid_get_all_raw_data or cpuid_deserialize_all_raw_data.
* Can also be NULL, in which case the functions calls
* cpuid_get_all_raw_data itself.
* @param system - Output - the decoded CPU features/info is written here for each CPU type.
* @note The function is similar to cpu_identify. Refer to cpu_identify notes.
* @returns zero if successful, and some negative number on error.
* The error message can be obtained by calling \ref cpuid_error.
* @see cpu_error_t
*/
int cpu_identify_all(struct cpu_raw_data_array_t *raw_array, struct system_id_t* system);
/**
* @brief Returns the short textual representation of a CPU architecture
* @param architecture - the architecture, whose textual representation is wanted.

View file

@ -30,5 +30,6 @@ cpuid_get_vendor
cpu_rdmsr_range
cpuid_get_epc
msr_serialize_raw_data
cpu_identify_all
cpu_architecture_str
cpu_purpose_str