Skip to content

Commit 114a9f5

Browse files
committed
sched: Add documentation for HRTimer.
This commit added documentation for HRTimer. Signed-off-by: ouyangxiangzhen <[email protected]>
1 parent aecacaa commit 114a9f5

File tree

1 file changed

+188
-60
lines changed

1 file changed

+188
-60
lines changed

Documentation/reference/os/time_clock.rst

Lines changed: 188 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -665,87 +665,215 @@ require nanosecond-level task timing, which tick-based timers
665665
like wdog cannot provide. Reducing the tick interval to micro-
666666
or nanoseconds is impractical, as it would overload the CPU with interrupts.
667667
668-
To address this, NuttX provides a high-resolution timer (hrtimer),
669-
which delivers true nanosecond-level precision. Unlike wdog’s list-based timers,
670-
hrtimer uses a red-black tree for efficient management of large numbers of timers,
671-
an important advantage in hard real-time systems like vehicle control.
672-
673-
A user can register an hrtimer callback to execute after a specified delay.
674-
The callback runs in the timer interrupt context, so only limited NuttX interfaces
675-
are available, such as ``mq_send()``, ``sigqueue()``, ``nxevent_post()``, or ``kill()``,
676-
to communicate with tasks.
677-
678-
- :c:func:`hrtimer_init`
679-
- :c:func:`hrtimer_cancel`
680-
- :c:func:`hrtimer_cancel_sync`
681-
- :c:func:`hrtimer_start`
682-
- High-resolution Timer Callback
683-
684-
.. c:function:: void hrtimer_init(FAR hrtimer_t *hrtimer, hrtentry_t func, \
685-
FAR void *arg)
686-
687-
This function initializes a high-resolution timer instance.
688-
Sets the expiration callback and its argument. The timer is
689-
not started by this function.
690-
691-
:param hrtimer: Pointer to hrtimer instance
668+
High-resolution Timer (HRTimer) is a timer abstraction capable of achieving
669+
nanosecond-level timing resolution, primarily used in scenarios requiring
670+
high-resolution clock events. With the advancement of integrated circuit
671+
technology, modern high-resolution timer hardware, such as the typical x86
672+
HPET, can already meet sub-nanosecond timing requirements and offer
673+
femtosecond-level jitter control.
674+
675+
Although the current hardware timer abstraction (`up_alarm/up_timer`)
676+
in the NuttX kernel already supports nanosecond-level timing, its software
677+
timer abstraction, wdog, and the timer timeout interrupt handling process
678+
remain at microsecond-level (tick) resolution, which falls short of
679+
high-resolution timing demands. Therefore, it is necessary to implement a
680+
new timer abstraction, HRTimer, to address the resolution limitations of
681+
wdog. HRTimer primarily provides the following functional interfaces:
682+
683+
**Set a timer in nanoseconds**: Configure a software timer to trigger at
684+
a specified nanosecond time.
685+
686+
**Cancel a timer**: Cancel the software timer.
687+
688+
**Handle timer timeout**: Execute timeout processing after the timer event
689+
is triggered.
690+
691+
The new NuttX HRTimer is designed to address the issues of insufficient
692+
resolution in the current NuttX wdog. It draws on the strengths of the Linux
693+
HRTimer design while improving upon its weaknesses.
694+
The HRTimer design is divided into two parts: the `HRTimer Queue` and the
695+
`HRTimer`. The `HRTimer Queue` is a reusable component that allows users to
696+
freely customize their own `HRTimer` interface by pairing it with a private
697+
timer driver, without needing to modify the kernel code.
698+
699+
The HRTimer Queue is a zero-performance-overhead, composable, and
700+
customizable abstraction that provides only asynchronous-style interfaces:
701+
702+
**hrtimer_queue_start(queue, timer)**: Asynchronously sends an HRTimer to
703+
HRTimer queue.
704+
705+
**hrtimer_queue_async_cancel(queue, timer)**:
706+
Asynchronously cancels anHRTimer and returns the current reference count
707+
of the timer.
708+
709+
**hrtimer_queue_wait(queue, timer)**:
710+
Waits for the release of all references to the HRTimer to obtain ownership
711+
of the HRTimer data structure.
712+
713+
All other user interfaces can be composed based on these three interfaces.
714+
715+
On top of the `HRTimer Queue`, users only need to implement the following
716+
interfaces to customize their own HRTimer implementation:
717+
718+
**hrtimer_expiry(current)**: Handles timer expiration, typically called
719+
within the execution path of the corresponding timer hardware
720+
interrupt handler.
721+
722+
**hrtimer_reprogram(queue, next_expired)**: Sets the next timer event.
723+
724+
**hrtimer_current()**: Gets the current time to set relative timers.
725+
726+
After implementing the above three interfaces, users can include one of the
727+
`hrtimer_type_xxx.h` implementation to compose their own hrtimer
728+
implementation, which mainly includes the following interfaces:
729+
730+
**hrtimer_start(timer, func, arg, delay)**: Starts a timer.
731+
732+
**hrtimer_restart(timer, func, arg, delay)**: Restarts a timer that has
733+
been asynchronously canceled (its callback function might still be executing).
734+
This interface is designed to explicitly remind users to be aware of
735+
concurrency issues,as concurrency problems are prone to occur in actual
736+
programming and are very difficult to locate. Providing such an interface
737+
facilitates quick identification of concurrency issues.
738+
739+
**hrtimer_cancel(timer)**: Asynchronously cancels a timer. Note that
740+
the semantics of this interface are completely different from Linux's
741+
`try_to_cancel`. It ensures that the timer can definitely be canceled
742+
successfully, but may need to wait for its callback function to finish
743+
execution.
744+
745+
**hrtimer_cancel_sync(timer)**: Synchronously cancels a timer. If the timer's
746+
callback function is still executing, this function will spin-wait until
747+
the callback completes. It ensures that the user can always obtain
748+
ownership of the timer.
749+
750+
The state-machine diagram of the HRTimer is as follows:
751+
752+
.. code-block:: text
753+
754+
┌─────────────────────────────────────────────────────────────────────┐
755+
│ │
756+
│ ┌─────────────────────┐ hrtimer_start ┌────────────────┐ │
757+
│ │ HRTIMER_COMPLETED │ ─────────────────────> │ HRTIMER_PENDING│ │
758+
│ │ (private) │ │ (shared) │ │
759+
│ └─────────────────────┘ └────────────────┘ │
760+
│ ^ │ │
761+
│ │ │ │
762+
│ │ hrtimer callback return 0 │ │
763+
│ │ in hrtimer_expiry │ │
764+
│ │ │ │
765+
│ │ ▼ │
766+
│ │ ┌───────────────────────────────────────────┐ │
767+
│ │ │ HRTIMER_CANCELED │ │
768+
│ │ │ (half_shared) │ │
769+
│ │ └───────────────────────────────────────────┘ │
770+
│ │ │ ▲ │
771+
│ │ │ │ │
772+
│ │ │ hrtimer_cancel │ hrtimer_restart │
773+
│ │ │ wait all cores │ │
774+
│ │ │ release the │ │
775+
│ │ │ references to │ │
776+
│ │ │ the timer. │ │
777+
│ │ ▼ │ │
778+
│ │ ┌───────────────────────────────────────────┐ │
779+
│ │ │ HRTIMER_CANCELED │ │
780+
│ │ │ (private) │ │
781+
│ │ └───────────────────────────────────────────┘ │
782+
│ │ │ │
783+
│ │ │ Complete the cancel │
784+
│ └────────────────────┘ │
785+
│ │
786+
│ Note: HRTIMER_PENDING has a self-transition for │
787+
│ "hrtimer callback return non-zero in hrtimer_expiry" │
788+
│ │
789+
└─────────────────────────────────────────────────────────────────────┘
790+
791+
.. c:function:: int hrtimer_restart(hrtimer_t *timer, hrtimer_callback_t func, FAR void *arg, uint64_t delay)
792+
.. c:function:: int hrtimer_restart_absolute(hrtimer_t *timer, hrtimer_callback_t func, FAR void *arg, uint64_t expired)
793+
794+
Restart a high-resolution timer with new parameters.
795+
796+
For relative mode timers, converts relative time to absolute expiration time.
797+
The expiration time is capped at HRTIMER_MAX_DELAY.
798+
799+
**Note:** This function is static inline and intended for internal use.
800+
801+
:param timer: Timer instance to restart
692802
:param func: Expiration callback function
693-
:param arg: Callback argument
803+
:param arg: Argument passed to callback function
804+
:param delay/expired: Expiration time in nanoseconds (relative or absolute)
694805
695-
:return: None.
806+
:return: Zero on success; error code on failure.
696807
697-
**POSIX Compatibility:** This is a NON-POSIX interface.
808+
**Assumptions:**
809+
- The caller has ownership of the timer.
698810
699-
.. c:function:: int hrtimer_cancel(FAR hrtimer_t *hrtimer)
811+
.. c:function:: int hrtimer_start(FAR hrtimer_t *timer, hrtimer_callback_t func, FAR void *arg, uint64_t delay)
812+
.. c:function:: int hrtimer_start_absolute(FAR hrtimer_t *timer, hrtimer_callback_t func, FAR void *arg, uint64_t expired)
700813
701-
If the timer is armed but has not yet expired, it will be removed from
702-
the timer queue and the callback will not be invoked.
814+
Start a high-resolution timer with relative or absolute time in nanoseconds.
703815
704-
If the timer callback is currently executing, this function will mark
705-
the timer as canceled and return immediately. The running callback is
706-
allowed to complete, but it will not be invoked again.
816+
The caller must have ownership of the timer. This function validates parameters
817+
and timer state before attempting to start the timer.
707818
708-
This function is non-blocking and does not wait for a running callback
709-
to finish.
819+
:param timer: Timer instance to start
820+
:param func: Expiration callback function
821+
:param arg: Argument passed to callback function
822+
:param delay/expired: Expiration time in nanoseconds (relative or absolute)
823+
824+
:return: Zero on success; ``-EINVAL`` if parameters are invalid or timer is pending.
825+
826+
**Assumptions:**
827+
- Timer is not NULL and callback function is not NULL.
828+
- Timer is not in pending state.
829+
830+
.. c:function:: int hrtimer_cancel(FAR hrtimer_t *timer)
831+
832+
Cancel a high-resolution timer asynchronously.
833+
834+
Sets the timer to cancelled state and returns immediately. The caller acquires
835+
limited ownership, allowing timer restart but not freeing. Callback may still
836+
be executing on another CPU. Use with caution to avoid concurrency issues.
837+
838+
:param timer: Timer instance to cancel
710839
711-
:param hrtimer: Timer instance to cancel
840+
:return: ``OK`` on success; ``-EINVAL`` if timer is not pending.
712841
713-
:return: ``OK`` on success; negated errno on failure.
842+
**Assumptions:**
843+
- Timer is not NULL.
714844
715-
**POSIX Compatibility:** This is a NON-POSIX interface.
845+
.. c:function:: int hrtimer_cancel_sync(FAR hrtimer_t *timer)
716846
717-
.. c:function:: int hrtimer_cancel_sync(FAR hrtimer_t *hrtimer)
847+
Cancel a high-resolution timer and synchronously wait for callback completion.
718848
719-
Cancel a high-resolution timer and wait synchronously until the timer
720-
becomes inactive.
849+
Sets timer to cancelled state and waits for all references to be released.
850+
Caller acquires full ownership and can safely deallocate the timer after
851+
this function returns.
721852
722-
This function first calls hrtimer_cancel() to request cancellation of
723-
the timer. If the timer callback is currently executing, this function
724-
will wait until the callback has completed and the timer state has
725-
transitioned to HRTIMER_STATE_INACTIVE.
853+
:param timer: Timer instance to cancel
726854
727-
This function may sleep and must not be called from interrupt context.
855+
:return: ``OK`` on success; ``-EINVAL`` if timer is not pending.
728856
729-
:param hrtimer: Timer instance to cancel
857+
**Assumptions:**
858+
- Timer is not NULL.
730859
731-
:return: ``OK`` on success; negated errno on failure.
860+
.. c:function:: uint64_t hrtimer_gettime(FAR hrtimer_t *timer)
732861
733-
**POSIX Compatibility:** This is a NON-POSIX interface.
862+
Get the remaining time until timer expiration.
734863
735-
.. c:function:: int hrtimer_start(FAR hrtimer_t *hrtimer, uint64_t ns, \
736-
enum hrtimer_mode_e mode)
864+
:param timer: Timer instance to query
737865
738-
This function starts a high-resolution timer in absolute or relative mode.
866+
:return: Remaining time in nanoseconds until next expiration.
739867
740-
:param hrtimer: Timer instance to cancel
741-
:param ns: Timer expiration in nanoseconds (absolute or relative)
742-
:param mode: HRTIMER_MODE_ABS or HRTIMER_MODE_REL
868+
**Assumptions:**
869+
- Timer is not NULL.
743870
744-
:return: ``OK`` on success; negated errno on failure.
871+
.. c:type:: uitn64_t (*hrtimer_callback_t)(void *arg, uint64_t expired)
745872
746-
**POSIX Compatibility:** This is a NON-POSIX interface.
873+
**High-resolution Timer Callback Type**: Function pointer type for timer
874+
expiration callbacks. When a hrtimer expires, a function of this type is called.
747875
748-
.. c:type:: void (*hrtentry_t)(FAR struct hrtimer_s *)
876+
:param arg: Argument passed to callback function
877+
:param expired: Time in nanoseconds when timer expired
749878
750-
**High-resolution Timer Callback**: when a hrtimer expires,
751-
the callback function with this type is called.
879+
:return: Next delay in nanoseconds until next expiration.

0 commit comments

Comments
 (0)