diff --git a/cli/ops/timers.rs b/cli/ops/timers.rs index 841cdf289d035..8037fd6982766 100644 --- a/cli/ops/timers.rs +++ b/cli/ops/timers.rs @@ -8,7 +8,11 @@ //! only need to be able to start, cancel and await a single timer (or Delay, as Tokio //! calls it) for an entire Isolate. This is what is implemented here. +use super::dispatch_minimal::minimal_op; +use super::dispatch_minimal::MinimalOp; +use crate::metrics::metrics_op; use crate::permissions::Permissions; +use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::futures; use deno_core::futures::channel::oneshot; @@ -77,7 +81,7 @@ pub fn init(rt: &mut deno_core::JsRuntime) { super::reg_json_sync(rt, "op_global_timer_stop", op_global_timer_stop); super::reg_json_sync(rt, "op_global_timer_start", op_global_timer_start); super::reg_json_async(rt, "op_global_timer", op_global_timer); - super::reg_json_sync(rt, "op_now", op_now); + rt.register_op("op_now", metrics_op(minimal_op(op_now))); super::reg_json_sync(rt, "op_sleep_sync", op_sleep_sync); } @@ -138,26 +142,38 @@ async fn op_global_timer( // If the High precision flag is not set, the // nanoseconds are rounded on 2ms. fn op_now( - state: &mut OpState, - _args: Value, - _zero_copy: &mut [ZeroCopyBuf], -) -> Result { - let start_time = state.borrow::(); + state: Rc>, + // Arguments are discarded + _sync: bool, + _x: i32, + mut zero_copy: BufVec, +) -> MinimalOp { + match zero_copy.len() { + 0 => return MinimalOp::Sync(Err(type_error("no buffer specified"))), + 1 => {} + _ => { + return MinimalOp::Sync(Err(type_error("Invalid number of arguments"))) + } + } + + let op_state = state.borrow(); + let start_time = op_state.borrow::(); let seconds = start_time.elapsed().as_secs(); - let mut subsec_nanos = start_time.elapsed().subsec_nanos(); - let reduced_time_precision = 2_000_000; // 2ms in nanoseconds + let mut subsec_nanos = start_time.elapsed().subsec_nanos() as f64; + let reduced_time_precision = 2_000_000.0; // 2ms in nanoseconds // If the permission is not enabled // Round the nano result on 2 milliseconds // see: https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp#Reduced_time_precision - if state.borrow::().check_hrtime().is_err() { + if op_state.borrow::().check_hrtime().is_err() { subsec_nanos -= subsec_nanos % reduced_time_precision; } - Ok(json!({ - "seconds": seconds, - "subsecNanos": subsec_nanos, - })) + let result = (seconds * 1_000) as f64 + (subsec_nanos / 1_000_000.0); + + (&mut zero_copy[0]).copy_from_slice(&result.to_be_bytes()); + + MinimalOp::Sync(Ok(0)) } #[derive(Deserialize)] diff --git a/cli/rt/11_timers.js b/cli/rt/11_timers.js index c762c59d83f74..5a59844a3306b 100644 --- a/cli/rt/11_timers.js +++ b/cli/rt/11_timers.js @@ -3,6 +3,7 @@ ((window) => { const assert = window.__bootstrap.util.assert; const core = window.Deno.core; + const { sendSync } = window.__bootstrap.dispatchMinimal; function opStopGlobalTimer() { core.jsonOpSync("op_global_timer_stop"); @@ -16,8 +17,10 @@ await core.jsonOpAsync("op_global_timer"); } + const nowBytes = new Uint8Array(8); function opNow() { - return core.jsonOpSync("op_now"); + sendSync("op_now", 0, nowBytes); + return new DataView(nowBytes.buffer).getFloat64(); } function sleepSync(millis = 0) { diff --git a/cli/rt/40_performance.js b/cli/rt/40_performance.js index 3d8be60314607..0a63dc704dfc9 100644 --- a/cli/rt/40_performance.js +++ b/cli/rt/40_performance.js @@ -43,8 +43,7 @@ } function now() { - const res = opNow(); - return res.seconds * 1e3 + res.subsecNanos / 1e6; + return opNow(); } class PerformanceEntry {