Problem: there are two similar mechanisms in nanokernel: nano_timers and
nano_timeouts. In order to optimize codeand space it's better to have one
mechanism for both.
Proposal: Implement nano_timer through timeout mechanism. This aproach
allows to get rid of heavier nanokernel lifo component in favor of more
lightweight nanokernel timeout implementation.
The _nano_timeout structure gets two additional arguments: void
*user_data_ptr and bool expired, the flag that is set to true when the
timeout is expired.
_nano_timeout structure now can be safely renamed to nano_timer, as it
has everything required by nano_timer API.
In this case, if a function like fiber_sleep() is invoked, the
user_data_ptr is set to NULL.
For the nano_timer API user_data_ptr is used to store the user data
pointer. When the nano_timer_init() function is called, it gets the
_nano_timer structure and initializes it as before. On the
nano_timer_start() call the nano_timer structure is being added to the
sorted list via _nano_timeout_add() function.
nano_timer_test() checks the expired flag of the nano_timer structure.
if it is true, the function just returns the user_data_ptr, otherwise,
if the timeout_in_ticks is not TICKS_NONE, it puts the fiber or task to
sleep by calling _Swap().
Question: is it needed to wait for a specified timeout, if
timeout_in_ticks argument is neither TICKS_NONE nor TICKS_UNLIMITED?
_nano_timeout_handle_one_timeout(), in turn, sets the expired flag to
true and if fiber or task is waiting, marks it runnable.
fiberRtnValueSet is used to set the return value to user_data_ptr.
Problem: in microkernel system clock ticks are processed in the k_server
fiber, which does not allow using timeouts during the initialization
before k_server fiber starts.
In order to allow using timeouts during the system initialization
_do_sys_clock_tick_announce pointer has to be modified to point at the
_nano_sys_clock_tick_announce() until the microkernel _k_server() fiber
starts. This way the _do_sys_clock_tick_announce may be initialized as a
_nano_sys_clock_tick_announce() routine by default.
This modification needs to be done with changing priority of the driver
initialization routines that use timeout. Such routines need to be
invoked not on PRIMARY, but on NANOKERNEL initialization level.