1// Copyright 2017 The Fuchsia Authors
2//
3// Use of this source code is governed by a MIT-style
4// license that can be found in the LICENSE file or at
5// https://opensource.org/licenses/MIT
6
7#include <err.h>
8#include <inttypes.h>
9#include <trace.h>
10
11#include <lib/ktrace.h>
12
13#include <object/handle.h>
14#include <object/process_dispatcher.h>
15#include <object/timer_dispatcher.h>
16
17#include <fbl/alloc_checker.h>
18#include <fbl/ref_ptr.h>
19
20#include <zircon/types.h>
21
22#include "priv.h"
23
24zx_status_t sys_timer_create(uint32_t options, zx_clock_t clock_id,
25                             user_out_handle* out) {
26    if (clock_id != ZX_CLOCK_MONOTONIC)
27        return ZX_ERR_INVALID_ARGS;
28
29    auto up = ProcessDispatcher::GetCurrent();
30    zx_status_t result = up->QueryPolicy(ZX_POL_NEW_TIMER);
31    if (result != ZX_OK)
32        return result;
33
34    fbl::RefPtr<Dispatcher> dispatcher;
35    zx_rights_t rights;
36
37    result = TimerDispatcher::Create(options, &dispatcher, &rights);
38
39    if (result == ZX_OK)
40        result = out->make(fbl::move(dispatcher), rights);
41    return result;
42}
43
44zx_status_t sys_timer_set(
45    zx_handle_t handle, zx_time_t deadline, zx_duration_t slack) {
46    if (slack < 0) {
47        return ZX_ERR_OUT_OF_RANGE;
48    }
49
50    auto up = ProcessDispatcher::GetCurrent();
51
52    fbl::RefPtr<TimerDispatcher> timer;
53    zx_status_t status = up->GetDispatcherWithRights(handle, ZX_RIGHT_WRITE, &timer);
54    if (status != ZX_OK)
55        return status;
56
57    return timer->Set(deadline, slack);
58}
59
60
61zx_status_t sys_timer_cancel(zx_handle_t handle) {
62    auto up = ProcessDispatcher::GetCurrent();
63
64    fbl::RefPtr<TimerDispatcher> timer;
65    zx_status_t status = up->GetDispatcherWithRights(handle, ZX_RIGHT_WRITE, &timer);
66    if (status != ZX_OK)
67        return status;
68
69    return timer->Cancel();
70}
71