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

feat: RUN-798: Add call context perf counter #435

Merged
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
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ opt-level = 'z'

[workspace.dependencies]
ic0 = { path = "src/ic0", version = "0.21.1" }
ic-cdk = { path = "src/ic-cdk", version = "0.11.2" }
ic-cdk = { path = "src/ic-cdk", version = "0.11.3" }
ic-cdk-timers = { path = "src/ic-cdk-timers", version = "0.5.1" }

candid = "0.9.6"
Expand Down
13 changes: 13 additions & 0 deletions src/ic-cdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [unreleased]

## [0.11.3] - 2023-10-12

### Added

- Another type of performance counter: "call context instruction counter".
Can be fetched using either method below: (#435)
- `ic_cdk::api::performance_counter(1)`;
- `ic_cdk::api::call_context_instruction_counter()` as a shorthand;

### Changed

- Deprecate `ic_cdk::api::call::performance_counter()` in favor of `ic_cdk::api::performance_counter()`. (#435)

## [0.11.2] - 2023-10-11

### Added
Expand Down
2 changes: 1 addition & 1 deletion src/ic-cdk/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ic-cdk"
version = "0.11.2"
version = "0.11.3"
authors.workspace = true
edition.workspace = true
license.workspace = true
Expand Down
11 changes: 7 additions & 4 deletions src/ic-cdk/src/api/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ pub fn arg_data_raw() -> Vec<u8> {
bytes
}

/// Get the len of the raw-argument-data-bytes.
/// Gets the len of the raw-argument-data-bytes.
pub fn arg_data_raw_size() -> usize {
// SAFETY: ic0.msg_arg_data_size is always safe to call.
unsafe { ic0::msg_arg_data_size() as usize }
Expand Down Expand Up @@ -577,10 +577,13 @@ pub fn method_name() -> String {
String::from_utf8_lossy(&bytes).into_owned()
}

/// Get the value of specified performance counter
/// Gets the value of specified performance counter
///
/// Supported counter type:
/// 0 : instruction counter. The number of WebAssembly instructions the system has determined that the canister has executed.
/// See [`crate::api::performance_counter`].
#[deprecated(
since = "0.11.3",
note = "This method conceptually doesn't belong to this module. Please use `ic_cdk::api::performance_counter` instead."
)]
pub fn performance_counter(counter_type: u32) -> u64 {
// SAFETY: ic0.performance_counter is always safe to call.
unsafe { ic0::performance_counter(counter_type as i32) as u64 }
Expand Down
34 changes: 26 additions & 8 deletions src/ic-cdk/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub fn trap(message: &str) -> ! {
unreachable!()
}

/// Get current timestamp, in nanoseconds since the epoch (1970-01-01)
/// Gets current timestamp, in nanoseconds since the epoch (1970-01-01)
pub fn time() -> u64 {
// SAFETY: ic0.time is always safe to call.
unsafe { ic0::time() as u64 }
Expand Down Expand Up @@ -54,13 +54,13 @@ pub fn id() -> Principal {
Principal::try_from(&bytes).unwrap()
}

/// Get the amount of funds available in the canister.
/// Gets the amount of funds available in the canister.
pub fn canister_balance() -> u64 {
// SAFETY: ic0.canister_cycle_balance is always safe to call.
unsafe { ic0::canister_cycle_balance() as u64 }
}

/// Get the amount of funds available in the canister.
/// Gets the amount of funds available in the canister.
pub fn canister_balance128() -> u128 {
let mut recv = 0u128;
// SAFETY: recv is writable and the size expected by ic0.canister_cycle_balance128.
Expand Down Expand Up @@ -118,23 +118,41 @@ pub fn instruction_counter() -> u64 {
performance_counter(0)
}

/// Get the value of specified performance counter.
/// Returns the number of WebAssembly instructions the canister has executed
/// within the call context of the current Message execution since
/// Call context creation.
///
/// Supported counter type:
/// 0 : instruction counter. The number of WebAssembly instructions the system has determined that the canister has executed.
/// The counter monotonically increases across all message executions
/// in the call context until the corresponding call context is removed.
#[inline]
pub fn call_context_instruction_counter() -> u64 {
performance_counter(1)
}

/// Gets the value of specified performance counter.
///
/// Supported counter types:
/// * `0` : current execution instruction counter. The number of WebAssembly
/// instructions the canister has executed since the beginning of the
/// current Message execution.
/// * `1` : call context instruction counter. The number of WebAssembly
/// instructions the canister has executed within the call context
/// of the current Message execution since Call context creation.
/// The counter monotonically increases across all message executions
/// in the call context until the corresponding call context is removed.
#[inline]
pub fn performance_counter(counter_type: u32) -> u64 {
// SAFETY: ic0.performance_counter is always safe to call.
unsafe { ic0::performance_counter(counter_type as i32) as u64 }
}

/// Get the value of canister version.
/// Gets the value of canister version.
pub fn canister_version() -> u64 {
// SAFETY: ic0.canister_version is always safe to call.
unsafe { ic0::canister_version() as u64 }
}

/// Determine if a Principal is a controller of the canister.
/// Determines if a Principal is a controller of the canister.
pub fn is_controller(principal: &Principal) -> bool {
let slice = principal.as_slice();
// SAFETY: `principal.as_bytes()`, being `&[u8]`, is a readable sequence of bytes and therefore safe to pass to `ic0.is_controller`.
Expand Down