Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CpuId reader trait and serialize feature fix #140

Merged
merged 17 commits into from
Apr 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/standard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Standard checks

on:
push:
branches: [ master ]
branches: [master]
pull_request:
branches: [ master ]
branches: [master]

jobs:
ci:
Expand Down Expand Up @@ -44,6 +44,7 @@ jobs:
- uses: actions-rs/cargo@v1.0.3
with:
command: test
args: --all-features

- uses: actions-rs/cargo@v1.0.3
with:
Expand Down
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [11.0.0] - 2023-04-17

### Breaking changes

- The `CpuId` type now takes a generic reader argument `CpuId<R: CpuIdReader>`:
which allows for more flexibility on how cpuid is queried and better support
for using the library on non-x86 targets. This is a breaking change for users
of `with_cpuid_fn` and potentially when specifying `CpuId` as a type argument
somewhere. To make existing code compile again, whenever a generic type
argument for CpuId is needed, you can use the `cpuid::NativeCpuIdReader` type
which provides the default behavior of execution the `cpuid` instruction.

For example, in your code there might be cases where the compiler now asks you
to specify the generic type of CpuId: e.g., `fn take_cpuid(cpuid: CpuId)`
would become: `fn take_cpuid(cpuid: CpuId<NativeCpuIdReader>)`

See also [#140](https://github.com/gz/rust-cpuid/pull/140) and
[#138](https://github.com/gz/rust-cpuid/pull/138) for the original discussion.

- If you're using the `serialization` feature: It go revamped by fixing some
long-standing problems with it that made it difficult to use
[#87](https://github.com/gz/rust-cpuid/issues/87). All types except
`CpuIdResult` types lost their `Serialize` and `Deserialize` derives. Check
the [new example](examples/serialize_deserialize.rs) on how to serialize and
deserialize cpuid information.

## [10.7.0] - 2023-02-27

- Include the pretty printing code in the library (instead of only having it in
Expand Down
2 changes: 2 additions & 0 deletions examples/cache.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! Example that displays information about the caches.
//!
//! This example only compiles on x86 platforms.
extern crate raw_cpuid;
use raw_cpuid::{CacheType, CpuId};

Expand Down
2 changes: 2 additions & 0 deletions examples/cpu.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! An example that displays the type/features/configuration of the CPU.
//!
//! This example only compiles on x86 platforms.
extern crate raw_cpuid;

fn main() {
Expand Down
51 changes: 51 additions & 0 deletions examples/serialize_deserialize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//! An example that serializes CpuId state, deserializes it back and passes it to a
//! CpuId instance with a custom reader.
//!
//! Run using:
//! `cargo run --features serialize --features serde_json --example serialize_deserialize`

use raw_cpuid::{CpuId, CpuIdReader, CpuIdResult};
use std::collections::HashMap;

#[derive(Clone)]
struct HashMapCpuIdReader {
ht: HashMap<u64, CpuIdResult>,
}

impl CpuIdReader for HashMapCpuIdReader {
fn cpuid2(&self, eax: u32, ecx: u32) -> CpuIdResult {
let key = (eax as u64) << u32::BITS | ecx as u64;
self.ht
.get(&key)
.unwrap_or(&CpuIdResult {
eax: 0,
ebx: 0,
ecx: 0,
edx: 0,
})
.clone()
}
}

fn main() {
let mut ht = HashMap::new();
ht.insert(
0x00000000_00000000u64,
CpuIdResult {
eax: 0x00000020,
ebx: 0x756e6547,
ecx: 0x6c65746e,
edx: 0x49656e69,
},
);

// Serialize to JSON and back
let cpuid_as_json = serde_json::to_string(&ht).unwrap();
let deserialized_ht: HashMap<u64, CpuIdResult> = serde_json::from_str(&cpuid_as_json).unwrap();

// Create a CpuId instance with a custom reader
let cpuid = CpuId::with_cpuid_reader(HashMapCpuIdReader {
ht: deserialized_ht,
});
assert!(cpuid.get_vendor_info().unwrap().as_str() == "GenuineIntel");
}
2 changes: 2 additions & 0 deletions examples/topology.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
//!
//! Intel Topology is a pretty complicated subject (unfortunately):
//! https://software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration/
//!
//! This example only compiles on x86 platforms.
extern crate core_affinity;
extern crate raw_cpuid;

Expand Down
4 changes: 3 additions & 1 deletion examples/tsc_frequency.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! An example that determines the time stamp counter frequency (RDTSC, RDTSCP) .
//! An example that determines the time stamp counter frequency (RDTSC, RDTSCP).
//!
//! This example only compiles on x86 platforms.
extern crate raw_cpuid;

use std::time;
Expand Down
13 changes: 5 additions & 8 deletions src/bin/cpuid.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! The cpuid binary accompanying the library.
//!
//! The cpuid binary only compiles/runs on x86 platforms.
use std::str::FromStr;

use clap::Parser;
use raw_cpuid::CpuId;
use raw_cpuid::{CpuId, CpuIdReaderNative};

enum OutputFormat {
Raw,
Json,
Cli,
}

Expand All @@ -15,7 +17,6 @@ impl FromStr for OutputFormat {
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"raw" => Ok(OutputFormat::Raw),
"json" => Ok(OutputFormat::Json),
"cli" => Ok(OutputFormat::Cli),
_ => Err("no match"),
}
Expand All @@ -35,11 +36,7 @@ struct Opts {
fn main() {
let opts: Opts = Opts::parse();
match opts.format {
OutputFormat::Raw => raw_cpuid::display::raw(),
OutputFormat::Json => {
let cpuid = CpuId::new();
raw_cpuid::display::json(cpuid);
}
OutputFormat::Raw => raw_cpuid::display::raw(CpuIdReaderNative),
OutputFormat::Cli => {
let cpuid = CpuId::new();
raw_cpuid::display::markdown(cpuid);
Expand Down
Loading