Skip to content

Commit

Permalink
wasi: support monotonic clock on clock_time_get. (#156)
Browse files Browse the repository at this point in the history
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
  • Loading branch information
mathetake authored May 6, 2021
1 parent 5791899 commit 31c75e0
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 4 deletions.
13 changes: 13 additions & 0 deletions include/proxy-wasm/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,19 @@ class ContextBase : public RootInterface,
#else
unimplemented();
return 0;
#endif
}
uint64_t getMonotonicTimeNanoseconds() override {
#if !defined(_MSC_VER)
struct timespec tpe;
clock_gettime(CLOCK_MONOTONIC, &tpe);
uint64_t t = tpe.tv_sec;
t *= 1000000000;
t += tpe.tv_nsec;
return t;
#else
unimplemented();
return 0;
#endif
}
std::string_view getConfiguration() override {
Expand Down
3 changes: 3 additions & 0 deletions include/proxy-wasm/context_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,9 @@ struct GeneralInterface {
// Provides the current time in nanoseconds since the Unix epoch.
virtual uint64_t getCurrentTimeNanoseconds() = 0;

// Provides the monotonic time in nanoseconds.
virtual uint64_t getMonotonicTimeNanoseconds() = 0;

// Returns plugin configuration.
virtual std::string_view getConfiguration() = 0;

Expand Down
15 changes: 11 additions & 4 deletions src/exports.cc
Original file line number Diff line number Diff line change
Expand Up @@ -833,12 +833,19 @@ Word wasi_unstable_args_sizes_get(void *raw_context, Word argc_ptr, Word argv_bu
Word wasi_unstable_clock_time_get(void *raw_context, Word clock_id, uint64_t precision,
Word result_time_uint64_ptr) {

if (clock_id != 0 /* realtime */) {
uint64_t result = 0;
auto context = WASM_CONTEXT(raw_context);
switch (clock_id) {
case 0 /* realtime */:
result = context->getCurrentTimeNanoseconds();
break;
case 1 /* monotonic */:
result = context->getMonotonicTimeNanoseconds();
break;
default:
// process_cputime_id and thread_cputime_id are not supported yet.
return 58; // __WASI_ENOTSUP
}

auto context = WASM_CONTEXT(raw_context);
uint64_t result = context->getCurrentTimeNanoseconds();
if (!context->wasm()->setDatatype(result_time_uint64_ptr, result)) {
return 21; // __WASI_EFAULT
}
Expand Down
1 change: 1 addition & 0 deletions test/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ cc_test(
srcs = ["exports_test.cc"],
copts = COPTS,
data = [
"//test/test_data:clock.wasm",
"//test/test_data:env.wasm",
],
linkopts = LINKOPTS,
Expand Down
23 changes: 23 additions & 0 deletions test/exports_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,28 @@ TEST_P(TestVM, WithoutEnvironment) {
EXPECT_EQ(context.log_msg(), "");
}

TEST_P(TestVM, Clock) {
initialize("clock.wasm");
auto wasm_base = WasmBase(std::move(vm_), "vm_id", "", "", {}, {});
ASSERT_TRUE(wasm_base.wasm_vm()->load(source_, false));

TestContext context(&wasm_base);
current_context_ = &context;

wasm_base.registerCallbacks();

ASSERT_TRUE(wasm_base.wasm_vm()->link(""));

WasmCallVoid<0> run;
wasm_base.wasm_vm()->getFunction("run", &run);
ASSERT_TRUE(run);
run(current_context_);

// Check logs.
auto msg = context.log_msg();
EXPECT_NE(std::string::npos, msg.find("monotonic: ")) << msg;
EXPECT_NE(std::string::npos, msg.find("realtime: ")) << msg;
}

} // namespace
} // namespace proxy_wasm
6 changes: 6 additions & 0 deletions test/test_data/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ wasm_rust_binary(
srcs = ["env.rs"],
wasi = True,
)

wasm_rust_binary(
name = "clock.wasm",
srcs = ["clock.rs"],
wasi = True,
)
21 changes: 21 additions & 0 deletions test/test_data/clock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::time::{Instant, SystemTime};

#[no_mangle]
pub extern "C" fn run() {
println!("monotonic: {:?}", Instant::now());
println!("realtime: {:?}", SystemTime::now());
}

0 comments on commit 31c75e0

Please sign in to comment.