libosmocore  1.4.0.80-4fb27
Osmocom core library
Osmocom timers

Timer management: More...

Files

file  timer.h
 Osmocom timer handling routines.
 
file  timer_compat.h
 Compatibility header with some helpers.
 
file  timer.c
 
file  timer_clockgettime.c
 Overriding Time: osmo_clock_gettime()
 
file  timer_clockgettime.c
 Overriding Time: osmo_clock_gettime()
 
file  timer_gettimeofday.c
 Overriding Time: osmo_gettimeofday()
 

Data Structures

struct  osmo_timer_list
 A structure representing a single instance of a timer. More...
 

Macros

#define OSMO_SEC2MIN(sec)   ((sec % (60 * 60)) / 60)
 
#define OSMO_SEC2HRS(sec)   ((sec % (60 * 60 * 24)) / (60 * 60))
 
#define OSMO_SEC2DAY(sec)   ((sec % (60 * 60 * 24 * 365)) / (60 * 60 * 24)) /* we ignore leap year for simplicity */
 
#define timerisset(tvp)   ((tvp)->tv_sec || (tvp)->tv_usec)
 
#define timerclear(tvp)   ((tvp)->tv_sec = (tvp)->tv_usec = 0)
 
#define timercmp(a, b, CMP)
 
#define timeradd(a, b, result)
 
#define timersub(a, b, result)
 
#define timespecisset(tvp)   ((tvp)->tv_sec || (tvp)->tv_nsec)
 
#define timespecclear(tvp)   ((tvp)->tv_sec = (tvp)->tv_nsec = 0)
 
#define timespeccmp(a, b, CMP)
 
#define timespecadd(a, b, result)
 
#define timespecsub(a, b, result)
 

Functions

void osmo_timer_setup (struct osmo_timer_list *timer, void(*cb)(void *data), void *data)
 set up timer callback and data More...
 
void osmo_timer_add (struct osmo_timer_list *timer)
 add a new timer to the timer management More...
 
void osmo_timer_schedule (struct osmo_timer_list *timer, int seconds, int microseconds)
 schedule a timer at a given future relative time More...
 
void osmo_timer_del (struct osmo_timer_list *timer)
 delete a timer from timer management More...
 
int osmo_timer_pending (struct osmo_timer_list *timer)
 check if given timer is still pending More...
 
int osmo_timer_remaining (const struct osmo_timer_list *timer, const struct timeval *now, struct timeval *remaining)
 compute the remaining time of a timer More...
 
struct timeval * osmo_timers_nearest (void)
 Determine time between now and the nearest timer. More...
 
void osmo_timers_prepare (void)
 Find the nearest time and update nearest_p. More...
 
int osmo_timers_update (void)
 fire all timers... More...
 
int osmo_timers_check (void)
 Check how many timers we have in the system. More...
 
int osmo_gettimeofday (struct timeval *tv, struct timezone *tz)
 shim around gettimeofday to be able to set the time manually. More...
 
int osmo_clock_gettime (clockid_t clk_id, struct timespec *tp)
 
void osmo_gettimeofday_override_add (time_t secs, suseconds_t usecs)
 convenience function to advance the fake time. More...
 
void osmo_clock_override_enable (clockid_t clk_id, bool enable)
 
void osmo_clock_override_add (clockid_t clk_id, time_t secs, long nsecs)
 
struct timespec * osmo_clock_override_gettimespec (clockid_t clk_id)
 
static void __add_timer (struct osmo_timer_list *timer)
 
static void update_nearest (struct timeval *cand, struct timeval *current)
 

Variables

bool osmo_gettimeofday_override
 
struct timeval osmo_gettimeofday_override_time
 
static __thread struct timeval nearest
 
static __thread struct timeval * nearest_p
 
static __thread struct rb_root timer_root = RB_ROOT
 
bool osmo_gettimeofday_override = false
 
struct timeval osmo_gettimeofday_override_time = { 23, 424242 }
 

Detailed Description

Timer management:

Osmocom timer abstraction; modelled after linux kernel timers.

Internally:

Macro Definition Documentation

◆ OSMO_SEC2DAY

#define OSMO_SEC2DAY (   sec)    ((sec % (60 * 60 * 24 * 365)) / (60 * 60 * 24)) /* we ignore leap year for simplicity */

◆ OSMO_SEC2HRS

#define OSMO_SEC2HRS (   sec)    ((sec % (60 * 60 * 24)) / (60 * 60))

◆ OSMO_SEC2MIN

#define OSMO_SEC2MIN (   sec)    ((sec % (60 * 60)) / 60)

◆ timeradd

#define timeradd (   a,
  b,
  result 
)
Value:
do { \
(result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
if ((result)->tv_usec >= 1000000) \
{ \
++(result)->tv_sec; \
(result)->tv_usec -= 1000000; \
} \
} while (0)

Referenced by osmo_gettimeofday_override_add(), and osmo_timer_schedule().

◆ timerclear

#define timerclear (   tvp)    ((tvp)->tv_sec = (tvp)->tv_usec = 0)

Referenced by update_nearest().

◆ timercmp

#define timercmp (   a,
  b,
  CMP 
)
Value:
(((a)->tv_sec == (b)->tv_sec) ? \
((a)->tv_usec CMP (b)->tv_usec) : \
((a)->tv_sec CMP (b)->tv_sec))

Referenced by __add_timer(), osmo_timers_update(), and update_nearest().

◆ timerisset

#define timerisset (   tvp)    ((tvp)->tv_sec || (tvp)->tv_usec)

◆ timersub

#define timersub (   a,
  b,
  result 
)
Value:
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
if ((result)->tv_usec < 0) { \
--(result)->tv_sec; \
(result)->tv_usec += 1000000; \
} \
} while (0)

Referenced by osmo_timer_remaining(), and update_nearest().

◆ timespecadd

#define timespecadd (   a,
  b,
  result 
)
Value:
do { \
(result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
(result)->tv_nsec = (a)->tv_nsec + (b)->tv_nsec; \
if ((result)->tv_nsec >= 1000000000) \
{ \
++(result)->tv_sec; \
(result)->tv_nsec -= 1000000000; \
} \
} while (0)

◆ timespecclear

#define timespecclear (   tvp)    ((tvp)->tv_sec = (tvp)->tv_nsec = 0)

◆ timespeccmp

#define timespeccmp (   a,
  b,
  CMP 
)
Value:
(((a)->tv_sec == (b)->tv_sec) ? \
((a)->tv_nsec CMP (b)->tv_nsec) : \
((a)->tv_sec CMP (b)->tv_sec))

◆ timespecisset

#define timespecisset (   tvp)    ((tvp)->tv_sec || (tvp)->tv_nsec)

◆ timespecsub

#define timespecsub (   a,
  b,
  result 
)
Value:
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec; \
if ((result)->tv_nsec < 0) { \
--(result)->tv_sec; \
(result)->tv_nsec += 1000000000; \
} \
} while (0)

Function Documentation

◆ __add_timer()

static void __add_timer ( struct osmo_timer_list timer)
static

◆ osmo_clock_gettime()

int osmo_clock_gettime ( clockid_t  clk_id,
struct timespec *  tp 
)

◆ osmo_clock_override_add()

void osmo_clock_override_add ( clockid_t  clk_id,
time_t  secs,
long  nsecs 
)

◆ osmo_clock_override_enable()

void osmo_clock_override_enable ( clockid_t  clk_id,
bool  enable 
)

◆ osmo_clock_override_gettimespec()

struct timespec* osmo_clock_override_gettimespec ( clockid_t  clk_id)

◆ osmo_gettimeofday()

int osmo_gettimeofday ( struct timeval *  tv,
struct timezone *  tz 
)

shim around gettimeofday to be able to set the time manually.

To override, set osmo_gettimeofday_override == true and set the desired current time in osmo_gettimeofday_override_time.

N. B: gettimeofday() is affected by discontinuous jumps in the system time (e.g., if the system administrator manually changes the system time). Hence this should NEVER be used for elapsed time computation. Instead, osmo_clock_gettime() with CLOCK_MONOTONIC should be used for that.

References osmo_gettimeofday_override, and osmo_gettimeofday_override_time.

Referenced by _gsmtap_raw_output(), _output(), osmo_timer_remaining(), osmo_timer_schedule(), osmo_timers_prepare(), and osmo_timers_update().

◆ osmo_gettimeofday_override_add()

void osmo_gettimeofday_override_add ( time_t  secs,
suseconds_t  usecs 
)

convenience function to advance the fake time.

Add the given values to osmo_gettimeofday_override_time.

References osmo_gettimeofday_override_time, and timeradd.

◆ osmo_timer_add()

void osmo_timer_add ( struct osmo_timer_list timer)

add a new timer to the timer management

Parameters
[in]timerthe timer that should be added

References __add_timer(), osmo_timer_list::active, INIT_LLIST_HEAD, osmo_timer_list::list, and osmo_timer_del().

Referenced by osmo_timer_schedule().

◆ osmo_timer_del()

void osmo_timer_del ( struct osmo_timer_list timer)

delete a timer from timer management

Parameters
[in]timerthe to-be-deleted timer

This function can be used to delete a previously added/scheduled timer from the timer management code.

References osmo_timer_list::active, osmo_timer_list::list, llist_del_init(), llist_empty(), osmo_timer_list::node, and rb_erase().

Referenced by osmo_fsm_inst_free(), osmo_timer_add(), osmo_timers_update(), and state_chg().

◆ osmo_timer_pending()

int osmo_timer_pending ( struct osmo_timer_list timer)

check if given timer is still pending

Parameters
[in]timerthe to-be-checked timer
Returns
1 if pending, 0 otherwise

This function can be used to determine whether a given timer has alredy expired (returns 0) or is still pending (returns 1)

References osmo_timer_list::active.

Referenced by state_chg().

◆ osmo_timer_remaining()

int osmo_timer_remaining ( const struct osmo_timer_list timer,
const struct timeval *  now,
struct timeval *  remaining 
)

compute the remaining time of a timer

Parameters
[in]timerthe to-be-checked timer
[in]nowthe current time (NULL if not known)
[out]remainingremaining time until timer fires
Returns
0 if timer has not expired yet, -1 if it has

This function can be used to determine the amount of time remaining until the expiration of the timer.

References osmo_gettimeofday(), osmo_timer_list::timeout, and timersub.

Referenced by state_chg().

◆ osmo_timer_schedule()

void osmo_timer_schedule ( struct osmo_timer_list timer,
int  seconds,
int  microseconds 
)

schedule a timer at a given future relative time

Parameters
[in]timerthe to-be-added timer
[in]secondsnumber of seconds from now
[in]microsecondsnumber of microseconds from now

This function can be used to (re-)schedule a given timer at a specified number of seconds+microseconds in the future. It will internally add it to the timer management data structures, thus osmo_timer_add() is automatically called.

References osmo_gettimeofday(), osmo_timer_add(), osmo_timer_list::timeout, and timeradd.

Referenced by rate_ctr_init(), rate_ctr_timer_cb(), and state_chg().

◆ osmo_timer_setup()

void osmo_timer_setup ( struct osmo_timer_list timer,
void(*)(void *data cb,
void *  data 
)

set up timer callback and data

Parameters
[in]timerthe timer that should be added
[in]cbfunction to be called when timer expires
[in]datapointer to data that passed to the callback function

References osmo_timer_list::cb, data, and osmo_timer_list::data.

Referenced by osmo_fsm_inst_alloc(), and rate_ctr_init().

◆ osmo_timers_check()

int osmo_timers_check ( void  )

Check how many timers we have in the system.

Returns
number of osmo_timer_list registered

References node, rb_first(), and rb_next().

◆ osmo_timers_nearest()

struct timeval * osmo_timers_nearest ( void  )

Determine time between now and the nearest timer.

Returns
pointer to timeval of nearest timer, NULL if there is none

if we have a nearest time return the delta between the current time and the time of the nearest timer. If the nearest timer timed out return NULL and then we will dispatch everything after the select

References nearest_p.

Referenced by _osmo_select_main().

◆ osmo_timers_prepare()

void osmo_timers_prepare ( void  )

Find the nearest time and update nearest_p.

References container_of, nearest_p, node, osmo_gettimeofday(), rb_first(), osmo_timer_list::timeout, and update_nearest().

Referenced by _osmo_select_main().

◆ osmo_timers_update()

◆ update_nearest()

static void update_nearest ( struct timeval *  cand,
struct timeval *  current 
)
static

References nearest, nearest_p, timerclear, timercmp, and timersub.

Referenced by osmo_timers_prepare().

Variable Documentation

◆ nearest

__thread struct timeval nearest
static

Referenced by update_nearest().

◆ nearest_p

__thread struct timeval* nearest_p
static

◆ osmo_gettimeofday_override [1/2]

bool osmo_gettimeofday_override = false

Referenced by osmo_gettimeofday().

◆ osmo_gettimeofday_override [2/2]

bool osmo_gettimeofday_override

Referenced by osmo_gettimeofday().

◆ osmo_gettimeofday_override_time [1/2]

struct timeval osmo_gettimeofday_override_time = { 23, 424242 }

◆ osmo_gettimeofday_override_time [2/2]

struct timeval osmo_gettimeofday_override_time

◆ timer_root

__thread struct rb_root timer_root = RB_ROOT
static