[clock] Introduce zx_clock_get_new to eventually supplant zx_clock_get
zx_clock_get is problematic in that it cannot report an error,
specifically when an invalid clock id is provided. We will migrate
users to zx_clock_get_new, and then rename zx_clock_get_new to
zx_clock_get.
ZX-2187
Change-Id: Ic5546c286431c4937263e3183bc7f76566f194b8
diff --git a/docs/syscalls/clock_get.md b/docs/syscalls/clock_get.md
index 2a5e1c9..bd87787 100644
--- a/docs/syscalls/clock_get.md
+++ b/docs/syscalls/clock_get.md
@@ -9,7 +9,8 @@
```
#include <zircon/syscalls.h>
-zx_time_t zx_clock_get(uint32_t clock_id)
+zx_time_t zx_clock_get(uint32_t clock_id);
+zx_status_t zx_clock_get(uint32_t clock_id, zx_time_t* out_time);
```
## DESCRIPTION
@@ -17,6 +18,9 @@
**zx_clock_get**() returns the current time of *clock_id*, or 0 if *clock_id* is
invalid.
+**zx_clock_get_new** returns the current time of *clock_id* via
+ *out_time*, and returns whether *clock_id* was valid.
+
## SUPPORTED CLOCK IDS
*ZX_CLOCK_MONOTONIC* number of nanoseconds since the system was powered on.
@@ -29,6 +33,10 @@
On success, **zx_clock_get**() returns the current time according to the given clock ID.
+On success, **zx_clock_get_new**() returns *ZX_OK*.
+
## ERRORS
On error, **zx_clock_get**() currently returns 0.
+
+**ZX_ERR_INVALID_ARGS** *clock_id* is not a valid clock id, or *out_time* is an invalid pointer.
diff --git a/kernel/syscalls/zircon.cpp b/kernel/syscalls/zircon.cpp
index 44abe03..ceb62f6 100644
--- a/kernel/syscalls/zircon.cpp
+++ b/kernel/syscalls/zircon.cpp
@@ -62,7 +62,7 @@
// update pvclock too.
fbl::atomic<int64_t> utc_offset;
-uint64_t sys_clock_get(uint32_t clock_id) {
+zx_time_t sys_clock_get(uint32_t clock_id) {
switch (clock_id) {
case ZX_CLOCK_MONOTONIC:
return current_time();
@@ -76,6 +76,25 @@
}
}
+zx_status_t sys_clock_get_new(uint32_t clock_id, user_out_ptr<zx_time_t> out_time) {
+ zx_time_t time;
+ switch (clock_id) {
+ case ZX_CLOCK_MONOTONIC:
+ time = current_time();
+ break;
+ case ZX_CLOCK_UTC:
+ time = current_time() + utc_offset.load();
+ break;
+ case ZX_CLOCK_THREAD:
+ time = ThreadDispatcher::GetCurrent()->runtime_ns();
+ break;
+ default:
+ return ZX_ERR_INVALID_ARGS;
+ }
+
+ return out_time.copy_to_user(time);
+}
+
zx_status_t sys_clock_adjust(zx_handle_t hrsrc, uint32_t clock_id, int64_t offset) {
// TODO(ZX-971): finer grained validation
zx_status_t status;
diff --git a/system/public/zircon/syscalls.abigen b/system/public/zircon/syscalls.abigen
index 3268afb..4f8f47b 100644
--- a/system/public/zircon/syscalls.abigen
+++ b/system/public/zircon/syscalls.abigen
@@ -53,6 +53,10 @@
(clock_id: uint32_t)
returns (zx_time_t);
+syscall clock_get_new
+ (clock_id: uint32_t)
+ returns (zx_status_t, out: zx_time_t);
+
syscall nanosleep blocking
(deadline: zx_time_t)
returns (zx_status_t);