|
static void | timer_kernel_trampoline_callback (struct timer_list *tl) |
|
static int | timer_kernel_init (struct m0_timer *timer, struct m0_timer_locality *loc) |
|
static void | timer_kernel_fini (struct m0_timer *timer) |
|
static void | timer_kernel_start (struct m0_timer *timer) |
|
static void | timer_kernel_stop (struct m0_timer *timer) |
|
M0_INTERNAL int | m0_timer_init (struct m0_timer *timer, enum m0_timer_type type, struct m0_timer_locality *loc, m0_timer_callback_t callback, unsigned long data) |
|
M0_INTERNAL void | m0_timer_start (struct m0_timer *timer, m0_time_t expire) |
|
M0_INTERNAL void | m0_timer_stop (struct m0_timer *timer) |
|
M0_INTERNAL bool | m0_timer_is_started (const struct m0_timer *timer) |
|
M0_INTERNAL void | m0_timer_fini (struct m0_timer *timer) |
|
M0_INTERNAL void | m0_timer_callback_execute (struct m0_timer *timer) |
|
M0_INTERNAL void | m0_timer_locality_init (struct m0_timer_locality *loc) |
|
M0_INTERNAL void | m0_timer_locality_fini (struct m0_timer_locality *loc) |
|
M0_INTERNAL int | m0_timer_thread_attach (struct m0_timer_locality *loc) |
|
M0_INTERNAL void | m0_timer_thread_detach (struct m0_timer_locality *loc) |
|
| M0_TL_DESCR_DEFINE (tid, "thread IDs", static, struct m0_timer_tid, tt_linkage, tt_magic, 0x696c444954726d74, 0x686c444954726d74) |
|
| M0_TL_DEFINE (tid, static, struct m0_timer_tid) |
|
static pid_t | _gettid () |
|
static struct m0_timer_tid * | locality_tid_find (struct m0_timer_locality *loc, pid_t tid) |
|
static pid_t | timer_locality_tid_next (struct m0_timer_locality *loc) |
|
static int | timer_posix_init (struct m0_timer *timer) |
|
static void | timer_posix_fini (timer_t posix_timer) |
|
static m0_time_t | timer_time_to_realtime (m0_time_t expire) |
|
static void | timer_posix_set (struct m0_timer *timer, m0_time_t expire, m0_time_t *old_expire) |
|
static int | timer_sigaction (int signo, void(*sighandler)(int, siginfo_t *, void *)) |
|
static void | timer_sighandler (int signo, siginfo_t *si, void *u_ctx) |
|
static int | timer_hard_init (struct m0_timer *timer, struct m0_timer_locality *loc) |
|
static void | timer_hard_fini (struct m0_timer *timer) |
|
static void | timer_hard_start (struct m0_timer *timer) |
|
static void | timer_hard_stop (struct m0_timer *timer) |
|
static void | timer_working_thread (struct m0_timer *timer) |
|
static int | timer_soft_initfini (struct m0_timer *timer, bool init) |
|
static int | timer_soft_init (struct m0_timer *timer, struct m0_timer_locality *loc) |
|
static void | timer_soft_fini (struct m0_timer *timer) |
|
static void | timer_soft_start (struct m0_timer *timer) |
|
static void | timer_soft_stop (struct m0_timer *timer) |
|
M0_INTERNAL int | m0_timers_init (void) |
|
M0_INTERNAL void | m0_timers_fini (void) |
|
Any timer should call m0_timer_init() function before any function. That init function does all initialization for this timer. After that, the m0_timer_start() function is called to start the timer. The timer callback function will be called repeatedly, if this is a repeatable timer. Function m0_timer_stop() is used to stop the timer, and m0_timer_fini() to destroy the timer after usage.
User supplied callback function should be small, run and complete quickly.
There are two types of timer: soft timer and hard timer. For Linux kernel implementation, all timers are hard timer. For userspace implementation, soft timer and hard timer have different mechanism:
- Hard timer has better resolution and is driven by signal. The user-defined callback should take short time, should never block at any time. Also in user space it should be async-signal-safe (see signal(7)), in kernel space it can only take _irq spin-locks.
- Soft timer creates separate thread to execute the user-defined callback for each timer. So the overhead is bigger than hard timer. The user-defined callback execution may take longer time and it will not impact other timers.
State machine
+------------+ m0_timer_start() +-------------+
| INITED |------------------------->| RUNNING |
+------------+ +-------------+
^ | | ^
m0_timer_init() | | m0_timer_fini() m0_timer_stop() | | m0_timer_start()
| v v |
+============+ +-------------+
| UNINIT |<-------------------------| STOPPED |
+============+ m0_timer_fini() +-------------+
Error handling
Implementation details
Limitations
- Number of hard timers is limited by maximum number of pending signals, see
ulimit -i
.
- Number of soft timers is limited by maximum number of threads.
- Note
- m0_timer_* functions should not be used in the timer callbacks.
Implementation of m0_timer on top of Linux struct timer_list.
Linux kernel timer.
Implementation of m0_timer.
User space timer.
◆ TIMER_SIGNO
#define TIMER_SIGNO SIGRTMIN |
Hard timer implementation uses TIMER_SIGNO signal for user-defined callback delivery.
Definition at line 49 of file timer.c.
◆ m0_timer_callback_t
typedef unsigned long(* m0_timer_callback_t) (unsigned long data) |
◆ m0_timer_state
Timer state.
- See also
- timer_state_change()
Enumerator |
---|
M0_TIMER_UNINIT | Not initialized.
|
M0_TIMER_INITED | Initialized.
|
M0_TIMER_RUNNING | Timer is running.
|
M0_TIMER_STOPPED | Timer is stopped
|
M0_TIMER_STATE_NR | Number of timer states
|
Definition at line 113 of file timer.h.
◆ m0_timer_type
Timer type.
Enumerator |
---|
M0_TIMER_SOFT | |
M0_TIMER_HARD | |
M0_TIMER_TYPE_NR | |
Definition at line 103 of file timer.h.
◆ _gettid()
gettid(2) implementation. Thread-safe, async-signal-safe.
Definition at line 70 of file timer.c.
◆ locality_tid_find()
◆ m0_timer_callback_execute()
M0_INTERNAL void m0_timer_callback_execute |
( |
struct m0_timer * |
timer | ) |
|
Execute timer callback.
It is used in timer implementation.
Definition at line 99 of file timer.c.
◆ m0_timer_fini()
M0_INTERNAL void m0_timer_fini |
( |
struct m0_timer * |
timer | ) |
|
Destroy the timer.
- Precondition
- m0_timer_init() for this timer was successfully called.
-
timer is not running.
Definition at line 65 of file timer.c.
◆ m0_timer_init()
Init the timer data structure.
- Parameters
-
timer | m0_timer structure |
type | timer type (M0_TIMER_SOFT or M0_TIMER_HARD) |
loc | timer locality, ignored for M0_TIMER_SOFT timers. Can be NULL - in this case hard timer signal will be delivered to the process. This parameter is ignored in kernel implementation. |
callback | this callback will be triggered when timer alarms. |
data | data for the callback. |
- Precondition
- callback != NULL
-
loc have at least one thread attached
- Postcondition
- timer is not running
- See also
- m0_timer_locality
Definition at line 39 of file timer.c.
◆ m0_timer_is_started()
M0_INTERNAL bool m0_timer_is_started |
( |
const struct m0_timer * |
timer | ) |
|
Returns true iff the timer is running.
Definition at line 94 of file timer.c.
◆ m0_timer_locality_fini()
◆ m0_timer_locality_init()
Init timer locality.
- Postcondition
- timer locality is empty
Definition at line 75 of file timer.c.
◆ m0_timer_start()
Start a timer.
- Parameters
-
expire | absolute expiration time for timer. If this time is already passed, then the timer callback will be executed ASAP. |
- Precondition
- m0_timer_init() successfully called.
-
timer is not running
Definition at line 75 of file timer.c.
◆ m0_timer_stop()
M0_INTERNAL void m0_timer_stop |
( |
struct m0_timer * |
timer | ) |
|
Stop a timer.
- Precondition
- m0_timer_init() successfully called.
-
timer is running
- Postcondition
- timer is not running
-
callback isn't running
Definition at line 86 of file timer.c.
◆ m0_timer_thread_attach()
Add current thread to the list of threads in locality.
- Precondition
- m0_timer_locality_init() successfully called.
-
current thread is not attached to locality.
- Postcondition
- current thread is attached to locality.
Definition at line 127 of file timer.c.
◆ m0_timer_thread_detach()
Remove current thread from the list of threads in locality. Current thread must be in this list.
- Precondition
- m0_timer_locality_init() successfully called.
-
current thread is attached to locality.
- Postcondition
- current thread is not attached to locality.
Definition at line 153 of file timer.c.
◆ m0_timers_fini()
M0_INTERNAL void m0_timers_fini |
( |
void |
| ) |
|
◆ m0_timers_init()
M0_INTERNAL int m0_timers_init |
( |
void |
| ) |
|
Init data structures for hard timer
Definition at line 457 of file timer.c.
◆ M0_TL_DEFINE()
ASCII "tmrTIDlh" - timer thread ID list head
◆ M0_TL_DESCR_DEFINE()
M0_TL_DESCR_DEFINE |
( |
tid |
, |
|
|
"thread IDs" |
, |
|
|
static |
, |
|
|
struct m0_timer_tid |
, |
|
|
tt_linkage |
, |
|
|
tt_magic |
, |
|
|
0x696c444954726d74 |
, |
|
|
0x686c444954726d74 |
|
|
) |
| |
◆ timer_hard_fini()
static void timer_hard_fini |
( |
struct m0_timer * |
timer | ) |
|
|
static |
◆ timer_hard_init()
◆ timer_hard_start()
static void timer_hard_start |
( |
struct m0_timer * |
timer | ) |
|
|
static |
Start one-shot POSIX timer for the given m0_timer.
Definition at line 319 of file timer.c.
◆ timer_hard_stop()
static void timer_hard_stop |
( |
struct m0_timer * |
timer | ) |
|
|
static |
Stop POSIX timer for the given m0_timer and wait for termination of user-defined timer callback.
Definition at line 330 of file timer.c.
◆ timer_kernel_fini()
static void timer_kernel_fini |
( |
struct m0_timer * |
timer | ) |
|
|
static |
◆ timer_kernel_init()
◆ timer_kernel_start()
static void timer_kernel_start |
( |
struct m0_timer * |
timer | ) |
|
|
static |
◆ timer_kernel_stop()
static void timer_kernel_stop |
( |
struct m0_timer * |
timer | ) |
|
|
static |
◆ timer_kernel_trampoline_callback()
static void timer_kernel_trampoline_callback |
( |
struct timer_list * |
tl | ) |
|
|
static |
◆ timer_locality_tid_next()
◆ timer_posix_fini()
static void timer_posix_fini |
( |
timer_t |
posix_timer | ) |
|
|
static |
Delete POSIX timer.
Definition at line 204 of file timer.c.
◆ timer_posix_init()
static int timer_posix_init |
( |
struct m0_timer * |
timer | ) |
|
|
static |
Init POSIX timer, write it to timer->t_ptimer. Timer notification is signal TIMER_SIGNO to thread timer->t_tid (or signal TIMER_SIGNO to the process if timer->t_tid == 0).
Definition at line 179 of file timer.c.
◆ timer_posix_set()
Run timer_settime() with given expire time (absolute). Return previous expiration time if old_expire != NULL.
Definition at line 228 of file timer.c.
◆ timer_sigaction()
static int timer_sigaction |
( |
int |
signo, |
|
|
void(*)(int, siginfo_t *, void *) |
sighandler |
|
) |
| |
|
static |
Set up signal handler sighandler for given signo.
Definition at line 254 of file timer.c.
◆ timer_sighandler()
static void timer_sighandler |
( |
int |
signo, |
|
|
siginfo_t * |
si, |
|
|
void * |
u_ctx |
|
) |
| |
|
static |
Signal handler for all POSIX timers. si->si_value.sival_ptr contains pointer to corresponding m0_timer structure.
Definition at line 275 of file timer.c.
◆ timer_soft_fini()
static void timer_soft_fini |
( |
struct m0_timer * |
timer | ) |
|
|
static |
◆ timer_soft_init()
◆ timer_soft_initfini()
static int timer_soft_initfini |
( |
struct m0_timer * |
timer, |
|
|
bool |
init |
|
) |
| |
|
static |
◆ timer_soft_start()
static void timer_soft_start |
( |
struct m0_timer * |
timer | ) |
|
|
static |
◆ timer_soft_stop()
static void timer_soft_stop |
( |
struct m0_timer * |
timer | ) |
|
|
static |
Stops soft timer and waits for callback termination.
Definition at line 433 of file timer.c.
◆ timer_time_to_realtime()
◆ timer_working_thread()
static void timer_working_thread |
( |
struct m0_timer * |
timer | ) |
|
|
static |
Soft timer working thread.
Definition at line 342 of file timer.c.
◆ clock_source_timer
int clock_source_timer = -1 |
|
static |
◆ m0_timer_ops [1/4]
◆ m0_timer_ops [2/4]
Initial value:= {
},
},
}
static void timer_kernel_fini(struct m0_timer *timer)
static void timer_kernel_start(struct m0_timer *timer)
static void timer_kernel_stop(struct m0_timer *timer)
static int timer_kernel_init(struct m0_timer *timer, struct m0_timer_locality *loc)
Definition at line 93 of file timer.c.
◆ m0_timer_ops [3/4]
◆ m0_timer_ops [4/4]
Initial value:= {
},
},
}
static int timer_hard_init(struct m0_timer *timer, struct m0_timer_locality *loc)
static void timer_hard_fini(struct m0_timer *timer)
static void timer_soft_start(struct m0_timer *timer)
static int timer_soft_init(struct m0_timer *timer, struct m0_timer_locality *loc)
static void timer_hard_start(struct m0_timer *timer)
static void timer_soft_fini(struct m0_timer *timer)
static void timer_soft_stop(struct m0_timer *timer)
static void timer_hard_stop(struct m0_timer *timer)
Definition at line 439 of file timer.c.
◆ zero_time