Skip to content

Commit

Permalink
feat: RUN-798: Add call context perf counter (#435)
Browse files Browse the repository at this point in the history
* feat: RUN-798: Add call context perf counter

* deprecated note

* improve doc

* fmt

* v0.11.3 and changelog

---------

Co-authored-by: Linwei Shang <linwei.shang@dfinity.org>
  • Loading branch information
dfinity-berestovskyy and lwshang authored Oct 12, 2023
1 parent cf6611b commit cda6077
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 15 deletions.
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

0 comments on commit cda6077

Please sign in to comment.