| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| library zx; |
| |
| // TODO(scottmg): These syscalls don't match the general naming convention of |
| // zx_something_name(), they're just zx_name(), so NoProtocolPrefix tells the |
| // generator to exclude putting "Misc" in the name. |
| @transport("Syscall") |
| @no_protocol_prefix |
| closed protocol Misc { |
| /// ## Summary |
| /// |
| /// High resolution sleep. |
| /// |
| /// ## Declaration |
| /// |
| /// ```c |
| /// #include <zircon/syscalls.h> |
| /// |
| /// zx_status_t zx_nanosleep(zx_instant_mono_t deadline); |
| /// ``` |
| /// |
| /// ## Description |
| /// |
| /// `zx_nanosleep()` suspends the calling thread execution until *deadline* passes |
| /// on `ZX_CLOCK_MONOTONIC`. *deadline* will be automatically adjusted according to the job's |
| /// [timer slack] policy. |
| /// |
| /// To sleep for a duration, use [`zx_deadline_after()`] and the |
| /// `ZX_\<time-unit\>` helpers: |
| /// |
| /// ```c |
| /// #include <zircon/syscalls.h> // zx_deadline_after, zx_nanosleep |
| /// #include <zircon/types.h> // ZX_MSEC et al. |
| /// |
| /// // Sleep 50 milliseconds |
| /// zx_nanosleep(zx_deadline_after(ZX_MSEC(50))); |
| /// ``` |
| /// |
| /// ## Rights |
| /// |
| /// None. |
| /// |
| /// ## Return value |
| /// |
| /// `zx_nanosleep()` always returns `ZX_OK`. |
| /// |
| /// ## See also |
| /// |
| /// - [timer slack] |
| /// - [`zx_deadline_after()`] |
| /// - [`zx_timer_cancel()`] |
| /// - [`zx_timer_create()`] |
| /// - [`zx_timer_set()`] |
| /// |
| /// [timer slack]: /docs/concepts/kernel/timer_slack.md |
| /// [`zx_deadline_after()`]: deadline_after.md |
| /// [`zx_timer_cancel()`]: timer_cancel.md |
| /// [`zx_timer_create()`]: timer_create.md |
| /// [`zx_timer_set()`]: timer_set.md |
| @blocking |
| strict Nanosleep(struct { |
| deadline InstantMono; |
| }) -> () error Status; |
| |
| /// ## Summary |
| /// |
| /// Read the number of high-precision timer ticks since boot, not including |
| /// time spent suspended. |
| /// |
| /// ## Declaration |
| /// |
| /// ```c |
| /// #include <zircon/syscalls.h> |
| /// |
| /// zx_instant_mono_ticks_t zx_ticks_get(void); |
| /// ``` |
| /// |
| /// ## Description |
| /// |
| /// `zx_ticks_get()` returns the number of high-precision timer ticks since boot, |
| /// not including time spent suspended. |
| /// |
| /// These ticks may be processor cycles, high speed timer, profiling timer, etc. |
| /// They are not guaranteed to continue advancing when the system is asleep. |
| /// |
| /// ## Rights |
| /// |
| /// TODO(https://fxbug.dev/42107318) |
| /// |
| /// ## Return value |
| /// |
| /// `zx_ticks_get()` returns the number of high-precision timer ticks since boot. |
| /// |
| /// ## Errors |
| /// |
| /// `zx_ticks_get()` does not report any error conditions. |
| /// |
| /// ## Notes |
| /// |
| /// The returned value may be highly variable. Factors that can affect it include: |
| /// |
| /// - System sleep/wake (post implementation of |
| /// [RFC-0230](https://fuchsia.dev/fuchsia-src/contribute/governance/rfcs/0230_suspend_to_idle)) |
| /// - Reset of the processor cycle counter |
| /// - Reordering of instructions (if required, use a memory barrier) |
| /// |
| /// All Fuchsia systems use an invariant-rate ticks clock, which means that the |
| /// number of ticks per second is constant regardless of changes in processor |
| /// speed or migration between processors. |
| /// |
| /// ## See also |
| /// |
| /// [ticks_per_second](ticks_per_second.md) |
| @vdsocall |
| strict TicksGet() -> (@wrapped_return struct { |
| ticks InstantMonoTicks; |
| }); |
| |
| /// ## Summary |
| /// |
| /// Read the number of high-precision timer ticks since boot, including any time spent in a |
| /// suspended state. |
| /// |
| /// ## Declaration |
| /// |
| /// ```c |
| /// #include <zircon/syscalls.h> |
| /// |
| /// zx_instant_boot_ticks_t zx_ticks_get_boot(void); |
| /// ``` |
| /// |
| /// ## Description |
| /// |
| /// `zx_ticks_get_boot()` returns the number of high-precision timer ticks since boot, |
| /// including any time spent in a suspended state. |
| /// |
| /// These ticks may be processor cycles, high speed timer, profiling timer, etc. |
| /// |
| /// ## Rights |
| /// |
| /// None. |
| /// |
| /// ## Return value |
| /// |
| /// `zx_ticks_get_boot()` returns the number of high-precision timer ticks since boot. |
| /// |
| /// ## Errors |
| /// |
| /// `zx_ticks_get_boot()` does not report any error conditions. |
| /// |
| /// ## Notes |
| /// |
| /// The returned value may be highly variable. Factors that can affect it include: |
| /// |
| /// - Reset of the processor cycle counter |
| /// - Reordering of instructions (if required, use a memory barrier) |
| /// |
| /// All Fuchsia systems use an invariant-rate ticks clock, which means that the |
| /// number of ticks per second is constant regardless of changes in processor |
| /// speed or migration between processors. |
| /// |
| /// ## See also |
| /// |
| /// [ticks_per_second](ticks_per_second.md) |
| @vdsocall |
| strict TicksGetBoot() -> (@wrapped_return struct { |
| ticks InstantBootTicks; |
| }); |
| |
| /// ## Summary |
| /// |
| /// Read the number of high-precision timer ticks in a second. |
| /// |
| /// ## Declaration |
| /// |
| /// ```c |
| /// #include <zircon/syscalls.h> |
| /// |
| /// zx_ticks_t zx_ticks_per_second(void); |
| /// ``` |
| /// |
| /// ## Description |
| /// |
| /// `zx_ticks_per_second()` returns the number of high-precision timer ticks in a |
| /// second. |
| /// |
| /// This can be used together with [`zx_ticks_get()`] to calculate the amount of |
| /// time elapsed between two subsequent calls to [`zx_ticks_get()`]. |
| /// |
| /// This value can vary from boot to boot of a given system. Once booted, |
| /// this value is guaranteed not to change. |
| /// |
| /// ## Rights |
| /// |
| /// TODO(https://fxbug.dev/42107318) |
| /// |
| /// ## Return value |
| /// |
| /// `zx_ticks_per_second()` returns the number of high-precision timer ticks in a |
| /// second. |
| /// |
| /// ## Errors |
| /// |
| /// `zx_ticks_per_second()` does not report any error conditions. |
| /// |
| /// ## EXAMPLES |
| /// |
| /// ```c |
| /// zx_ticks_t ticks_per_second = zx_ticks_per_second(); |
| /// zx_instant_mono_ticks_t ticks_start = zx_ticks_get(); |
| /// |
| /// // do some more work |
| /// |
| /// zx_instant_mono_ticks_t ticks_end = zx_ticks_get(); |
| /// double elapsed_seconds = (ticks_end - ticks_start) / (double)ticks_per_second; |
| /// ``` |
| /// |
| /// ## See also |
| /// |
| /// - [`zx_ticks_get()`] |
| /// |
| /// [`zx_ticks_get()`]: ticks_get.md |
| @const |
| @vdsocall |
| strict TicksPerSecond() -> (@wrapped_return struct { |
| ticks Ticks; |
| }); |
| |
| /// ## Summary |
| /// |
| /// Convert a time relative to now to an absolute deadline. |
| /// |
| /// ## Declaration |
| /// |
| /// ```c |
| /// #include <zircon/syscalls.h> |
| /// |
| /// zx_instant_mono_t zx_deadline_after(zx_duration_mono_t nanoseconds); |
| /// ``` |
| /// |
| /// ## Description |
| /// |
| /// `zx_deadline_after()` is a utility for converting from now-relative durations |
| /// to absolute deadlines. If *nanoseconds* plus the current time is bigger than the |
| /// maximum value for `zx_instant_mono_t`, the output is clamped to `ZX_TIME_INFINITE`. |
| /// |
| /// ## Rights |
| /// |
| /// TODO(https://fxbug.dev/42107318) |
| /// |
| /// ## Return value |
| /// |
| /// `zx_deadline_after()` returns the absolute time (with respect to `ZX_CLOCK_MONOTONIC`) |
| /// that is *nanoseconds* nanoseconds from now. |
| /// |
| /// ## Errors |
| /// |
| /// `zx_deadline_after()` does not report any error conditions. |
| /// |
| /// ## EXAMPLES |
| /// |
| /// ```c |
| /// // Sleep 50 milliseconds |
| /// zx_instant_mono_t deadline = zx_deadline_after(ZX_MSEC(50)); |
| /// zx_nanosleep(deadline); |
| /// ``` |
| /// |
| /// ## See also |
| /// |
| /// [ticks_get](ticks_get.md) |
| @vdsocall |
| strict DeadlineAfter(struct { |
| nanoseconds DurationMono; |
| }) -> (@wrapped_return struct { |
| time InstantMono; |
| }); |
| |
| /// ## Summary |
| /// |
| /// Unmap memory, close handle, exit. |
| /// |
| /// ## Declaration |
| /// |
| /// ```c |
| /// #include <zircon/syscalls.h> |
| /// |
| /// zx_status_t zx_vmar_unmap_handle_close_thread_exit(zx_handle_t vmar_handle, |
| /// zx_vaddr_t addr, |
| /// size_t size, |
| /// zx_handle_t close_handle); |
| /// ``` |
| /// |
| /// ## Description |
| /// |
| /// `zx_vmar_unmap_handle_close_thread_exit()` does a sequence of three operations: |
| /// |
| /// 1. `zx_vmar_unmap(vmar_handle, addr, size)` |
| /// 2. `zx_handle_close(close_handle)` |
| /// 3. `zx_thread_exit()` |
| /// |
| /// The expectation is that the first operation unmaps a region including the |
| /// calling thread's own stack. (It's not required, but it's permitted.) This |
| /// is valid for this call, though it would be invalid for [`zx_vmar_unmap()`] or |
| /// any other call. |
| /// |
| /// If the [`zx_vmar_unmap()`] operation is successful, then this call never returns. |
| /// If *close_handle* is an invalid handle so that the [`zx_handle_close()`] operation |
| /// fails, then the thread takes a trap (as if by `__builtin_trap();`). |
| /// |
| /// ## Rights |
| /// |
| /// TODO(https://fxbug.dev/42107318) |
| /// |
| /// ## Return value |
| /// |
| /// `zx_vmar_unmap_handle_close_thread_exit()` does not return on success. |
| /// |
| /// ## Errors |
| /// |
| /// Same as [`zx_vmar_unmap()`]. |
| /// |
| /// ## Notes |
| /// |
| /// The intended use for this is for a dying thread to unmap its own stack, |
| /// close its own thread handle, and exit. The thread handle cannot be closed |
| /// beforehand because closing the last handle to a thread kills that thread. |
| /// The stack cannot be unmapped beforehand because the thread must have some |
| /// stack space on which to make its final system calls. |
| /// |
| /// This call is used for detached threads, while |
| /// [`zx_futex_wake_handle_close_thread_exit()`] |
| /// is used for joinable threads. |
| /// |
| /// ## See also |
| /// |
| /// - [`zx_futex_wake_handle_close_thread_exit()`] |
| /// - [`zx_handle_close()`] |
| /// - [`zx_thread_exit()`] |
| /// - [`zx_vmar_unmap()`] |
| /// |
| /// [`zx_futex_wake_handle_close_thread_exit()`]: futex_wake_handle_close_thread_exit.md |
| /// [`zx_handle_close()`]: handle_close.md |
| /// [`zx_thread_exit()`]: thread_exit.md |
| /// [`zx_vmar_unmap()`]: vmar_unmap.md |
| @vdsocall |
| strict VmarUnmapHandleCloseThreadExit(resource struct { |
| vmar_handle Handle:VMAR; |
| addr Vaddr; |
| size usize64; |
| @release |
| close_handle Handle; |
| }) -> () error Status; |
| |
| /// ## Summary |
| /// |
| /// Write to futex, wake futex, close handle, exit. |
| /// |
| /// ## Declaration |
| /// |
| /// ```c |
| /// #include <zircon/syscalls.h> |
| /// |
| /// [[noreturn]] void zx_futex_wake_handle_close_thread_exit( |
| /// const zx_futex_t* value_ptr, |
| /// uint32_t wake_count, |
| /// int32_t new_value, |
| /// zx_handle_t close_handle); |
| /// ``` |
| /// |
| /// ## Description |
| /// |
| /// `zx_futex_wake_handle_close_thread_exit()` does a sequence of four operations: |
| /// |
| /// 1. `atomic_store_explicit(value_ptr, new_value, memory_order_release);` |
| /// 2. `zx_futex_wake(value_ptr, wake_count);` |
| /// 3. `zx_handle_close(close_handle);` |
| /// 4. `zx_thread_exit();` |
| /// |
| /// The expectation is that as soon as the first operation completes, |
| /// other threads may unmap or reuse the memory containing the calling |
| /// thread's own stack. This is valid for this call, though it would be |
| /// invalid for plain [`zx_futex_wake()`] or any other call. |
| /// |
| /// If any of the operations fail, then the thread takes a trap (as if by `__builtin_trap();`). |
| /// |
| /// ## Rights |
| /// |
| /// TODO(https://fxbug.dev/42107318) |
| /// |
| /// ## Return value |
| /// |
| /// `zx_futex_wake_handle_close_thread_exit()` does not return. |
| /// |
| /// ## Errors |
| /// |
| /// None. |
| /// |
| /// ## Notes |
| /// |
| /// The intended use for this is for a dying thread to alert another thread |
| /// waiting for its completion, close its own thread handle, and exit. |
| /// The thread handle cannot be closed beforehand because closing the last |
| /// handle to a thread kills that thread. The write to *value_ptr* can't be |
| /// done before this call because any time after the write, a joining thread might |
| /// reuse or deallocate this thread's stack, which may cause issues with calling |
| /// conventions into this function. |
| /// |
| /// This call is used for joinable threads, while |
| /// [`zx_vmar_unmap_handle_close_thread_exit()`] |
| /// is used for detached threads. |
| /// |
| /// ## See also |
| /// |
| /// - [futex objects] |
| /// - [`zx_futex_wake()`] |
| /// - [`zx_handle_close()`] |
| /// - [`zx_thread_exit()`] |
| /// - [`zx_vmar_unmap_handle_close_thread_exit()`] |
| /// |
| /// [futex objects]: /docs/reference/kernel_objects/futex.md |
| /// [`zx_futex_wake()`]: futex_wake.md |
| /// [`zx_handle_close()`]: handle_close.md |
| /// [`zx_thread_exit()`]: thread_exit.md |
| /// [`zx_vmar_unmap_handle_close_thread_exit()`]: vmar_unmap_handle_close_thread_exit.md |
| @noreturn |
| @vdsocall |
| strict FutexWakeHandleCloseThreadExit(resource struct { |
| @embedded_alias("zx/Futex") |
| value_ptr experimental_pointer<Futex>; |
| wake_count uint32; |
| new_value int32; |
| @release |
| close_handle Handle; |
| }); |
| |
| // Read the number of high-precision timer ticks since boot, but demand |
| // that the read be performed using a syscall, instead of a vdso call. |
| // |
| // Note that this is an internal syscall, not meant to be used by |
| // application code. By default, the vdso version of this syscall will do |
| // the proper thing, either directly reading from the hardware register |
| // backing the tick counter, or by making a syscall if the register is not |
| // accessible from user mode code (for whatever reason). |
| @internal |
| strict TicksGetViaKernel() -> (@wrapped_return struct { |
| ticks InstantMonoTicks; |
| }); |
| |
| // Read the number of high-precision timer ticks since boot including any |
| // time spent suspended, but demand that the read be performed using a |
| // syscall, instead of a vdso call. |
| // |
| // Note that this is an internal syscall, not meant to be used by |
| // application code. By default, the vdso version of this syscall will do |
| // the proper thing, either directly reading from the hardware register |
| // backing the tick counter, or by making a syscall if the register is not |
| // accessible from user mode code (for whatever reason). |
| @internal |
| strict TicksGetBootViaKernel() -> (@wrapped_return struct { |
| ticks InstantBootTicks; |
| }); |
| }; |