1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <vector>
6
7 #include <fbl/string_printf.h>
8 #include <lib/zx/timer.h>
9 #include <perftest/perftest.h>
10
11 namespace {
12
13 struct TimerState {
14 zx::duration wait_time;
15 zx::duration slack_time;
16 };
17
SlackTypeToString(uint32_t slack_type)18 const char* SlackTypeToString(uint32_t slack_type) {
19 switch (slack_type) {
20 case ZX_TIMER_SLACK_LATE:
21 return "SlackLate";
22 case ZX_TIMER_SLACK_EARLY:
23 return "SlackEarly";
24 case ZX_TIMER_SLACK_CENTER:
25 return "SlackCenter";
26 default:
27 ZX_ASSERT_MSG(true, "Slack type unsupported\n");
28 return nullptr;
29 }
30 }
31
32 // Measures how long a timer takes to fire based on the wait time, slack time,
33 // and slack type. This can be useful for measuring the overhead of sleeping.
34 // It can also be used to measure the variation in actual sleep times.
TimerWaitTest(perftest::RepeatState * state,TimerState timer_state,uint32_t slack_type)35 bool TimerWaitTest(perftest::RepeatState* state, TimerState timer_state, uint32_t slack_type) {
36 zx_status_t status;
37 zx::timer timer;
38
39 status = zx::timer::create(slack_type, ZX_CLOCK_MONOTONIC, &timer);
40 ZX_ASSERT(status == ZX_OK);
41
42 while (state->KeepRunning()) {
43 status = timer.set(zx::deadline_after(timer_state.wait_time),
44 timer_state.slack_time);
45 ZX_ASSERT(status == ZX_OK);
46 zx_status_t status = timer.wait_one(
47 ZX_TIMER_SIGNALED, zx::time::infinite(), nullptr);
48 ZX_ASSERT(status == ZX_OK);
49 }
50
51 return true;
52 }
53
RegisterTests()54 void RegisterTests() {
55 const TimerState timers[] = {
56 TimerState{zx::msec(1), zx::usec(0)},
57 TimerState{zx::msec(1), zx::usec(500)}};
58 const uint32_t slack_types[] = {ZX_TIMER_SLACK_LATE,
59 ZX_TIMER_SLACK_EARLY, ZX_TIMER_SLACK_CENTER};
60
61 for (auto timer : timers) {
62 for (auto slack_type : slack_types) {
63 auto name = fbl::StringPrintf("Timer/%lumsWait/%s%luus",
64 timer.wait_time.to_msecs(),
65 SlackTypeToString(slack_type),
66 timer.slack_time.to_usecs());
67 perftest::RegisterTest(name.c_str(), TimerWaitTest, timer, slack_type);
68 }
69 }
70 }
71 PERFTEST_CTOR(RegisterTests);
72
73 } // namespace
74