RTS API Documentation  1.10.11
Data Structures | Macros | Typedefs | Functions | Variables
switch_time.c File Reference
#include <switch.h>
#include <stdio.h>
#include "private/switch_apr_pvt.h"
#include "private/switch_core_pvt.h"
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <assert.h>
+ Include dependency graph for switch_time.c:

Go to the source code of this file.

Data Structures

struct  timer_private
 
struct  timer_matrix
 
struct  switch_timezones_list_t
 
struct  rule
 
struct  ttinfo
 
struct  lsinfo
 
struct  state
 

Macros

#define DISABLE_1MS_COND
 
#define UINT32_MAX   0xffffffff
 
#define MAX_TICK   UINT32_MAX - 1024
 
#define MAX_ELEMENTS   3600
 
#define IDLE_SPEED   100
 
#define calc_step()   if (step > 11) step -= 10; else if (step > 1) step--
 
#define check_roll()
 
#define TRUE   1
 
#define FALSE   0
 
#define TZ_MAX_TIMES   370
 
#define TZ_MAX_TYPES   256 /* Limited by what (unsigned char)'s can hold */
 
#define TZ_MAX_CHARS   50 /* Maximum number of abbreviation characters */
 
#define TZ_MAX_LEAPS   50 /* Maximum number of leap second corrections */
 
#define MY_TZNAME_MAX   255
 
#define SECSPERMIN   60
 
#define MINSPERHOUR   60
 
#define HOURSPERDAY   24
 
#define DAYSPERWEEK   7
 
#define DAYSPERNYEAR   365
 
#define DAYSPERLYEAR   366
 
#define SECSPERHOUR   (SECSPERMIN * MINSPERHOUR)
 
#define SECSPERDAY   ((long) SECSPERHOUR * HOURSPERDAY)
 
#define MONSPERYEAR   12
 
#define JULIAN_DAY   0 /* Jn - Julian day */
 
#define DAY_OF_YEAR   1 /* n - day of year */
 
#define MONTH_NTH_DAY_OF_WEEK   2 /* Mm.n.d - month, week, day of week */
 
#define EPOCH_YEAR   1970
 
#define EPOCH_WDAY   TM_THURSDAY
 
#define TZDEFRULES   "posixrules"
 
#define TZDEFRULESTRING   ",M4.1.0,M10.5.0"
 
#define is_digit(c)   ((unsigned)(c) - '0' <= 9)
 
#define BIGGEST(a, b)   (((a) > (b)) ? (a) : (b))
 
#define isleap(y)   (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
 
#define INITIALIZE(x)
 
#define TM_SUNDAY   0
 
#define TM_MONDAY   1
 
#define TM_TUESDAY   2
 
#define TM_WEDNESDAY   3
 
#define TM_THURSDAY   4
 
#define TM_FRIDAY   5
 
#define TM_SATURDAY   6
 
#define TM_JANUARY   0
 
#define TM_FEBRUARY   1
 
#define TM_MARCH   2
 
#define TM_APRIL   3
 
#define TM_MAY   4
 
#define TM_JUNE   5
 
#define TM_JULY   6
 
#define TM_AUGUST   7
 
#define TM_SEPTEMBER   8
 
#define TM_OCTOBER   9
 
#define TM_NOVEMBER   10
 
#define TM_DECEMBER   11
 
#define TM_YEAR_BASE   1900
 
#define EPOCH_YEAR   1970
 
#define EPOCH_WDAY   TM_THURSDAY
 
#define CHARS_DEF   BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), (2 * (MY_TZNAME_MAX + 1)))
 
#define switch_assert(expr)   assert(expr)
 
#define LEAPS_THRU_END_OF(y)   ((y) / 4 - (y) / 100 + (y) / 400)
 

Typedefs

typedef struct timer_private timer_private_t
 
typedef struct timer_matrix timer_matrix_t
 

Functions

 SWITCH_MODULE_LOAD_FUNCTION (softtimer_load)
 
 SWITCH_MODULE_SHUTDOWN_FUNCTION (softtimer_shutdown)
 
 SWITCH_MODULE_RUNTIME_FUNCTION (softtimer_runtime)
 
 SWITCH_MODULE_DEFINITION (CORE_SOFTTIMER_MODULE, softtimer_load, softtimer_shutdown, softtimer_runtime)
 
static switch_time_t time_now (int64_t offset)
 
void switch_os_yield (void)
 
static void do_sleep (switch_interval_time_t t)
 
static switch_interval_time_t average_time (switch_interval_time_t t, int reps)
 
void switch_time_calibrate_clock (void)
 
switch_time_t switch_micro_time_now (void)
 Get the current epoch time in microseconds. More...
 
switch_time_t switch_mono_micro_time_now (void)
 
time_t switch_epoch_time_now (time_t *t)
 Get the current epoch time. More...
 
void switch_time_set_monotonic (switch_bool_t enable)
 
void switch_time_set_use_system_time (switch_bool_t enable)
 
void switch_time_set_timerfd (int enable)
 
void switch_time_set_matrix (switch_bool_t enable)
 
void switch_time_set_nanosleep (switch_bool_t enable)
 
void switch_time_set_cond_yield (switch_bool_t enable)
 
static switch_status_t timer_generic_sync (switch_timer_t *timer)
 
switch_time_t switch_time_ref (void)
 
void switch_time_sync (void)
 
void switch_micro_sleep (switch_interval_time_t t)
 
void switch_sleep (switch_interval_time_t t)
 
void switch_cond_next (void)
 
void switch_cond_yield (switch_interval_time_t t)
 
static switch_status_t timer_init (switch_timer_t *timer)
 
static switch_status_t timer_step (switch_timer_t *timer)
 
static switch_status_t timer_sync (switch_timer_t *timer)
 
static switch_status_t timer_next (switch_timer_t *timer)
 
static switch_status_t timer_check (switch_timer_t *timer, switch_bool_t step)
 
static switch_status_t timer_destroy (switch_timer_t *timer)
 
static void win32_init_timers (void)
 
static void tm2switchtime (struct tm *tm, switch_time_exp_t *xt)
 
const char * switch_lookup_timezone (const char *tz_name)
 
void switch_load_timezones (switch_bool_t reload)
 
static void event_handler (switch_event_t *event)
 
static void tztime (const time_t *const timep, const char *tzstring, struct tm *const tmp)
 
switch_status_t switch_time_exp_tz_name (const char *tz, switch_time_exp_t *tm, switch_time_t thetime)
 
switch_status_t switch_strftime_tz (const char *tz, const char *format, char *date, size_t len, switch_time_t thetime)
 
static const char * getzname (register const char *strp)
 
static const char * getnum (register const char *strp, int *const nump, const int min, const int max)
 
static const char * getsecs (register const char *strp, long *const secsp)
 
static const char * getoffset (register const char *strp, long *const offsetp)
 
static const char * getrule (const char *strp, register struct rule *const rulep)
 
static time_t transtime (const time_t janfirst, const int year, register const struct rule *const rulep, const long offset)
 
static int tzparse (const char *name, register struct state *const sp, const int lastditch)
 
static void timesub (const time_t *const timep, const long offset, register const struct state *const sp, register struct tm *const tmp)
 

Variables

static int MONO = 0
 
static int SYSTEM_TIME = 0
 
static int TFD = 0
 
static int NANO = 0
 
static int OFFSET = 0
 
static int COND = 1
 
static int MATRIX = 1
 
static switch_memory_pool_tmodule_pool = NULL
 
struct {
   int32_t   RUNNING
 
   int32_t   STARTED
 
   int32_t   use_cond_yield
 
   switch_mutex_t *   mutex
 
   uint32_t   timer_count
 
globals
 
static timer_matrix_t TIMER_MATRIX [MAX_ELEMENTS+1]
 
static switch_time_t last_time = 0
 
static switch_timezones_list_t TIMEZONES_LIST = { 0 }
 
static switch_event_node_tNODE = NULL
 
static const char gmt [] = "GMT"
 
static const int mon_lengths [2][MONSPERYEAR]
 
static const int year_lengths [2]
 

Macro Definition Documentation

◆ BIGGEST

#define BIGGEST (   a,
  b 
)    (((a) > (b)) ? (a) : (b))

Definition at line 1747 of file switch_time.c.

◆ calc_step

#define calc_step ( )    if (step > 11) step -= 10; else if (step > 1) step--

Definition at line 207 of file switch_time.c.

Referenced by switch_time_calibrate_clock().

◆ CHARS_DEF

#define CHARS_DEF   BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), (2 * (MY_TZNAME_MAX + 1)))

Definition at line 1814 of file switch_time.c.

◆ check_roll

#define check_roll ( )
Value:
if (private_info->roll < TIMER_MATRIX[timer->interval].roll) { \
private_info->roll++; \
private_info->reference = private_info->start = (switch_size_t)TIMER_MATRIX[timer->interval].tick; \
private_info->start--; /* Must have a diff */ \
} \
static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
Definition: switch_time.c:138
uint32_t roll
Definition: switch_time.c:131
uintptr_t switch_size_t
uint64_t tick
Definition: switch_time.c:129

Definition at line 768 of file switch_time.c.

Referenced by timer_check(), timer_next(), and timer_step().

◆ DAY_OF_YEAR

#define DAY_OF_YEAR   1 /* n - day of year */

Definition at line 1712 of file switch_time.c.

Referenced by getrule(), and transtime().

◆ DAYSPERLYEAR

#define DAYSPERLYEAR   366

Definition at line 1706 of file switch_time.c.

Referenced by getrule().

◆ DAYSPERNYEAR

#define DAYSPERNYEAR   365

Definition at line 1705 of file switch_time.c.

Referenced by getrule(), and timesub().

◆ DAYSPERWEEK

#define DAYSPERWEEK   7

Definition at line 1704 of file switch_time.c.

Referenced by getrule(), getsecs(), timesub(), and transtime().

◆ DISABLE_1MS_COND

#define DISABLE_1MS_COND

Definition at line 44 of file switch_time.c.

◆ EPOCH_WDAY [1/2]

#define EPOCH_WDAY   TM_THURSDAY

Definition at line 1805 of file switch_time.c.

Referenced by timesub().

◆ EPOCH_WDAY [2/2]

#define EPOCH_WDAY   TM_THURSDAY

Definition at line 1805 of file switch_time.c.

◆ EPOCH_YEAR [1/2]

#define EPOCH_YEAR   1970

Definition at line 1804 of file switch_time.c.

Referenced by timesub(), and tzparse().

◆ EPOCH_YEAR [2/2]

#define EPOCH_YEAR   1970

Definition at line 1804 of file switch_time.c.

◆ FALSE

#define FALSE   0

Definition at line 1652 of file switch_time.c.

Referenced by tzparse(), and tztime().

◆ HOURSPERDAY

#define HOURSPERDAY   24

Definition at line 1703 of file switch_time.c.

Referenced by getsecs().

◆ IDLE_SPEED

#define IDLE_SPEED   100

Definition at line 54 of file switch_time.c.

◆ INITIALIZE

#define INITIALIZE (   x)

Definition at line 1776 of file switch_time.c.

Referenced by transtime(), and tzparse().

◆ is_digit

#define is_digit (   c)    ((unsigned)(c) - '0' <= 9)

Definition at line 1745 of file switch_time.c.

Referenced by getnum(), getrule(), and getzname().

◆ isleap

#define isleap (   y)    (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))

Definition at line 1749 of file switch_time.c.

Referenced by timesub(), transtime(), and tzparse().

◆ JULIAN_DAY

#define JULIAN_DAY   0 /* Jn - Julian day */

Definition at line 1711 of file switch_time.c.

Referenced by getrule(), and transtime().

◆ LEAPS_THRU_END_OF

#define LEAPS_THRU_END_OF (   y)    ((y) / 4 - (y) / 100 + (y) / 400)

Referenced by timesub().

◆ MAX_ELEMENTS

#define MAX_ELEMENTS   3600

Definition at line 53 of file switch_time.c.

Referenced by SWITCH_MODULE_RUNTIME_FUNCTION(), and timer_destroy().

◆ MAX_TICK

#define MAX_TICK   UINT32_MAX - 1024

Definition at line 51 of file switch_time.c.

Referenced by SWITCH_MODULE_RUNTIME_FUNCTION().

◆ MINSPERHOUR

#define MINSPERHOUR   60

Definition at line 1702 of file switch_time.c.

Referenced by getsecs().

◆ MONSPERYEAR

#define MONSPERYEAR   12

Definition at line 1709 of file switch_time.c.

Referenced by getrule().

◆ MONTH_NTH_DAY_OF_WEEK

#define MONTH_NTH_DAY_OF_WEEK   2 /* Mm.n.d - month, week, day of week */

Definition at line 1713 of file switch_time.c.

Referenced by getrule(), and transtime().

◆ MY_TZNAME_MAX

#define MY_TZNAME_MAX   255

Definition at line 1697 of file switch_time.c.

◆ SECSPERDAY

#define SECSPERDAY   ((long) SECSPERHOUR * HOURSPERDAY)

Definition at line 1708 of file switch_time.c.

Referenced by timesub(), transtime(), and tzparse().

◆ SECSPERHOUR

#define SECSPERHOUR   (SECSPERMIN * MINSPERHOUR)

Definition at line 1707 of file switch_time.c.

Referenced by getrule(), getsecs(), timesub(), and tzparse().

◆ SECSPERMIN

#define SECSPERMIN   60

Definition at line 1701 of file switch_time.c.

Referenced by getsecs(), and timesub().

◆ switch_assert

#define switch_assert (   expr)    assert(expr)

Definition at line 2343 of file switch_time.c.

Referenced by timesub().

◆ TM_APRIL

#define TM_APRIL   3

Definition at line 1792 of file switch_time.c.

◆ TM_AUGUST

#define TM_AUGUST   7

Definition at line 1796 of file switch_time.c.

◆ TM_DECEMBER

#define TM_DECEMBER   11

Definition at line 1800 of file switch_time.c.

◆ TM_FEBRUARY

#define TM_FEBRUARY   1

Definition at line 1790 of file switch_time.c.

◆ TM_FRIDAY

#define TM_FRIDAY   5

Definition at line 1786 of file switch_time.c.

◆ TM_JANUARY

#define TM_JANUARY   0

Definition at line 1789 of file switch_time.c.

◆ TM_JULY

#define TM_JULY   6

Definition at line 1795 of file switch_time.c.

◆ TM_JUNE

#define TM_JUNE   5

Definition at line 1794 of file switch_time.c.

◆ TM_MARCH

#define TM_MARCH   2

Definition at line 1791 of file switch_time.c.

◆ TM_MAY

#define TM_MAY   4

Definition at line 1793 of file switch_time.c.

◆ TM_MONDAY

#define TM_MONDAY   1

Definition at line 1782 of file switch_time.c.

◆ TM_NOVEMBER

#define TM_NOVEMBER   10

Definition at line 1799 of file switch_time.c.

◆ TM_OCTOBER

#define TM_OCTOBER   9

Definition at line 1798 of file switch_time.c.

◆ TM_SATURDAY

#define TM_SATURDAY   6

Definition at line 1787 of file switch_time.c.

◆ TM_SEPTEMBER

#define TM_SEPTEMBER   8

Definition at line 1797 of file switch_time.c.

◆ TM_SUNDAY

#define TM_SUNDAY   0

Definition at line 1781 of file switch_time.c.

◆ TM_THURSDAY

#define TM_THURSDAY   4

Definition at line 1785 of file switch_time.c.

◆ TM_TUESDAY

#define TM_TUESDAY   2

Definition at line 1783 of file switch_time.c.

◆ TM_WEDNESDAY

#define TM_WEDNESDAY   3

Definition at line 1784 of file switch_time.c.

◆ TM_YEAR_BASE

#define TM_YEAR_BASE   1900

Definition at line 1802 of file switch_time.c.

Referenced by timesub().

◆ TRUE

#define TRUE   1

Definition at line 1648 of file switch_time.c.

Referenced by tzparse().

◆ TZ_MAX_CHARS

#define TZ_MAX_CHARS   50 /* Maximum number of abbreviation characters */

Definition at line 1684 of file switch_time.c.

◆ TZ_MAX_LEAPS

#define TZ_MAX_LEAPS   50 /* Maximum number of leap second corrections */

Definition at line 1689 of file switch_time.c.

◆ TZ_MAX_TIMES

#define TZ_MAX_TIMES   370

Definition at line 1664 of file switch_time.c.

Referenced by tzparse().

◆ TZ_MAX_TYPES

#define TZ_MAX_TYPES   256 /* Limited by what (unsigned char)'s can hold */

Definition at line 1670 of file switch_time.c.

◆ TZDEFRULES

#define TZDEFRULES   "posixrules"

Definition at line 1730 of file switch_time.c.

◆ TZDEFRULESTRING

#define TZDEFRULESTRING   ",M4.1.0,M10.5.0"

Definition at line 1741 of file switch_time.c.

◆ UINT32_MAX

#define UINT32_MAX   0xffffffff

Definition at line 48 of file switch_time.c.

Referenced by timer_step().

Typedef Documentation

◆ timer_matrix_t

typedef struct timer_matrix timer_matrix_t

Definition at line 136 of file switch_time.c.

◆ timer_private_t

Definition at line 126 of file switch_time.c.

Function Documentation

◆ average_time()

static switch_interval_time_t average_time ( switch_interval_time_t  t,
int  reps 
)
static

Definition at line 191 of file switch_time.c.

References do_sleep(), timer_private::start, and switch_time_ref().

Referenced by switch_time_calibrate_clock().

192 {
193  int x = 0;
194  switch_time_t start, stop, sum = 0;
195 
196  for (x = 0; x < reps; x++) {
197  start = switch_time_ref();
198  do_sleep(t);
199  stop = switch_time_ref();
200  sum += (stop - start);
201  }
202 
203  return sum / reps;
204 
205 }
int64_t switch_time_t
Definition: switch_apr.h:188
static void do_sleep(switch_interval_time_t t)
Definition: switch_time.c:151
switch_time_t switch_time_ref(void)
Definition: switch_time.c:596

◆ do_sleep()

static void do_sleep ( switch_interval_time_t  t)
static

Definition at line 151 of file switch_time.c.

References NANO, and OFFSET.

Referenced by average_time(), switch_cond_next(), switch_cond_yield(), switch_micro_sleep(), SWITCH_MODULE_RUNTIME_FUNCTION(), SWITCH_MODULE_SHUTDOWN_FUNCTION(), switch_sleep(), switch_time_calibrate_clock(), timer_init(), and timer_next().

152 {
153 #if defined(HAVE_CLOCK_NANOSLEEP) || defined(DARWIN)
154  struct timespec ts;
155 #endif
156 
157 #if defined(WIN32)
158  if (t < 1000) {
159  t = 1000;
160  }
161 #endif
162 
163 #if !defined(DARWIN)
164  if (t > 100000 || !NANO) {
165  fspr_sleep(t);
166  return;
167  }
168 #endif
169 
170 #if defined(HAVE_CLOCK_NANOSLEEP)
171  t -= OFFSET;
172  ts.tv_sec = t / 1000000;
173  ts.tv_nsec = ((t % 1000000) * 1000);
174  clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
175 
176 #elif defined(DARWIN)
177  t -= OFFSET;
178  ts.tv_sec = t / APR_USEC_PER_SEC;
179  ts.tv_nsec = (t % APR_USEC_PER_SEC) * 850;
180  nanosleep(&ts, NULL);
181 #else
182  fspr_sleep(t);
183 #endif
184 
185 #if defined(DARWIN)
186  sched_yield();
187 #endif
188 
189 }
static int OFFSET
Definition: switch_time.c:85
static int NANO
Definition: switch_time.c:82

◆ event_handler()

static void event_handler ( switch_event_t event)
static

Definition at line 1439 of file switch_time.c.

References globals, switch_load_timezones(), switch_mutex_lock(), switch_mutex_unlock(), and tztime().

Referenced by SWITCH_MODULE_LOAD_FUNCTION().

1440 {
1441  switch_mutex_lock(globals.mutex);
1444 }
static struct @9 globals
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
void switch_load_timezones(switch_bool_t reload)
Definition: switch_time.c:1397

◆ getnum()

static const char* getnum ( register const char *  strp,
int *const  nump,
const int  min,
const int  max 
)
static

Definition at line 1889 of file switch_time.c.

References is_digit.

Referenced by getrule(), and getsecs().

1890 {
1891  register char c;
1892  register int num;
1893 
1894  if (strp == NULL || !is_digit(c = *strp))
1895  return NULL;
1896  num = 0;
1897  do {
1898  num = num * 10 + (c - '0');
1899  if (num > max)
1900  return NULL; /* illegal value */
1901  c = *++strp;
1902  } while (is_digit(c));
1903  if (num < min)
1904  return NULL; /* illegal value */
1905  *nump = num;
1906  return strp;
1907 }
#define is_digit(c)
Definition: switch_time.c:1745

◆ getoffset()

static const char* getoffset ( register const char *  strp,
long *const  offsetp 
)
static

Definition at line 1956 of file switch_time.c.

References getsecs().

Referenced by tzparse().

1957 {
1958  register int neg = 0;
1959 
1960  if (*strp == '-') {
1961  neg = 1;
1962  ++strp;
1963  } else if (*strp == '+')
1964  ++strp;
1965  strp = getsecs(strp, offsetp);
1966  if (strp == NULL)
1967  return NULL; /* illegal time */
1968  if (neg)
1969  *offsetp = -*offsetp;
1970  return strp;
1971 }
static const char * getsecs(register const char *strp, long *const secsp)
Definition: switch_time.c:1917

◆ getrule()

static const char* getrule ( const char *  strp,
register struct rule *const  rulep 
)
static

Definition at line 1980 of file switch_time.c.

References DAY_OF_YEAR, DAYSPERLYEAR, DAYSPERNYEAR, DAYSPERWEEK, getnum(), getsecs(), is_digit, JULIAN_DAY, MONSPERYEAR, MONTH_NTH_DAY_OF_WEEK, rule::r_day, rule::r_mon, rule::r_time, rule::r_type, rule::r_week, and SECSPERHOUR.

Referenced by tzparse().

1981 {
1982  if (*strp == 'J') {
1983  /*
1984  ** Julian day.
1985  */
1986  rulep->r_type = JULIAN_DAY;
1987  ++strp;
1988  strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
1989  } else if (*strp == 'M') {
1990  /*
1991  ** Month, week, day.
1992  */
1993  rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
1994  ++strp;
1995  strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
1996  if (strp == NULL)
1997  return NULL;
1998  if (*strp++ != '.')
1999  return NULL;
2000  strp = getnum(strp, &rulep->r_week, 1, 5);
2001  if (strp == NULL)
2002  return NULL;
2003  if (*strp++ != '.')
2004  return NULL;
2005  strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
2006  } else if (is_digit(*strp)) {
2007  /*
2008  ** Day of year.
2009  */
2010  rulep->r_type = DAY_OF_YEAR;
2011  strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
2012  } else
2013  return NULL; /* invalid format */
2014  if (strp == NULL)
2015  return NULL;
2016  if (*strp == '/') {
2017  /*
2018  ** Time specified.
2019  */
2020  ++strp;
2021  strp = getsecs(strp, &rulep->r_time);
2022  } else
2023  rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
2024  return strp;
2025 }
#define JULIAN_DAY
Definition: switch_time.c:1711
#define is_digit(c)
Definition: switch_time.c:1745
#define SECSPERHOUR
Definition: switch_time.c:1707
static const char * getsecs(register const char *strp, long *const secsp)
Definition: switch_time.c:1917
#define DAYSPERWEEK
Definition: switch_time.c:1704
#define MONTH_NTH_DAY_OF_WEEK
Definition: switch_time.c:1713
static const char * getnum(register const char *strp, int *const nump, const int min, const int max)
Definition: switch_time.c:1889
#define MONSPERYEAR
Definition: switch_time.c:1709
#define DAYSPERNYEAR
Definition: switch_time.c:1705
#define DAYSPERLYEAR
Definition: switch_time.c:1706
#define DAY_OF_YEAR
Definition: switch_time.c:1712

◆ getsecs()

static const char* getsecs ( register const char *  strp,
long *const  secsp 
)
static

Definition at line 1917 of file switch_time.c.

References DAYSPERWEEK, getnum(), HOURSPERDAY, MINSPERHOUR, SECSPERHOUR, and SECSPERMIN.

Referenced by getoffset(), and getrule().

1918 {
1919  int num;
1920 
1921  /*
1922  ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
1923  ** "M10.4.6/26", which does not conform to Posix,
1924  ** but which specifies the equivalent of
1925  ** ``02:00 on the first Sunday on or after 23 Oct''.
1926  */
1927  strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
1928  if (strp == NULL)
1929  return NULL;
1930  *secsp = num * (long) SECSPERHOUR;
1931  if (*strp == ':') {
1932  ++strp;
1933  strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
1934  if (strp == NULL)
1935  return NULL;
1936  *secsp += num * SECSPERMIN;
1937  if (*strp == ':') {
1938  ++strp;
1939  /* `SECSPERMIN' allows for leap seconds. */
1940  strp = getnum(strp, &num, 0, SECSPERMIN);
1941  if (strp == NULL)
1942  return NULL;
1943  *secsp += num;
1944  }
1945  }
1946  return strp;
1947 }
#define HOURSPERDAY
Definition: switch_time.c:1703
#define SECSPERMIN
Definition: switch_time.c:1701
#define MINSPERHOUR
Definition: switch_time.c:1702
#define SECSPERHOUR
Definition: switch_time.c:1707
#define DAYSPERWEEK
Definition: switch_time.c:1704
static const char * getnum(register const char *strp, int *const nump, const int min, const int max)
Definition: switch_time.c:1889

◆ getzname()

static const char* getzname ( register const char *  strp)
static

Definition at line 1872 of file switch_time.c.

References is_digit.

Referenced by tzparse().

1873 {
1874  register char c;
1875 
1876  while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && c != '+')
1877  ++strp;
1878  return strp;
1879 }
#define is_digit(c)
Definition: switch_time.c:1745

◆ switch_load_timezones()

void switch_load_timezones ( switch_bool_t  reload)

Definition at line 1397 of file switch_time.c.

References switch_timezones_list_t::hash, memset(), name, switch_xml::next, switch_timezones_list_t::pool, SWITCH_CHANNEL_LOG, switch_core_destroy_memory_pool, switch_core_hash_destroy(), switch_core_hash_init, switch_core_hash_insert, switch_core_new_memory_pool, switch_core_strdup, SWITCH_LOG_INFO, switch_log_printf(), switch_xml_attr(), switch_xml_child(), switch_xml_free(), switch_xml_open_cfg(), value, and zstr.

Referenced by event_handler(), and SWITCH_MODULE_LOAD_FUNCTION().

1398 {
1399  switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, cfg = NULL;
1400  unsigned total = 0;
1401 
1402  if (TIMEZONES_LIST.hash) {
1404  }
1405 
1406  if (TIMEZONES_LIST.pool) {
1408  }
1409 
1410  memset(&TIMEZONES_LIST, 0, sizeof(TIMEZONES_LIST));
1413 
1414  if ((xml = switch_xml_open_cfg("timezones.conf", &cfg, NULL))) {
1415  if ((x_lists = switch_xml_child(cfg, "timezones"))) {
1416  for (x_list = switch_xml_child(x_lists, "zone"); x_list; x_list = x_list->next) {
1417  const char *name = switch_xml_attr(x_list, "name");
1418  const char *value = switch_xml_attr(x_list, "value");
1419 
1420  if (zstr(name)) {
1421  continue;
1422  }
1423 
1424  if (zstr(value)) {
1425  continue;
1426  }
1427 
1429  total++;
1430  }
1431  }
1432 
1433  switch_xml_free(xml);
1434  }
1435 
1436  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Timezone %sloaded %d definitions\n", reload ? "re" : "", total);
1437 }
void switch_xml_free(_In_opt_ switch_xml_t xml)
frees the memory allocated for an switch_xml structure
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core&#39;s master pool.
Definition: switch_core.h:633
#define SWITCH_CHANNEL_LOG
switch_status_t switch_core_hash_destroy(_Inout_ switch_hash_t **hash)
Destroy an existing hash table.
const char * switch_xml_attr(_In_opt_ switch_xml_t xml, _In_opt_z_ const char *attr)
returns the value of the requested tag attribute, or NULL if not found
#define switch_core_hash_init(_hash)
Definition: switch_core.h:1431
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:733
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
const char *const const char *const const cJSON *const value
static switch_timezones_list_t TIMEZONES_LIST
Definition: switch_time.c:1376
A representation of an XML tree.
Definition: switch_xml.h:79
#define zstr(x)
Definition: switch_utils.h:314
switch_xml_t next
Definition: switch_xml.h:91
switch_memory_pool_t * pool
Definition: switch_time.c:1372
switch_xml_t switch_xml_open_cfg(_In_z_ const char *file_path, _Out_ switch_xml_t *node, _In_opt_ switch_event_t *params)
open a config in the core registry
#define switch_core_hash_insert(_h, _k, _d)
Definition: switch_core.h:1479
switch_hash_t * hash
Definition: switch_time.c:1373
switch_xml_t switch_xml_child(_In_ switch_xml_t xml, _In_z_ const char *name)
returns the first child tag (one level deeper) with the given name or NULL \ if not found ...
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
const char *const name
Definition: switch_cJSON.h:250
memset(buf, 0, buflen)

◆ SWITCH_MODULE_DEFINITION()

SWITCH_MODULE_DEFINITION ( CORE_SOFTTIMER_MODULE  ,
softtimer_load  ,
softtimer_shutdown  ,
softtimer_runtime   
)

◆ SWITCH_MODULE_LOAD_FUNCTION()

SWITCH_MODULE_LOAD_FUNCTION ( softtimer_load  )

Definition at line 1514 of file switch_time.c.

References event_handler(), globals, switch_runtime::initiated, switch_timer_interface::interface_name, switch_runtime::memory_pool, memset(), module_pool, MONO, pool, runtime, SCF_CALIBRATE_CLOCK, SCF_USE_CLOCK_RT, SCF_USE_HEAVY_TIMING, SCF_USE_WIN32_MONOTONIC, SWITCH_CHANNEL_LOG, switch_clear_flag, switch_event_bind_removable(), SWITCH_EVENT_RELOADXML, SWITCH_FALSE, switch_load_timezones(), switch_loadable_module_create_interface(), switch_loadable_module_create_module_interface(), SWITCH_LOG_CONSOLE, SWITCH_LOG_ERROR, SWITCH_LOG_NOTICE, switch_log_printf(), switch_mono_micro_time_now(), switch_mutex_init(), SWITCH_MUTEX_NESTED, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_time_calibrate_clock(), switch_time_set_cond_yield(), switch_time_set_nanosleep(), SWITCH_TIMER_INTERFACE, TFD, switch_timer_interface::timer_check, timer_check(), switch_timer_interface::timer_destroy, timer_destroy(), switch_timer_interface::timer_init, timer_init(), switch_timer_interface::timer_next, timer_next(), switch_timer_interface::timer_step, timer_step(), switch_timer_interface::timer_sync, timer_sync(), and win32_init_timers().

1515 {
1516  switch_timer_interface_t *timer_interface;
1517  module_pool = pool;
1518 
1519 #ifdef WIN32
1520  timeBeginPeriod(1);
1521 
1522  InitializeCriticalSection(&timer_section);
1523 
1524  win32_init_timers(); /* Init timers for Windows, if we should use timeGetTime() or QueryPerformanceCounters() */
1525 #endif
1526 
1527  memset(&globals, 0, sizeof(globals));
1529 
1532  }
1534 
1535  /* connect my internal structure to the blank pointer passed to me */
1536  *module_interface = switch_loadable_module_create_module_interface(pool, modname);
1537  timer_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_TIMER_INTERFACE);
1538  timer_interface->interface_name = "soft";
1539  timer_interface->timer_init = timer_init;
1540  timer_interface->timer_next = timer_next;
1541  timer_interface->timer_step = timer_step;
1542  timer_interface->timer_sync = timer_sync;
1543  timer_interface->timer_check = timer_check;
1544  timer_interface->timer_destroy = timer_destroy;
1545 
1548  }
1549 
1552  }
1553 
1554  if (TFD) {
1556  }
1557 
1558 #ifdef WIN32
1560  MONO = 1;
1561 
1562  if (win32_use_qpc) {
1563  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Enabled Windows monotonic clock, using QueryPerformanceCounter()\n");
1564  } else {
1565  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Enabled Windows monotonic clock, using timeGetTime()\n");
1566  }
1567 
1568  runtime.initiated = switch_mono_micro_time_now(); /* Update mono_initiated, since now is the first time the real clock is enabled */
1569  }
1570 
1571  /* No need to calibrate clock in Win32, we will only sleep ms anyway, it's just not accurate enough */
1573 #endif
1574 
1576  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Calibrating timer, please wait...\n");
1578  } else {
1579  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clock calibration disabled.\n");
1580  }
1581 
1582  /* indicate that the module should continue to be loaded */
1583  return SWITCH_STATUS_SUCCESS;
1584 }
switch_status_t(* timer_sync)(switch_timer_t *)
static switch_status_t timer_sync(switch_timer_t *timer)
Definition: switch_time.c:810
static switch_status_t timer_init(switch_timer_t *timer)
Definition: switch_time.c:699
static switch_status_t timer_step(switch_timer_t *timer)
Definition: switch_time.c:775
switch_status_t switch_event_bind_removable(const char *id, switch_event_types_t event, const char *subclass_name, switch_event_callback_t callback, void *user_data, switch_event_node_t **node)
Bind an event callback to a specific event.
#define SWITCH_CHANNEL_LOG
switch_time_t initiated
void switch_time_set_nanosleep(switch_bool_t enable)
Definition: switch_time.c:366
switch_memory_pool_t * pool
static int TFD
Definition: switch_time.c:81
static struct @9 globals
static switch_memory_pool_t * module_pool
Definition: switch_time.c:100
A table of functions that a timer module implements.
struct switch_runtime runtime
Definition: switch_core.c:86
switch_status_t(* timer_init)(switch_timer_t *)
static switch_status_t timer_destroy(switch_timer_t *timer)
Definition: switch_time.c:944
static switch_status_t timer_next(switch_timer_t *timer)
Definition: switch_time.c:840
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:724
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
static int MONO
Definition: switch_time.c:64
switch_status_t(* timer_check)(switch_timer_t *, switch_bool_t)
switch_status_t(* timer_destroy)(switch_timer_t *)
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:293
static switch_status_t timer_check(switch_timer_t *timer, switch_bool_t step)
Definition: switch_time.c:903
static switch_event_node_t * NODE
Definition: switch_time.c:1377
void switch_load_timezones(switch_bool_t reload)
Definition: switch_time.c:1397
switch_status_t(* timer_step)(switch_timer_t *)
switch_loadable_module_interface_t * switch_loadable_module_create_module_interface(switch_memory_pool_t *pool, const char *name)
void switch_time_calibrate_clock(void)
Definition: switch_time.c:208
switch_time_t switch_mono_micro_time_now(void)
Definition: switch_time.c:316
void switch_time_set_cond_yield(switch_bool_t enable)
Definition: switch_time.c:373
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
switch_memory_pool_t * memory_pool
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
static void event_handler(switch_event_t *event)
Definition: switch_time.c:1439
static void win32_init_timers(void)
Definition: switch_time.c:989
memset(buf, 0, buflen)
switch_status_t(* timer_next)(switch_timer_t *)
void * switch_loadable_module_create_interface(switch_loadable_module_interface_t *mod, switch_module_interface_name_t iname)

◆ SWITCH_MODULE_RUNTIME_FUNCTION()

SWITCH_MODULE_RUNTIME_FUNCTION ( softtimer_runtime  )

Definition at line 1038 of file switch_time.c.

References COND, count, do_sleep(), globals, switch_runtime::initiated, MATRIX, MAX_ELEMENTS, MAX_TICK, switch_runtime::microseconds_per_tick, module_pool, MONO, mutex, NANO, switch_runtime::offset, switch_runtime::profile_time, switch_runtime::profile_timer, switch_runtime::reference, timer_matrix::roll, runtime, switch_session_manager::session_count, switch_runtime::session_hash_mutex, session_manager, switch_runtime::sessions_peak_fivemin, switch_runtime::sps, switch_runtime::sps_last, switch_runtime::sps_peak, switch_runtime::sps_peak_fivemin, switch_runtime::sps_total, SWITCH_CHANNEL_LOG, switch_core_thread_set_cpu_affinity(), switch_delete_profile_timer(), switch_get_system_idle_time(), SWITCH_LOG_CONSOLE, SWITCH_LOG_CRIT, SWITCH_LOG_DEBUG, switch_log_printf(), switch_mono_micro_time_now(), switch_mutex_init(), switch_mutex_lock(), SWITCH_MUTEX_NESTED, switch_mutex_trylock(), switch_mutex_unlock(), switch_new_profile_timer(), switch_os_yield(), SWITCH_STATUS_SUCCESS, SWITCH_STATUS_TERM, switch_thread_cond_broadcast(), switch_thread_cond_create(), switch_time_now(), switch_time_ref(), switch_time_sync(), TFD, switch_runtime::throttle_mutex, timer_matrix::tick, time_now(), switch_runtime::time_sync, switch_runtime::timer_affinity, switch_runtime::timestamp, switch_runtime::tipping_point, and win32_init_timers().

1039 {
1040  switch_time_t too_late = runtime.microseconds_per_tick * 1000;
1041  uint32_t current_ms = 0;
1042  uint32_t x, tick = 0, sps_interval_ticks = 0;
1043  switch_time_t ts = 0, last = 0;
1044  int fwd_errs = 0, rev_errs = 0;
1045  int profile_tick = 0;
1046  int tfd = -1;
1047  uint32_t time_sync;
1048 
1049 #ifdef HAVE_TIMERFD_CREATE
1050  int last_MICROSECONDS_PER_TICK = runtime.microseconds_per_tick;
1051 
1052  struct itimerspec spec = { { 0 } };
1053 
1054  if (MONO && TFD) {
1055  tfd = timerfd_create(CLOCK_MONOTONIC, 0);
1056 
1057  if (tfd > -1) {
1058  spec.it_interval.tv_sec = 0;
1059  spec.it_interval.tv_nsec = runtime.microseconds_per_tick * 1000;
1060  spec.it_value.tv_sec = 0;
1061  spec.it_value.tv_nsec = 100000;
1062 
1063  if (timerfd_settime(tfd, 0, &spec, NULL)) {
1064  close(tfd);
1065  tfd = -1;
1066  }
1067  }
1068 
1069  if (tfd > -1) MATRIX = 0;
1070  }
1071 #else
1072  tfd = -1;
1073 #endif
1074 
1077 
1078  if (runtime.timer_affinity > -1) {
1080  }
1081 
1082  switch_time_sync();
1083 
1084  globals.STARTED = globals.RUNNING = 1;
1088 
1089  if (MONO) {
1090  int loops;
1091  for (loops = 0; loops < 3; loops++) {
1092  ts = switch_time_ref();
1093  /* if it returns the same value every time it won't be of much use. */
1094  if (ts == last) {
1095  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Broken MONOTONIC Clock Detected!, Support Disabled.\n");
1096  MONO = 0;
1097  NANO = 0;
1100  break;
1101  }
1103  last = ts;
1104  }
1105  }
1106 
1107  last = 0;
1108  fwd_errs = rev_errs = 0;
1109 
1110 #ifndef DISABLE_1MS_COND
1111  if (!NANO) {
1114  }
1115 #endif
1116 
1117 
1118  switch_time_sync();
1119  time_sync = runtime.time_sync;
1120 
1121  globals.use_cond_yield = COND;
1122  globals.RUNNING = 1;
1123 
1124  while (globals.RUNNING == 1) {
1125 
1126 #ifdef HAVE_TIMERFD_CREATE
1127  if (last_MICROSECONDS_PER_TICK != runtime.microseconds_per_tick) {
1128  spec.it_interval.tv_nsec = runtime.microseconds_per_tick * 1000;
1129  timerfd_settime(tfd, 0, &spec, NULL);
1130  }
1131 
1132  last_MICROSECONDS_PER_TICK = runtime.microseconds_per_tick;
1133 #endif
1134 
1136 
1137  while (((ts = time_now(runtime.offset)) + 100) < runtime.reference) {
1138  if (ts < last) {
1139  if (MONO) {
1141 
1142  if (time_sync == runtime.time_sync) { /* Only resync if not in the middle of switch_time_sync() already */
1143  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n");
1144  win32_init_timers(); /* Make sure to reinit timers on WIN32 */
1145  switch_time_sync();
1146  time_sync = runtime.time_sync;
1147  }
1148  } else {
1149  int64_t diff = (int64_t) (ts - last);
1150  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Reverse Clock Skew Detected!\n");
1152  current_ms = 0;
1153  tick = 0;
1154  runtime.initiated += diff;
1155  rev_errs++;
1156  }
1157 
1158  if (!MONO || time_sync == runtime.time_sync) {
1159 #if defined(HAVE_CLOCK_NANOSLEEP)
1161  "If you see this message many times try setting the param enable-clock-nanosleep to true in switch.conf.xml or consider a nicer machine to run me on.\n");
1162 #else
1164  "If you see this message many times consider a nicer machine to run me on.\n");
1165 #endif
1166  }
1167  } else {
1168  rev_errs = 0;
1169  }
1170 
1171  if (runtime.tipping_point && globals.timer_count >= runtime.tipping_point) {
1172  switch_os_yield();
1173  } else {
1174  if (tfd > -1 && globals.RUNNING == 1) {
1175  uint64_t exp;
1176  read(tfd, &exp, sizeof(exp));
1177  (void)exp;
1178  } else {
1179  switch_time_t timediff = runtime.reference - ts;
1180 
1181  if (runtime.microseconds_per_tick < timediff) {
1182  /* Only sleep for runtime.microseconds_per_tick if this value is lower then the actual time diff we need to sleep */
1184  } else {
1185 #ifdef WIN32
1186  /* Windows only sleeps in ms precision, try to round the usec value as good as possible */
1187  do_sleep((switch_interval_time_t)floor((timediff / 1000.0) + 0.5) * 1000);
1188 #else
1189  do_sleep(timediff);
1190 #endif
1191  }
1192  }
1193  }
1194 
1195  last = ts;
1196  }
1197 
1198  if (ts > (runtime.reference + too_late)) {
1199  if (MONO) {
1201 
1202  if (time_sync == runtime.time_sync) { /* Only resync if not in the middle of switch_time_sync() already */
1203  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n");
1204  win32_init_timers(); /* Make sure to reinit timers on WIN32 */
1205  switch_time_sync();
1206  time_sync = runtime.time_sync;
1207  }
1208  } else {
1210  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Forward Clock Skew Detected!\n");
1211  fwd_errs++;
1213  current_ms = 0;
1214  tick = 0;
1215  runtime.initiated += diff;
1216  }
1217  } else {
1218  fwd_errs = 0;
1219  }
1220 
1221  if (fwd_errs > 9 || rev_errs > 9) {
1222  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Auto Re-Syncing clock.\n");
1223  switch_time_sync();
1224  time_sync = runtime.time_sync;
1225  fwd_errs = rev_errs = 0;
1226  }
1227 
1228  runtime.timestamp = ts;
1229  current_ms += (runtime.microseconds_per_tick / 1000);
1230  tick++;
1231 
1232  if (time_sync < runtime.time_sync) {
1233  time_sync++; /* Only step once for each loop, we want to make sure to keep this thread safe */
1234  }
1235 
1236  if (tick >= (1000000 / runtime.microseconds_per_tick)) {
1237  if (++profile_tick == 1) {
1239  profile_tick = 0;
1240  }
1241 
1242  if (runtime.sps <= 0) {
1243  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Rate of %d!\n", runtime.sps_total);
1244  }
1245 
1246  /* These two mutexes must be held in exact order: session_hash_mutex and then throttle_mutex. See switch_core_session_request_uuid() */
1250 
1251  if (sps_interval_ticks >= 300) {
1253  sps_interval_ticks = 0;
1254  /* This line is protected by runtime.session_hash_mutex */
1256  }
1257 
1258  sps_interval_ticks++;
1259 
1262  }
1263 
1264  if (runtime.sps_last > runtime.sps_peak) {
1266  }
1270  tick = 0;
1271  }
1272 #ifndef DISABLE_1MS_COND
1273  TIMER_MATRIX[1].tick++;
1277  }
1278  if (TIMER_MATRIX[1].tick == MAX_TICK) {
1279  TIMER_MATRIX[1].tick = 0;
1280  TIMER_MATRIX[1].roll++;
1281  }
1282 #endif
1283 
1284 
1285  if (MATRIX && (current_ms % (runtime.microseconds_per_tick / 1000)) == 0) {
1286  for (x = (runtime.microseconds_per_tick / 1000); x <= MAX_ELEMENTS; x += (runtime.microseconds_per_tick / 1000)) {
1287  if ((current_ms % x) == 0) {
1288  if (TIMER_MATRIX[x].count) {
1289  TIMER_MATRIX[x].tick++;
1290 #ifdef DISABLE_1MS_COND
1291 
1295  }
1296 #endif
1297  if (TIMER_MATRIX[x].tick == MAX_TICK) {
1298  TIMER_MATRIX[x].tick = 0;
1299  TIMER_MATRIX[x].roll++;
1300  }
1301  }
1302  }
1303  }
1304  }
1305 
1306  if (current_ms == MAX_ELEMENTS) {
1307  current_ms = 0;
1308  }
1309  }
1310 
1311  globals.use_cond_yield = 0;
1312 
1313  for (x = (runtime.microseconds_per_tick / 1000); x <= MAX_ELEMENTS; x += (runtime.microseconds_per_tick / 1000)) {
1317  }
1318  }
1319 
1320  if (tfd > -1) {
1321  close(tfd);
1322  }
1323 
1324 
1325  switch_mutex_lock(globals.mutex);
1326  globals.RUNNING = 0;
1328 
1330 
1331  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Soft timer thread exiting.\n");
1332 
1333  return SWITCH_STATUS_TERM;
1334 }
void switch_time_sync(void)
Definition: switch_time.c:609
switch_status_t switch_thread_cond_create(switch_thread_cond_t **cond, switch_memory_pool_t *pool)
Definition: switch_apr.c:373
#define SWITCH_CHANNEL_LOG
switch_time_t initiated
switch_status_t switch_mutex_trylock(switch_mutex_t *lock)
Definition: switch_apr.c:318
static switch_time_t time_now(int64_t offset)
Definition: switch_time.c:540
void switch_os_yield(void)
Definition: switch_time.c:142
static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
Definition: switch_time.c:138
#define MAX_ELEMENTS
Definition: switch_time.c:53
int32_t timer_affinity
static int TFD
Definition: switch_time.c:81
static struct @9 globals
#define MAX_TICK
Definition: switch_time.c:51
static switch_memory_pool_t * module_pool
Definition: switch_time.c:100
switch_mutex_t * throttle_mutex
struct switch_runtime runtime
Definition: switch_core.c:86
uint32_t microseconds_per_tick
switch_status_t switch_core_thread_set_cpu_affinity(int cpu)
Definition: switch_core.c:1763
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
static int MONO
Definition: switch_time.c:64
int64_t switch_time_t
Definition: switch_apr.h:188
int32_t sessions_peak_fivemin
switch_bool_t switch_get_system_idle_time(switch_profile_timer_t *p, double *idle_percentage)
provides the percentage of idle system time
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
uint32_t roll
Definition: switch_time.c:131
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:293
switch_mutex_t * session_hash_mutex
int64_t switch_interval_time_t
Definition: switch_apr.h:191
static int COND
Definition: switch_time.c:87
void switch_delete_profile_timer(switch_profile_timer_t **p)
Deletes profile timer.
switch_profile_timer_t * switch_new_profile_timer(void)
create a new profile timer
switch_time_t timestamp
struct switch_session_manager session_manager
uint32_t tipping_point
int32_t sps_peak_fivemin
static int NANO
Definition: switch_time.c:82
switch_time_t switch_mono_micro_time_now(void)
Definition: switch_time.c:316
uint64_t tick
Definition: switch_time.c:129
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
int count
Definition: switch_cJSON.h:204
static void do_sleep(switch_interval_time_t t)
Definition: switch_time.c:151
switch_status_t switch_thread_cond_broadcast(switch_thread_cond_t *cond)
Definition: switch_apr.c:399
static void win32_init_timers(void)
Definition: switch_time.c:989
switch_time_t switch_time_now(void)
Definition: switch_apr.c:325
switch_mutex_t * mutex
Definition: switch_time.c:106
static int MATRIX
Definition: switch_time.c:89
switch_profile_timer_t * profile_timer
switch_time_t reference
switch_time_t switch_time_ref(void)
Definition: switch_time.c:596

◆ SWITCH_MODULE_SHUTDOWN_FUNCTION()

SWITCH_MODULE_SHUTDOWN_FUNCTION ( softtimer_shutdown  )

Definition at line 1586 of file switch_time.c.

References do_sleep(), globals, switch_timezones_list_t::hash, switch_timezones_list_t::pool, switch_core_destroy_memory_pool, switch_core_hash_destroy(), switch_event_unbind(), switch_mutex_lock(), switch_mutex_unlock(), and SWITCH_STATUS_SUCCESS.

1587 {
1588  globals.use_cond_yield = 0;
1589 
1590  if (globals.RUNNING == 1) {
1591  switch_mutex_lock(globals.mutex);
1592  globals.RUNNING = -1;
1594 
1595  while (globals.RUNNING == -1) {
1596  do_sleep(10000);
1597  }
1598  }
1599 #if defined(WIN32)
1600  timeEndPeriod(1);
1601  win32_tick_time_since_start = -1; /* we are not initialized anymore */
1602  DeleteCriticalSection(&timer_section);
1603 #endif
1604 
1605  if (NODE) {
1607  }
1608 
1609  switch_mutex_lock(globals.mutex);
1610  if (TIMEZONES_LIST.hash) {
1612  }
1613 
1615 
1616  if (TIMEZONES_LIST.pool) {
1618  }
1619 
1620  return SWITCH_STATUS_SUCCESS;
1621 }
switch_status_t switch_core_hash_destroy(_Inout_ switch_hash_t **hash)
Destroy an existing hash table.
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
static switch_timezones_list_t TIMEZONES_LIST
Definition: switch_time.c:1376
static struct @9 globals
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_memory_pool_t * pool
Definition: switch_time.c:1372
static switch_event_node_t * NODE
Definition: switch_time.c:1377
switch_hash_t * hash
Definition: switch_time.c:1373
static void do_sleep(switch_interval_time_t t)
Definition: switch_time.c:151
switch_status_t switch_event_unbind(switch_event_node_t **node)
Unbind a bound event consumer.

◆ switch_os_yield()

void switch_os_yield ( void  )

Definition at line 142 of file switch_time.c.

Referenced by switch_cond_next(), switch_core_session_read_frame(), switch_event_channel_deliver_thread(), switch_event_dispatch_thread(), SWITCH_MODULE_RUNTIME_FUNCTION(), and timer_next().

143 {
144 #if defined(WIN32)
145  SwitchToThread();
146 #else
147  sched_yield();
148 #endif
149 }

◆ time_now()

static switch_time_t time_now ( int64_t  offset)
static

Definition at line 540 of file switch_time.c.

References count, MONO, and switch_time_now().

Referenced by SWITCH_MODULE_RUNTIME_FUNCTION(), switch_mono_micro_time_now(), switch_time_ref(), switch_time_sync(), switch_xml_locate_user_cache(), and switch_xml_locate_user_merged().

541 {
542  switch_time_t now;
543 
544 #if (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) || defined(WIN32)
545  if (MONO) {
546 #ifndef WIN32
547  struct timespec ts;
548  clock_gettime(offset ? CLOCK_MONOTONIC : CLOCK_REALTIME, &ts);
549  if (offset < 0) offset = 0;
550  now = ts.tv_sec * APR_USEC_PER_SEC + (ts.tv_nsec / 1000) + offset;
551 #else
552  if (offset == 0) {
553  return switch_time_now();
554  } else if (offset < 0) offset = 0;
555 
556 
557  if (win32_use_qpc) {
558  /* Use QueryPerformanceCounter */
559  uint64_t count = 0;
560  QueryPerformanceCounter((LARGE_INTEGER*)&count);
561  now = ((count * 1000000) / win32_qpc_freq) + offset;
562  } else {
563  /* Use good old timeGetTime() */
564  DWORD tick_now;
565  DWORD tick_diff;
566 
567  tick_now = timeGetTime();
568  if (win32_tick_time_since_start != -1) {
569  EnterCriticalSection(&timer_section);
570  /* just add diff (to make it work more than 50 days). */
571  tick_diff = tick_now - win32_last_get_time_tick;
572  win32_tick_time_since_start += tick_diff;
573 
574  win32_last_get_time_tick = tick_now;
575  now = (win32_tick_time_since_start * 1000) + offset;
576  LeaveCriticalSection(&timer_section);
577  } else {
578  /* If someone is calling us before timer is initialized,
579  * return the current tick + offset
580  */
581  now = (tick_now * 1000) + offset;
582  }
583  }
584 #endif
585  } else {
586 #endif
587  now = switch_time_now();
588 
589 #if (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) || defined(WIN32)
590  }
591 #endif
592 
593  return now;
594 }
static int MONO
Definition: switch_time.c:64
int64_t switch_time_t
Definition: switch_apr.h:188
int count
Definition: switch_cJSON.h:204
switch_time_t switch_time_now(void)
Definition: switch_apr.c:325

◆ timer_check()

static switch_status_t timer_check ( switch_timer_t timer,
switch_bool_t  step 
)
static

Definition at line 903 of file switch_time.c.

References check_roll, switch_timer::diff, globals, switch_timer::interval, switch_timer::private_info, timer_private::ready, timer_private::reference, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, TFD, timer_matrix::tick, switch_timer::tick, and timer_step().

Referenced by rtp_common_read(), and SWITCH_MODULE_LOAD_FUNCTION().

904 {
905  timer_private_t *private_info;
907 
908  if (timer->interval == 1) {
909  return SWITCH_STATUS_FALSE;
910  }
911 
912 #ifdef HAVE_TIMERFD_CREATE
913  if (TFD == 2) {
914  return _timerfd_check(timer, step);
915  }
916 #endif
917 
918  private_info = timer->private_info;
919 
920  if (globals.RUNNING != 1 || !private_info->ready) {
921  return SWITCH_STATUS_SUCCESS;
922  }
923 
924  check_roll();
925 
926  timer->tick = TIMER_MATRIX[timer->interval].tick;
927 
928  if (timer->tick < private_info->reference) {
929  timer->diff = (switch_size_t)(private_info->reference - timer->tick);
930  } else {
931  timer->diff = 0;
932  }
933 
934  if (timer->diff) {
935  status = SWITCH_STATUS_FALSE;
936  } else if (step) {
937  timer_step(timer);
938  }
939 
940 
941  return status;
942 }
#define check_roll()
Definition: switch_time.c:768
static switch_status_t timer_step(switch_timer_t *timer)
Definition: switch_time.c:775
static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
Definition: switch_time.c:138
static int TFD
Definition: switch_time.c:81
static struct @9 globals
uintptr_t switch_size_t
switch_size_t reference
Definition: switch_time.c:121
uint32_t ready
Definition: switch_time.c:124
switch_status_t
Common return values.
uint64_t tick
Definition: switch_time.c:129

◆ timer_destroy()

static switch_status_t timer_destroy ( switch_timer_t timer)
static

Definition at line 944 of file switch_time.c.

References timer_matrix::count, globals, switch_timer::interval, MAX_ELEMENTS, switch_timer::private_info, timer_private::ready, runtime, SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), SWITCH_STATUS_SUCCESS, TFD, timer_matrix::tick, and switch_runtime::tipping_point.

Referenced by SWITCH_MODULE_LOAD_FUNCTION().

945 {
946  timer_private_t *private_info;
947 
948  if (timer->interval == 1) {
949  switch_mutex_lock(globals.mutex);
950  if (globals.timer_count) {
951  globals.timer_count--;
952  }
954  return SWITCH_STATUS_SUCCESS;
955  }
956 
957 #ifdef HAVE_TIMERFD_CREATE
958  if (TFD == 2) {
959  return _timerfd_destroy(timer);
960  }
961 #endif
962 
963  private_info = timer->private_info;
964 
965  if (timer->interval < MAX_ELEMENTS) {
966  switch_mutex_lock(globals.mutex);
967  TIMER_MATRIX[timer->interval].count--;
968  if (TIMER_MATRIX[timer->interval].count == 0) {
969  TIMER_MATRIX[timer->interval].tick = 0;
970  }
972  }
973  if (private_info) {
974  private_info->ready = 0;
975  }
976 
977  switch_mutex_lock(globals.mutex);
978  if (globals.timer_count) {
979  globals.timer_count--;
980  if (runtime.tipping_point && globals.timer_count == (runtime.tipping_point - 1)) {
981  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Fell Below tipping point of %u, shifting into low-gear.\n", runtime.tipping_point);
982  }
983  }
985 
986  return SWITCH_STATUS_SUCCESS;
987 }
#define SWITCH_CHANNEL_LOG
static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
Definition: switch_time.c:138
#define MAX_ELEMENTS
Definition: switch_time.c:53
static int TFD
Definition: switch_time.c:81
static struct @9 globals
struct switch_runtime runtime
Definition: switch_core.c:86
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
uint32_t count
Definition: switch_time.c:130
uint32_t ready
Definition: switch_time.c:124
uint32_t tipping_point
uint64_t tick
Definition: switch_time.c:129
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.

◆ timer_generic_sync()

static switch_status_t timer_generic_sync ( switch_timer_t timer)
static

Definition at line 382 of file switch_time.c.

References switch_timer::diff, switch_timer::interval, switch_timer::last_samplecount, switch_timer::memory_pool, switch_timer::private_info, switch_timer::samplecount, switch_timer::samples, switch_timer::start, SWITCH_CHANNEL_LOG, switch_core_alloc, SWITCH_LOG_DEBUG1, switch_log_printf(), switch_micro_time_now(), SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, and switch_timer::tick.

Referenced by timer_sync().

383 {
385  int64_t elapsed = (now - timer->start);
386 
387  timer->tick = (elapsed / timer->interval) / 1000;
388  timer->samplecount = (uint32_t)(timer->tick * timer->samples);
389 
390  if (timer->interval == 1 && timer->samplecount == timer->last_samplecount) {
391  timer->samplecount++;
392  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Timer sync too often\n");
393  }
394  timer->last_samplecount = timer->samplecount;
395 
396 
397 
398  return SWITCH_STATUS_SUCCESS;
399 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:311
#define SWITCH_CHANNEL_LOG
int64_t switch_time_t
Definition: switch_apr.h:188
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.

◆ timer_init()

static switch_status_t timer_init ( switch_timer_t timer)
static

Definition at line 699 of file switch_time.c.

References timer_matrix::cond, timer_matrix::count, do_sleep(), globals, if(), switch_timer::interval, switch_timer::memory_pool, switch_runtime::microseconds_per_tick, module_pool, timer_matrix::mutex, switch_timer::private_info, timer_private::ready, timer_private::reference, timer_private::roll, timer_matrix::roll, runtime, timer_private::start, switch_timer::start, SWITCH_CHANNEL_LOG, switch_core_alloc, SWITCH_LOG_NOTICE, switch_log_printf(), SWITCH_LOG_WARNING, switch_micro_time_now(), switch_mutex_init(), switch_mutex_lock(), SWITCH_MUTEX_NESTED, switch_mutex_unlock(), SWITCH_STATUS_FALSE, SWITCH_STATUS_MEMERR, SWITCH_STATUS_SUCCESS, switch_thread_cond_create(), switch_time_sync(), TFD, timer_matrix::tick, and switch_runtime::tipping_point.

Referenced by SWITCH_MODULE_LOAD_FUNCTION().

700 {
701  timer_private_t *private_info;
702  int sanity = 0;
703 
704  timer->start = switch_micro_time_now();
705 
706  if (timer->interval == 1) {
707  switch_mutex_lock(globals.mutex);
708  globals.timer_count++;
710  return SWITCH_STATUS_SUCCESS;
711  }
712 
713 #ifdef HAVE_TIMERFD_CREATE
714  if (TFD == 2) {
715  return _timerfd_init(timer);
716  }
717 #endif
718 
719  while (globals.STARTED == 0) {
720  do_sleep(100000);
721  if (++sanity == 300) {
722  abort();
723  }
724  }
725 
726  if (globals.RUNNING != 1 || !globals.mutex || timer->interval < 1) {
727  return SWITCH_STATUS_FALSE;
728  }
729 
730  if ((private_info = switch_core_alloc(timer->memory_pool, sizeof(*private_info)))) {
731  switch_mutex_lock(globals.mutex);
732  if (!TIMER_MATRIX[timer->interval].mutex) {
735  }
736  TIMER_MATRIX[timer->interval].count++;
738  timer->private_info = private_info;
739  private_info->start = private_info->reference = (switch_size_t)TIMER_MATRIX[timer->interval].tick;
740  private_info->start -= 2; /* switch_core_timer_init sets samplecount to samples, this makes first next() step once */
741  private_info->roll = TIMER_MATRIX[timer->interval].roll;
742  private_info->ready = 1;
743 
744  if (runtime.microseconds_per_tick > 10000 && (timer->interval % (int)(runtime.microseconds_per_tick / 1000)) != 0 && (timer->interval % 10) == 0) {
745  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Increasing global timer resolution to 10ms to handle interval %d\n", timer->interval);
747  }
748 
749  if (timer->interval > 0 && (timer->interval < (int)(runtime.microseconds_per_tick / 1000) || (timer->interval % 10) != 0)) {
750  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Increasing global timer resolution to 1ms to handle interval %d\n", timer->interval);
753  }
754 
755  switch_mutex_lock(globals.mutex);
756  globals.timer_count++;
757  if (runtime.tipping_point && globals.timer_count == (runtime.tipping_point + 1)) {
758  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Crossed tipping point of %u, shifting into high-gear.\n", runtime.tipping_point);
759  }
761 
762  return SWITCH_STATUS_SUCCESS;
763  }
764 
765  return SWITCH_STATUS_MEMERR;
766 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:311
void switch_time_sync(void)
Definition: switch_time.c:609
switch_status_t switch_thread_cond_create(switch_thread_cond_t **cond, switch_memory_pool_t *pool)
Definition: switch_apr.c:373
#define SWITCH_CHANNEL_LOG
static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
Definition: switch_time.c:138
static int TFD
Definition: switch_time.c:81
static struct @9 globals
static switch_memory_pool_t * module_pool
Definition: switch_time.c:100
struct switch_runtime runtime
Definition: switch_core.c:86
uint32_t microseconds_per_tick
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
if((uint32_t)(unpack->cur - unpack->buf) > unpack->buflen)
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_memory_pool_t * memory_pool
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684
switch_size_t start
Definition: switch_time.c:122
uint32_t roll
Definition: switch_time.c:131
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:293
uintptr_t switch_size_t
switch_size_t reference
Definition: switch_time.c:121
uint32_t count
Definition: switch_time.c:130
uint32_t ready
Definition: switch_time.c:124
switch_thread_cond_t * cond
Definition: switch_time.c:133
uint32_t tipping_point
switch_mutex_t * mutex
Definition: switch_time.c:132
uint64_t tick
Definition: switch_time.c:129
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
uint32_t roll
Definition: switch_time.c:123
static void do_sleep(switch_interval_time_t t)
Definition: switch_time.c:151

◆ timer_next()

static switch_status_t timer_next ( switch_timer_t timer)
static

Definition at line 840 of file switch_time.c.

References check_roll, do_sleep(), globals, switch_timer::interval, MATRIX, mutex, switch_timer::private_info, timer_private::ready, timer_private::reference, runtime, switch_mutex_lock(), switch_mutex_unlock(), switch_os_yield(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_thread_cond_wait(), TFD, timer_matrix::tick, switch_timer::tick, timer_step(), and switch_runtime::tipping_point.

Referenced by SWITCH_MODULE_LOAD_FUNCTION().

841 {
842  timer_private_t *private_info;
843 
844 #ifdef DISABLE_1MS_COND
845  int cond_index = timer->interval;
846 #else
847  int cond_index = 1;
848 #endif
849  int delta;
850 
851  if (timer->interval == 1) {
852  return SWITCH_STATUS_FALSE;
853  }
854 
855 #ifdef HAVE_TIMERFD_CREATE
856  if (TFD == 2) {
857  return _timerfd_next(timer);
858  }
859 #endif
860 
861  private_info = timer->private_info;
862 
863  delta = (int) (private_info->reference - TIMER_MATRIX[timer->interval].tick);
864 
865 
866 
867  /* sync up timer if it's not been called for a while otherwise it will return instantly several times until it catches up */
868  if (delta < -1) {
869  private_info->reference = (switch_size_t)(timer->tick = TIMER_MATRIX[timer->interval].tick);
870  }
871  timer_step(timer);
872 
873  if (!MATRIX) {
874  do_sleep(1000 * timer->interval);
875  goto end;
876  }
877 
878  while (globals.RUNNING == 1 && private_info->ready && TIMER_MATRIX[timer->interval].tick < private_info->reference) {
879  check_roll();
880 
881  switch_os_yield();
882 
883 
884  if (runtime.tipping_point && globals.timer_count >= runtime.tipping_point) {
885  globals.use_cond_yield = 0;
886  } else {
887  if (globals.use_cond_yield == 1) {
888  switch_mutex_lock(TIMER_MATRIX[cond_index].mutex);
889  if (TIMER_MATRIX[timer->interval].tick < private_info->reference) {
890  switch_thread_cond_wait(TIMER_MATRIX[cond_index].cond, TIMER_MATRIX[cond_index].mutex);
891  }
893  } else {
894  do_sleep(1000);
895  }
896  }
897  }
898 
899  end:
900  return globals.RUNNING == 1 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
901 }
#define check_roll()
Definition: switch_time.c:768
static switch_status_t timer_step(switch_timer_t *timer)
Definition: switch_time.c:775
void switch_os_yield(void)
Definition: switch_time.c:142
static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
Definition: switch_time.c:138
static int TFD
Definition: switch_time.c:81
static struct @9 globals
switch_status_t switch_thread_cond_wait(switch_thread_cond_t *cond, switch_mutex_t *mutex)
Definition: switch_apr.c:378
struct switch_runtime runtime
Definition: switch_core.c:86
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
uintptr_t switch_size_t
switch_size_t reference
Definition: switch_time.c:121
uint32_t ready
Definition: switch_time.c:124
uint32_t tipping_point
uint64_t tick
Definition: switch_time.c:129
static void do_sleep(switch_interval_time_t t)
Definition: switch_time.c:151
switch_mutex_t * mutex
Definition: switch_time.c:106
static int MATRIX
Definition: switch_time.c:89

◆ timer_step()

static switch_status_t timer_step ( switch_timer_t timer)
static

Definition at line 775 of file switch_time.c.

References check_roll, globals, switch_timer::interval, switch_timer::private_info, timer_private::ready, timer_private::reference, switch_timer::samplecount, switch_timer::samples, timer_private::start, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, TFD, and UINT32_MAX.

Referenced by SWITCH_MODULE_LOAD_FUNCTION(), timer_check(), timer_next(), and timer_sync().

776 {
777  timer_private_t *private_info;
778  uint64_t samples;
779 
780  if (timer->interval == 1) {
781  return SWITCH_STATUS_FALSE;
782  }
783 
784 #ifdef HAVE_TIMERFD_CREATE
785  if (TFD == 2) {
786  return _timerfd_step(timer);
787  }
788 #endif
789 
790  private_info = timer->private_info;
791 
792  if (globals.RUNNING != 1 || private_info->ready == 0) {
793  return SWITCH_STATUS_FALSE;
794  }
795 
796  check_roll();
797  samples = (uint64_t)timer->samples * (private_info->reference - private_info->start);
798 
799  if (samples > UINT32_MAX) {
800  private_info->start = private_info->reference - 1; /* Must have a diff */
801  samples = timer->samples;
802  }
803 
804  timer->samplecount = (uint32_t) samples;
805  private_info->reference++;
806 
807  return SWITCH_STATUS_SUCCESS;
808 }
#define check_roll()
Definition: switch_time.c:768
static int TFD
Definition: switch_time.c:81
static struct @9 globals
switch_size_t start
Definition: switch_time.c:122
#define UINT32_MAX
Definition: switch_time.c:48
switch_size_t reference
Definition: switch_time.c:121
uint32_t ready
Definition: switch_time.c:124

◆ timer_sync()

static switch_status_t timer_sync ( switch_timer_t timer)
static

Definition at line 810 of file switch_time.c.

References globals, switch_timer::interval, switch_timer::private_info, timer_private::ready, timer_private::reference, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, TFD, timer_matrix::tick, switch_timer::tick, timer_generic_sync(), and timer_step().

Referenced by SWITCH_MODULE_LOAD_FUNCTION().

811 {
812  timer_private_t *private_info;
813 
814  if (timer->interval == 1) {
815  return timer_generic_sync(timer);
816  }
817 
818 #ifdef HAVE_TIMERFD_CREATE
819  if (TFD == 2) {
820  return timer_generic_sync(timer);
821  }
822 #endif
823 
824  private_info = timer->private_info;
825 
826  if (globals.RUNNING != 1 || private_info->ready == 0) {
827  return SWITCH_STATUS_FALSE;
828  }
829 
830  /* sync the clock */
831  private_info->reference = (switch_size_t)(timer->tick = TIMER_MATRIX[timer->interval].tick);
832 
833  /* apply timestamp */
834  timer_step(timer);
835 
836  return SWITCH_STATUS_SUCCESS;
837 }
static switch_status_t timer_step(switch_timer_t *timer)
Definition: switch_time.c:775
static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
Definition: switch_time.c:138
static int TFD
Definition: switch_time.c:81
static struct @9 globals
uintptr_t switch_size_t
switch_size_t reference
Definition: switch_time.c:121
uint32_t ready
Definition: switch_time.c:124
static switch_status_t timer_generic_sync(switch_timer_t *timer)
Definition: switch_time.c:382
uint64_t tick
Definition: switch_time.c:129

◆ timesub()

static void timesub ( const time_t *const  timep,
const long  offset,
register const struct state *const  sp,
register struct tm *const  tmp 
)
static

Definition at line 2346 of file switch_time.c.

References DAYSPERNYEAR, DAYSPERWEEK, EPOCH_WDAY, EPOCH_YEAR, ip, isleap, state::leapcnt, LEAPS_THRU_END_OF, lsinfo::ls_corr, lsinfo::ls_trans, state::lsis, mon_lengths, SECSPERDAY, SECSPERHOUR, SECSPERMIN, switch_assert, TM_YEAR_BASE, while(), and year_lengths.

Referenced by tztime().

2347 {
2348  register const struct lsinfo *lp;
2349  register long days;
2350  register time_t rem;
2351  register int y;
2352  register int yleap;
2353  register const int *ip;
2354  register long corr;
2355  register int hit;
2356  register int i;
2357 
2358  switch_assert(timep != NULL);
2359  switch_assert(sp != NULL);
2360  switch_assert(tmp != NULL);
2361 
2362  corr = 0;
2363  hit = 0;
2364  i = (sp == NULL) ? 0 : sp->leapcnt;
2365 
2366  while (--i >= 0) {
2367  lp = &sp->lsis[i];
2368  if (*timep >= lp->ls_trans) {
2369  if (*timep == lp->ls_trans) {
2370  hit = ((i == 0 && lp->ls_corr > 0) || (i > 0 && lp->ls_corr > sp->lsis[i - 1].ls_corr));
2371  if (hit)
2372  while (i > 0 && sp->lsis[i].ls_trans == sp->lsis[i - 1].ls_trans + 1 && sp->lsis[i].ls_corr == sp->lsis[i - 1].ls_corr + 1) {
2373  ++hit;
2374  --i;
2375  }
2376  }
2377  corr = lp->ls_corr;
2378  break;
2379  }
2380  }
2381  days = (long) (*timep / SECSPERDAY);
2382  rem = *timep % SECSPERDAY;
2383 
2384 
2385 #ifdef mc68k
2386  /* If this is for CPU bugs workarounds, i would remove this anyway. Who would use it on an old mc68k ? */
2387  if (*timep == 0x80000000) {
2388  /*
2389  ** A 3B1 muffs the division on the most negative number.
2390  */
2391  days = -24855;
2392  rem = -11648;
2393  }
2394 #endif
2395 
2396  rem += (offset - corr);
2397  while (rem < 0) {
2398  rem += SECSPERDAY;
2399  --days;
2400  }
2401  while (rem >= SECSPERDAY) {
2402  rem -= SECSPERDAY;
2403  ++days;
2404  }
2405  tmp->tm_hour = (int) (rem / SECSPERHOUR);
2406  rem = rem % SECSPERHOUR;
2407  tmp->tm_min = (int) (rem / SECSPERMIN);
2408 
2409  /*
2410  ** A positive leap second requires a special
2411  ** representation. This uses "... ??:59:60" et seq.
2412  */
2413  tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
2414  tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
2415 
2416  if (tmp->tm_wday < 0)
2417  tmp->tm_wday += DAYSPERWEEK;
2418 
2419  y = EPOCH_YEAR;
2420 
2421 #define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
2422 
2423  while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
2424  register int newy;
2425 
2426  newy = (int) (y + days / DAYSPERNYEAR);
2427  if (days < 0)
2428  --newy;
2429  days -= (newy - y) * DAYSPERNYEAR + LEAPS_THRU_END_OF(newy - 1) - LEAPS_THRU_END_OF(y - 1);
2430  y = newy;
2431  }
2432 
2433  tmp->tm_year = y - TM_YEAR_BASE;
2434  tmp->tm_yday = (int) days;
2435 
2436  ip = mon_lengths[yleap];
2437 
2438  for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
2439  days = days - (long) ip[tmp->tm_mon];
2440 
2441  tmp->tm_mday = (int) (days + 1);
2442  tmp->tm_isdst = 0;
2443 #if defined(HAVE_STRUCT_TM_TM_GMTOFF)
2444  tmp->tm_gmtoff = offset;
2445 #endif
2446 }
#define SECSPERMIN
Definition: switch_time.c:1701
static const int year_lengths[2]
Definition: switch_time.c:1856
#define EPOCH_WDAY
Definition: switch_time.c:1805
static const int mon_lengths[2][MONSPERYEAR]
Definition: switch_time.c:1851
long ls_corr
Definition: switch_time.c:1834
#define switch_assert(expr)
Definition: switch_time.c:2343
#define isleap(y)
Definition: switch_time.c:1749
char * ip
Definition: switch_msrp.c:60
#define SECSPERHOUR
Definition: switch_time.c:1707
#define SECSPERDAY
Definition: switch_time.c:1708
#define LEAPS_THRU_END_OF(y)
#define DAYSPERWEEK
Definition: switch_time.c:1704
#define TM_YEAR_BASE
Definition: switch_time.c:1802
while(unpack->bits_cur<=SWITCH_BITS_PER_BYTE)
#define EPOCH_YEAR
Definition: switch_time.c:1804
time_t ls_trans
Definition: switch_time.c:1833
#define DAYSPERNYEAR
Definition: switch_time.c:1705

◆ tm2switchtime()

static void tm2switchtime ( struct tm *  tm,
switch_time_exp_t xt 
)
static

Definition at line 1342 of file switch_time.c.

References memset(), switch_time_exp_t::tm_gmtoff, switch_time_exp_t::tm_hour, switch_time_exp_t::tm_isdst, switch_time_exp_t::tm_mday, switch_time_exp_t::tm_min, switch_time_exp_t::tm_mon, switch_time_exp_t::tm_sec, switch_time_exp_t::tm_wday, switch_time_exp_t::tm_yday, and switch_time_exp_t::tm_year.

Referenced by switch_strftime_tz(), and switch_time_exp_tz_name().

1343 {
1344 
1345  if (!xt || !tm) {
1346  return;
1347  }
1348  memset(xt, 0, sizeof(*xt));
1349 
1350  xt->tm_sec = tm->tm_sec;
1351  xt->tm_min = tm->tm_min;
1352  xt->tm_hour = tm->tm_hour;
1353  xt->tm_mday = tm->tm_mday;
1354  xt->tm_mon = tm->tm_mon;
1355  xt->tm_year = tm->tm_year;
1356  xt->tm_wday = tm->tm_wday;
1357  xt->tm_yday = tm->tm_yday;
1358  xt->tm_isdst = tm->tm_isdst;
1359 
1360 #if defined(HAVE_STRUCT_TM_TM_GMTOFF)
1361  xt->tm_gmtoff = tm->tm_gmtoff;
1362 #endif
1363 
1364  return;
1365 }
memset(buf, 0, buflen)

◆ transtime()

static time_t transtime ( const time_t  janfirst,
const int  year,
register const struct rule *const  rulep,
const long  offset 
)
static

Definition at line 2034 of file switch_time.c.

References DAY_OF_YEAR, DAYSPERWEEK, INITIALIZE, isleap, JULIAN_DAY, mon_lengths, MONTH_NTH_DAY_OF_WEEK, rule::r_day, rule::r_mon, rule::r_time, rule::r_type, rule::r_week, SECSPERDAY, and value.

Referenced by tzparse().

2035 {
2036  register int leapyear;
2037  register time_t value;
2038  register int i;
2039  int d, m1, yy0, yy1, yy2, dow;
2040 
2041  INITIALIZE(value);
2042  leapyear = isleap(year);
2043  switch (rulep->r_type) {
2044 
2045  case JULIAN_DAY:
2046  /*
2047  ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
2048  ** years.
2049  ** In non-leap years, or if the day number is 59 or less, just
2050  ** add SECSPERDAY times the day number-1 to the time of
2051  ** January 1, midnight, to get the day.
2052  */
2053  value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
2054  if (leapyear && rulep->r_day >= 60)
2055  value += SECSPERDAY;
2056  break;
2057 
2058  case DAY_OF_YEAR:
2059  /*
2060  ** n - day of year.
2061  ** Just add SECSPERDAY times the day number to the time of
2062  ** January 1, midnight, to get the day.
2063  */
2064  value = janfirst + rulep->r_day * SECSPERDAY;
2065  break;
2066 
2067  case MONTH_NTH_DAY_OF_WEEK:
2068  /*
2069  ** Mm.n.d - nth "dth day" of month m.
2070  */
2071  value = janfirst;
2072  for (i = 0; i < rulep->r_mon - 1; ++i)
2073  value += mon_lengths[leapyear][i] * SECSPERDAY;
2074 
2075  /*
2076  ** Use Zeller's Congruence to get day-of-week of first day of
2077  ** month.
2078  */
2079  m1 = (rulep->r_mon + 9) % 12 + 1;
2080  yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
2081  yy1 = yy0 / 100;
2082  yy2 = yy0 % 100;
2083  dow = ((26 * m1 - 2) / 10 + 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
2084  if (dow < 0)
2085  dow += DAYSPERWEEK;
2086 
2087  /*
2088  ** "dow" is the day-of-week of the first day of the month. Get
2089  ** the day-of-month (zero-origin) of the first "dow" day of the
2090  ** month.
2091  */
2092  d = rulep->r_day - dow;
2093  if (d < 0)
2094  d += DAYSPERWEEK;
2095  for (i = 1; i < rulep->r_week; ++i) {
2096  if (d + DAYSPERWEEK >= mon_lengths[leapyear][rulep->r_mon - 1])
2097  break;
2098  d += DAYSPERWEEK;
2099  }
2100 
2101  /*
2102  ** "d" is the day-of-month (zero-origin) of the day we want.
2103  */
2104  value += d * SECSPERDAY;
2105  break;
2106  }
2107 
2108  /*
2109  ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
2110  ** question. To get the Epoch-relative time of the specified local
2111  ** time on that day, add the transition time and the current offset
2112  ** from UTC.
2113  */
2114  return value + rulep->r_time + offset;
2115 }
#define JULIAN_DAY
Definition: switch_time.c:1711
const char *const const char *const const cJSON *const value
static const int mon_lengths[2][MONSPERYEAR]
Definition: switch_time.c:1851
#define INITIALIZE(x)
Definition: switch_time.c:1776
#define isleap(y)
Definition: switch_time.c:1749
#define SECSPERDAY
Definition: switch_time.c:1708
#define DAYSPERWEEK
Definition: switch_time.c:1704
#define MONTH_NTH_DAY_OF_WEEK
Definition: switch_time.c:1713
#define DAY_OF_YEAR
Definition: switch_time.c:1712

◆ tzparse()

static int tzparse ( const char *  name,
register struct state *const  sp,
const int  lastditch 
)
static

Definition at line 2124 of file switch_time.c.

References state::ats, state::charcnt, state::chars, EPOCH_YEAR, FALSE, getoffset(), getrule(), getzname(), if(), INITIALIZE, isleap, state::leapcnt, name, SECSPERDAY, SECSPERHOUR, state::timecnt, transtime(), TRUE, ttinfo::tt_abbrind, ttinfo::tt_gmtoff, ttinfo::tt_isdst, ttinfo::tt_ttisgmt, ttinfo::tt_ttisstd, state::ttis, state::typecnt, state::types, TZ_MAX_TIMES, and year_lengths.

Referenced by tztime().

2125 {
2126  const char *stdname;
2127  const char *dstname;
2128  size_t stdlen;
2129  size_t dstlen;
2130  long stdoffset;
2131  long dstoffset;
2132  register time_t *atp;
2133  register unsigned char *typep;
2134  register char *cp;
2135 
2136 
2137  INITIALIZE(dstname);
2138  stdname = name;
2139 
2140  if (lastditch) {
2141  stdlen = strlen(name); /* length of standard zone name */
2142  name += stdlen;
2143  if (stdlen >= sizeof sp->chars)
2144  stdlen = (sizeof sp->chars) - 1;
2145  stdoffset = 0;
2146  } else {
2147  name = getzname(name);
2148  stdlen = name - stdname;
2149  if (stdlen < 3)
2150  return -1;
2151  if (*name == '\0')
2152  return -1;
2153  name = getoffset(name, &stdoffset);
2154  if (name == NULL)
2155  return -1;
2156  }
2157 
2158  sp->leapcnt = 0; /* so, we're off a little */
2159 
2160  if (*name != '\0') {
2161  dstname = name;
2162  name = getzname(name);
2163  dstlen = name - dstname; /* length of DST zone name */
2164  if (dstlen < 3)
2165  return -1;
2166  if (*name != '\0' && *name != ',' && *name != ';') {
2167  name = getoffset(name, &dstoffset);
2168  if (name == NULL)
2169  return -1;
2170  } else
2171  dstoffset = stdoffset - SECSPERHOUR;
2172 
2173  /* Go parsing the daylight saving stuff */
2174  if (*name == ',' || *name == ';') {
2175  struct rule start;
2176  struct rule end;
2177  register int year;
2178  register time_t janfirst;
2179  time_t starttime;
2180  time_t endtime;
2181 
2182  ++name;
2183  if ((name = getrule(name, &start)) == NULL)
2184  return -1;
2185  if (*name++ != ',')
2186  return -1;
2187  if ((name = getrule(name, &end)) == NULL)
2188  return -1;
2189  if (*name != '\0')
2190  return -1;
2191 
2192  sp->typecnt = 2; /* standard time and DST */
2193 
2194  /*
2195  ** Two transitions per year, from EPOCH_YEAR to 2037.
2196  */
2197  sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1);
2198 
2199  if (sp->timecnt > TZ_MAX_TIMES)
2200  return -1;
2201 
2202  sp->ttis[0].tt_gmtoff = -dstoffset;
2203  sp->ttis[0].tt_isdst = 1;
2204  sp->ttis[0].tt_abbrind = (int) (stdlen + 1);
2205  sp->ttis[1].tt_gmtoff = -stdoffset;
2206  sp->ttis[1].tt_isdst = 0;
2207  sp->ttis[1].tt_abbrind = 0;
2208 
2209  atp = sp->ats;
2210  typep = sp->types;
2211  janfirst = 0;
2212 
2213  for (year = EPOCH_YEAR; year <= 2037; ++year) {
2214  starttime = transtime(janfirst, year, &start, stdoffset);
2215  endtime = transtime(janfirst, year, &end, dstoffset);
2216  if (starttime > endtime) {
2217  *atp++ = endtime;
2218  *typep++ = 1; /* DST ends */
2219  *atp++ = starttime;
2220  *typep++ = 0; /* DST begins */
2221  } else {
2222  *atp++ = starttime;
2223  *typep++ = 0; /* DST begins */
2224  *atp++ = endtime;
2225  *typep++ = 1; /* DST ends */
2226  }
2227 
2228  janfirst += year_lengths[isleap(year)] * SECSPERDAY;
2229  }
2230 
2231  } else {
2232  register long theirstdoffset;
2233  register long theirdstoffset;
2234  register long theiroffset;
2235  register int isdst;
2236  register int i;
2237  register int j;
2238 
2239  if (*name != '\0')
2240  return -1;
2241  /*
2242  Initial values of theirstdoffset and theirdstoffset.
2243  */
2244  theirstdoffset = 0;
2245  for (i = 0; i < sp->timecnt; ++i) {
2246  j = sp->types[i];
2247  if (!sp->ttis[j].tt_isdst) {
2248  theirstdoffset = -sp->ttis[j].tt_gmtoff;
2249  break;
2250  }
2251  }
2252  theirdstoffset = 0;
2253  for (i = 0; i < sp->timecnt; ++i) {
2254  j = sp->types[i];
2255  if (sp->ttis[j].tt_isdst) {
2256  theirdstoffset = -sp->ttis[j].tt_gmtoff;
2257  break;
2258  }
2259  }
2260  /*
2261  ** Initially we're assumed to be in standard time.
2262  */
2263  isdst = FALSE;
2264  /*
2265  ** Now juggle transition times and types
2266  ** tracking offsets as you do.
2267  */
2268  for (i = 0; i < sp->timecnt; ++i) {
2269  j = sp->types[i];
2270  sp->types[i] = (unsigned char) sp->ttis[j].tt_isdst;
2271  if (sp->ttis[j].tt_ttisgmt) {
2272  /* No adjustment to transition time */
2273  } else {
2274  /*
2275  ** If summer time is in effect, and the
2276  ** transition time was not specified as
2277  ** standard time, add the summer time
2278  ** offset to the transition time;
2279  ** otherwise, add the standard time
2280  ** offset to the transition time.
2281  */
2282  /*
2283  ** Transitions from DST to DDST
2284  ** will effectively disappear since
2285  ** POSIX provides for only one DST
2286  ** offset.
2287  */
2288  if (isdst && !sp->ttis[j].tt_ttisstd) {
2289  sp->ats[i] += dstoffset - theirdstoffset;
2290  } else {
2291  sp->ats[i] += stdoffset - theirstdoffset;
2292  }
2293  }
2294  theiroffset = -sp->ttis[j].tt_gmtoff;
2295  if (sp->ttis[j].tt_isdst)
2296  theirdstoffset = theiroffset;
2297  else
2298  theirstdoffset = theiroffset;
2299  }
2300  /*
2301  ** Finally, fill in ttis.
2302  ** ttisstd and ttisgmt need not be handled.
2303  */
2304  sp->ttis[0].tt_gmtoff = -stdoffset;
2305  sp->ttis[0].tt_isdst = FALSE;
2306  sp->ttis[0].tt_abbrind = 0;
2307  sp->ttis[1].tt_gmtoff = -dstoffset;
2308  sp->ttis[1].tt_isdst = TRUE;
2309  sp->ttis[1].tt_abbrind = (int) (stdlen + 1);
2310  sp->typecnt = 2;
2311  }
2312  } else {
2313  dstlen = 0;
2314  sp->typecnt = 1; /* only standard time */
2315  sp->timecnt = 0;
2316  sp->ttis[0].tt_gmtoff = -stdoffset;
2317  sp->ttis[0].tt_isdst = 0;
2318  sp->ttis[0].tt_abbrind = 0;
2319  }
2320 
2321  sp->charcnt = (int) (stdlen + 1);
2322  if (dstlen != 0)
2323  sp->charcnt += (int) (dstlen + 1);
2324  if ((size_t) sp->charcnt > sizeof sp->chars)
2325  return -1;
2326  cp = sp->chars;
2327  (void) strncpy(cp, stdname, stdlen);
2328  cp += stdlen;
2329  *cp++ = '\0';
2330  if (dstlen != 0) {
2331  (void) strncpy(cp, dstname, dstlen);
2332  *(cp + dstlen) = '\0';
2333  }
2334  return 0;
2335 }
static const char * getoffset(register const char *strp, long *const offsetp)
Definition: switch_time.c:1956
#define TZ_MAX_TIMES
Definition: switch_time.c:1664
static const int year_lengths[2]
Definition: switch_time.c:1856
if((uint32_t)(unpack->cur - unpack->buf) > unpack->buflen)
static time_t transtime(const time_t janfirst, const int year, register const struct rule *const rulep, const long offset)
Definition: switch_time.c:2034
#define TRUE
Definition: switch_time.c:1648
#define INITIALIZE(x)
Definition: switch_time.c:1776
#define isleap(y)
Definition: switch_time.c:1749
static const char * getzname(register const char *strp)
Definition: switch_time.c:1872
#define SECSPERHOUR
Definition: switch_time.c:1707
#define SECSPERDAY
Definition: switch_time.c:1708
const char *const name
Definition: switch_cJSON.h:250
#define EPOCH_YEAR
Definition: switch_time.c:1804
#define FALSE
Definition: switch_time.c:1652
static const char * getrule(const char *strp, register struct rule *const rulep)
Definition: switch_time.c:1980

◆ tztime()

static void tztime ( const time_t *const  timep,
const char *  tzstring,
struct tm *const  tmp 
)
static

Definition at line 2452 of file switch_time.c.

References state::ats, state::chars, FALSE, gmt, memset(), state::timecnt, timesub(), ttinfo::tt_abbrind, ttinfo::tt_gmtoff, ttinfo::tt_isdst, state::ttis, state::typecnt, state::types, and tzparse().

Referenced by event_handler(), switch_strftime_tz(), and switch_time_exp_tz_name().

2453 {
2454  struct state *tzptr, *sp;
2455  const time_t t = *timep;
2456  register int i;
2457  register const struct ttinfo *ttisp;
2458 
2459  if (tzstring == NULL)
2460  tzstring = gmt;
2461 
2462  tzptr = (struct state *) malloc(sizeof(struct state));
2463  sp = tzptr;
2464 
2465  if (tzptr != NULL) {
2466 
2467  memset(tzptr, 0, sizeof(struct state));
2468 
2469  (void) tzparse(tzstring, tzptr, FALSE);
2470 
2471  if (sp->timecnt == 0 || t < sp->ats[0]) {
2472  i = 0;
2473  while (sp->ttis[i].tt_isdst)
2474  if (++i >= sp->typecnt) {
2475  i = 0;
2476  break;
2477  }
2478  } else {
2479  for (i = 1; i < sp->timecnt; ++i)
2480  if (t < sp->ats[i])
2481  break;
2482  i = sp->types[i - 1]; // DST begin or DST end
2483  }
2484  ttisp = &sp->ttis[i];
2485 
2486  /*
2487  To get (wrong) behavior that's compatible with System V Release 2.0
2488  you'd replace the statement below with
2489  t += ttisp->tt_gmtoff;
2490  timesub(&t, 0L, sp, tmp);
2491  */
2492  if (tmp != NULL) { /* Just a check not to assert */
2493  timesub(&t, ttisp->tt_gmtoff, sp, tmp);
2494  tmp->tm_isdst = ttisp->tt_isdst;
2495 #if defined(HAVE_STRUCT_TM_TM_ZONE)
2496  tmp->tm_zone = &sp->chars[ttisp->tt_abbrind];
2497 #endif
2498  }
2499 
2500  free(tzptr);
2501  }
2502 
2503 }
time_t ats[TZ_MAX_TIMES]
Definition: switch_time.c:1843
static const char gmt[]
Definition: switch_time.c:1812
static void timesub(const time_t *const timep, const long offset, register const struct state *const sp, register struct tm *const tmp)
Definition: switch_time.c:2346
static int tzparse(const char *name, register struct state *const sp, const int lastditch)
Definition: switch_time.c:2124
long tt_gmtoff
Definition: switch_time.c:1825
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: switch_time.c:1845
unsigned char types[TZ_MAX_TIMES]
Definition: switch_time.c:1844
int timecnt
Definition: switch_time.c:1840
char chars[CHARS_DEF]
Definition: switch_time.c:1846
int tt_abbrind
Definition: switch_time.c:1827
int tt_isdst
Definition: switch_time.c:1826
int typecnt
Definition: switch_time.c:1841
#define FALSE
Definition: switch_time.c:1652
memset(buf, 0, buflen)

◆ win32_init_timers()

static void win32_init_timers ( void  )
static

Definition at line 989 of file switch_time.c.

References count.

Referenced by SWITCH_MODULE_LOAD_FUNCTION(), and SWITCH_MODULE_RUNTIME_FUNCTION().

990 {
991 #ifdef WIN32
992  OSVERSIONINFOEX version_info; /* Used to fetch current OS version from Windows */
993 
994  EnterCriticalSection(&timer_section);
995 
996  ZeroMemory(&version_info, sizeof(OSVERSIONINFOEX));
997  version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
998 
999  /* Check if we should use timeGetTime() (pre-Vista) or QueryPerformanceCounter() (Vista and later) */
1000 
1001  if (GetVersionEx((OSVERSIONINFO*) &version_info)) {
1002  if (version_info.dwPlatformId == VER_PLATFORM_WIN32_NT && version_info.dwMajorVersion >= 6) {
1003  if (QueryPerformanceFrequency((LARGE_INTEGER*)&win32_qpc_freq) && win32_qpc_freq > 0) {
1004  /* At least Vista, and QueryPerformanceFrequency() suceeded, enable qpc */
1005  win32_use_qpc = 1;
1006  } else {
1007  /* At least Vista, but QueryPerformanceFrequency() failed, disable qpc */
1008  win32_use_qpc = 0;
1009  }
1010  } else {
1011  /* Older then Vista, disable qpc */
1012  win32_use_qpc = 0;
1013  }
1014  } else {
1015  /* Unknown version - we want at least Vista, disable qpc */
1016  win32_use_qpc = 0;
1017  }
1018 
1019  if (win32_use_qpc) {
1020  uint64_t count = 0;
1021 
1022  if (!QueryPerformanceCounter((LARGE_INTEGER*)&count) || count == 0) {
1023  /* Call to QueryPerformanceCounter() failed, disable qpc again */
1024  win32_use_qpc = 0;
1025  }
1026  }
1027 
1028  if (!win32_use_qpc) {
1029  /* This will enable timeGetTime() instead, qpc init failed */
1030  win32_last_get_time_tick = timeGetTime();
1031  win32_tick_time_since_start = win32_last_get_time_tick;
1032  }
1033 
1034  LeaveCriticalSection(&timer_section);
1035 #endif
1036 }
int count
Definition: switch_cJSON.h:204

Variable Documentation

◆ COND

int COND = 1
static

Definition at line 87 of file switch_time.c.

Referenced by SWITCH_MODULE_RUNTIME_FUNCTION(), and switch_time_set_cond_yield().

◆ globals

struct { ... } globals

◆ gmt

const char gmt[] = "GMT"
static

Definition at line 1812 of file switch_time.c.

Referenced by tztime().

◆ last_time

switch_time_t last_time = 0
static

Definition at line 607 of file switch_time.c.

Referenced by switch_time_sync().

◆ MATRIX

int MATRIX = 1
static

◆ module_pool

switch_memory_pool_t* module_pool = NULL
static

◆ mon_lengths

const int mon_lengths[2][MONSPERYEAR]
static
Initial value:
= {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
}

Definition at line 1851 of file switch_time.c.

Referenced by timesub(), and transtime().

◆ MONO

int MONO = 0
static

◆ mutex

◆ NANO

int NANO = 0
static

◆ NODE

switch_event_node_t* NODE = NULL
static

Definition at line 1377 of file switch_time.c.

◆ OFFSET

int OFFSET = 0
static

Definition at line 85 of file switch_time.c.

Referenced by do_sleep(), and switch_time_calibrate_clock().

◆ RUNNING

int32_t RUNNING

Definition at line 103 of file switch_time.c.

◆ STARTED

int32_t STARTED

Definition at line 104 of file switch_time.c.

◆ SYSTEM_TIME

int SYSTEM_TIME = 0
static

◆ TFD

int TFD = 0
static

◆ timer_count

uint32_t timer_count

Definition at line 107 of file switch_time.c.

◆ TIMER_MATRIX

timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
static

Definition at line 138 of file switch_time.c.

◆ TIMEZONES_LIST

switch_timezones_list_t TIMEZONES_LIST = { 0 }
static

Definition at line 1376 of file switch_time.c.

◆ use_cond_yield

int32_t use_cond_yield

Definition at line 105 of file switch_time.c.

◆ year_lengths

const int year_lengths[2]
static
Initial value:
= {
}
#define DAYSPERNYEAR
Definition: switch_time.c:1705
#define DAYSPERLYEAR
Definition: switch_time.c:1706

Definition at line 1856 of file switch_time.c.

Referenced by timesub(), and tzparse().