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 1741 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 1808 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 1706 of file switch_time.c.

Referenced by getrule(), and transtime().

◆ DAYSPERLYEAR

#define DAYSPERLYEAR   366

Definition at line 1700 of file switch_time.c.

Referenced by getrule().

◆ DAYSPERNYEAR

#define DAYSPERNYEAR   365

Definition at line 1699 of file switch_time.c.

Referenced by getrule(), and timesub().

◆ DAYSPERWEEK

#define DAYSPERWEEK   7

Definition at line 1698 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 1799 of file switch_time.c.

Referenced by timesub().

◆ EPOCH_WDAY [2/2]

#define EPOCH_WDAY   TM_THURSDAY

Definition at line 1799 of file switch_time.c.

◆ EPOCH_YEAR [1/2]

#define EPOCH_YEAR   1970

Definition at line 1798 of file switch_time.c.

Referenced by timesub(), and tzparse().

◆ EPOCH_YEAR [2/2]

#define EPOCH_YEAR   1970

Definition at line 1798 of file switch_time.c.

◆ FALSE

#define FALSE   0

Definition at line 1646 of file switch_time.c.

Referenced by tzparse(), and tztime().

◆ HOURSPERDAY

#define HOURSPERDAY   24

Definition at line 1697 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 1770 of file switch_time.c.

Referenced by transtime(), and tzparse().

◆ is_digit

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

Definition at line 1739 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 1743 of file switch_time.c.

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

◆ JULIAN_DAY

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

Definition at line 1705 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 1696 of file switch_time.c.

Referenced by getsecs().

◆ MONSPERYEAR

#define MONSPERYEAR   12

Definition at line 1703 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 1707 of file switch_time.c.

Referenced by getrule(), and transtime().

◆ MY_TZNAME_MAX

#define MY_TZNAME_MAX   255

Definition at line 1691 of file switch_time.c.

◆ SECSPERDAY

#define SECSPERDAY   ((long) SECSPERHOUR * HOURSPERDAY)

Definition at line 1702 of file switch_time.c.

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

◆ SECSPERHOUR

#define SECSPERHOUR   (SECSPERMIN * MINSPERHOUR)

Definition at line 1701 of file switch_time.c.

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

◆ SECSPERMIN

#define SECSPERMIN   60

Definition at line 1695 of file switch_time.c.

Referenced by getsecs(), and timesub().

◆ switch_assert

#define switch_assert (   expr)    assert(expr)

Definition at line 2337 of file switch_time.c.

Referenced by timesub().

◆ TM_APRIL

#define TM_APRIL   3

Definition at line 1786 of file switch_time.c.

◆ TM_AUGUST

#define TM_AUGUST   7

Definition at line 1790 of file switch_time.c.

◆ TM_DECEMBER

#define TM_DECEMBER   11

Definition at line 1794 of file switch_time.c.

◆ TM_FEBRUARY

#define TM_FEBRUARY   1

Definition at line 1784 of file switch_time.c.

◆ TM_FRIDAY

#define TM_FRIDAY   5

Definition at line 1780 of file switch_time.c.

◆ TM_JANUARY

#define TM_JANUARY   0

Definition at line 1783 of file switch_time.c.

◆ TM_JULY

#define TM_JULY   6

Definition at line 1789 of file switch_time.c.

◆ TM_JUNE

#define TM_JUNE   5

Definition at line 1788 of file switch_time.c.

◆ TM_MARCH

#define TM_MARCH   2

Definition at line 1785 of file switch_time.c.

◆ TM_MAY

#define TM_MAY   4

Definition at line 1787 of file switch_time.c.

◆ TM_MONDAY

#define TM_MONDAY   1

Definition at line 1776 of file switch_time.c.

◆ TM_NOVEMBER

#define TM_NOVEMBER   10

Definition at line 1793 of file switch_time.c.

◆ TM_OCTOBER

#define TM_OCTOBER   9

Definition at line 1792 of file switch_time.c.

◆ TM_SATURDAY

#define TM_SATURDAY   6

Definition at line 1781 of file switch_time.c.

◆ TM_SEPTEMBER

#define TM_SEPTEMBER   8

Definition at line 1791 of file switch_time.c.

◆ TM_SUNDAY

#define TM_SUNDAY   0

Definition at line 1775 of file switch_time.c.

◆ TM_THURSDAY

#define TM_THURSDAY   4

Definition at line 1779 of file switch_time.c.

◆ TM_TUESDAY

#define TM_TUESDAY   2

Definition at line 1777 of file switch_time.c.

◆ TM_WEDNESDAY

#define TM_WEDNESDAY   3

Definition at line 1778 of file switch_time.c.

◆ TM_YEAR_BASE

#define TM_YEAR_BASE   1900

Definition at line 1796 of file switch_time.c.

Referenced by timesub().

◆ TRUE

#define TRUE   1

Definition at line 1642 of file switch_time.c.

Referenced by tzparse().

◆ TZ_MAX_CHARS

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

Definition at line 1678 of file switch_time.c.

◆ TZ_MAX_LEAPS

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

Definition at line 1683 of file switch_time.c.

◆ TZ_MAX_TIMES

#define TZ_MAX_TIMES   370

Definition at line 1658 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 1664 of file switch_time.c.

◆ TZDEFRULES

#define TZDEFRULES   "posixrules"

Definition at line 1724 of file switch_time.c.

◆ TZDEFRULESTRING

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

Definition at line 1735 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 1436 of file switch_time.c.

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

Referenced by SWITCH_MODULE_LOAD_FUNCTION().

1437 {
1438  switch_mutex_lock(globals.mutex);
1441 }
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:1394

◆ getnum()

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

Definition at line 1883 of file switch_time.c.

References is_digit.

Referenced by getrule(), and getsecs().

1884 {
1885  register char c;
1886  register int num;
1887 
1888  if (strp == NULL || !is_digit(c = *strp))
1889  return NULL;
1890  num = 0;
1891  do {
1892  num = num * 10 + (c - '0');
1893  if (num > max)
1894  return NULL; /* illegal value */
1895  c = *++strp;
1896  } while (is_digit(c));
1897  if (num < min)
1898  return NULL; /* illegal value */
1899  *nump = num;
1900  return strp;
1901 }
#define is_digit(c)
Definition: switch_time.c:1739

◆ getoffset()

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

Definition at line 1950 of file switch_time.c.

References getsecs().

Referenced by tzparse().

1951 {
1952  register int neg = 0;
1953 
1954  if (*strp == '-') {
1955  neg = 1;
1956  ++strp;
1957  } else if (*strp == '+')
1958  ++strp;
1959  strp = getsecs(strp, offsetp);
1960  if (strp == NULL)
1961  return NULL; /* illegal time */
1962  if (neg)
1963  *offsetp = -*offsetp;
1964  return strp;
1965 }
static const char * getsecs(register const char *strp, long *const secsp)
Definition: switch_time.c:1911

◆ getrule()

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

Definition at line 1974 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().

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

◆ getsecs()

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

Definition at line 1911 of file switch_time.c.

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

Referenced by getoffset(), and getrule().

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

◆ getzname()

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

Definition at line 1866 of file switch_time.c.

References is_digit.

Referenced by tzparse().

1867 {
1868  register char c;
1869 
1870  while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && c != '+')
1871  ++strp;
1872  return strp;
1873 }
#define is_digit(c)
Definition: switch_time.c:1739

◆ switch_load_timezones()

void switch_load_timezones ( switch_bool_t  reload)

Definition at line 1394 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().

1395 {
1396  switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, cfg = NULL;
1397  unsigned total = 0;
1398 
1399  if (TIMEZONES_LIST.hash) {
1401  }
1402 
1403  if (TIMEZONES_LIST.pool) {
1405  }
1406 
1407  memset(&TIMEZONES_LIST, 0, sizeof(TIMEZONES_LIST));
1410 
1411  if ((xml = switch_xml_open_cfg("timezones.conf", &cfg, NULL))) {
1412  if ((x_lists = switch_xml_child(cfg, "timezones"))) {
1413  for (x_list = switch_xml_child(x_lists, "zone"); x_list; x_list = x_list->next) {
1414  const char *name = switch_xml_attr(x_list, "name");
1415  const char *value = switch_xml_attr(x_list, "value");
1416 
1417  if (zstr(name)) {
1418  continue;
1419  }
1420 
1421  if (zstr(value)) {
1422  continue;
1423  }
1424 
1426  total++;
1427  }
1428  }
1429 
1430  switch_xml_free(xml);
1431  }
1432 
1433  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Timezone %sloaded %d definitions\n", reload ? "re" : "", total);
1434 }
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 1511 of file switch_time.c.

References event_handler(), globals, switch_runtime::initiated, switch_timer_interface::interface_name, 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().

1512 {
1513  switch_timer_interface_t *timer_interface;
1514  module_pool = pool;
1515 
1516 #ifdef WIN32
1517  timeBeginPeriod(1);
1518 
1519  InitializeCriticalSection(&timer_section);
1520 
1521  win32_init_timers(); /* Init timers for Windows, if we should use timeGetTime() or QueryPerformanceCounters() */
1522 #endif
1523 
1524  memset(&globals, 0, sizeof(globals));
1526 
1529  }
1531 
1532  /* connect my internal structure to the blank pointer passed to me */
1533  *module_interface = switch_loadable_module_create_module_interface(pool, modname);
1534  timer_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_TIMER_INTERFACE);
1535  timer_interface->interface_name = "soft";
1536  timer_interface->timer_init = timer_init;
1537  timer_interface->timer_next = timer_next;
1538  timer_interface->timer_step = timer_step;
1539  timer_interface->timer_sync = timer_sync;
1540  timer_interface->timer_check = timer_check;
1541  timer_interface->timer_destroy = timer_destroy;
1542 
1545  }
1546 
1549  }
1550 
1551  if (TFD) {
1553  }
1554 
1555 #ifdef WIN32
1557  MONO = 1;
1558 
1559  if (win32_use_qpc) {
1560  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Enabled Windows monotonic clock, using QueryPerformanceCounter()\n");
1561  } else {
1562  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Enabled Windows monotonic clock, using timeGetTime()\n");
1563  }
1564 
1565  runtime.initiated = switch_mono_micro_time_now(); /* Update mono_initiated, since now is the first time the real clock is enabled */
1566  }
1567 
1568  /* No need to calibrate clock in Win32, we will only sleep ms anyway, it's just not accurate enough */
1570 #endif
1571 
1573  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Calibrating timer, please wait...\n");
1575  } else {
1576  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clock calibration disabled.\n");
1577  }
1578 
1579  /* indicate that the module should continue to be loaded */
1580  return SWITCH_STATUS_SUCCESS;
1581 }
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:1394
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
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:1436
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 1583 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.

1584 {
1585  globals.use_cond_yield = 0;
1586 
1587  if (globals.RUNNING == 1) {
1588  switch_mutex_lock(globals.mutex);
1589  globals.RUNNING = -1;
1591 
1592  while (globals.RUNNING == -1) {
1593  do_sleep(10000);
1594  }
1595  }
1596 #if defined(WIN32)
1597  timeEndPeriod(1);
1598  win32_tick_time_since_start = -1; /* we are not initialized anymore */
1599  DeleteCriticalSection(&timer_section);
1600 #endif
1601 
1602  if (TIMEZONES_LIST.hash) {
1604  }
1605 
1606  if (TIMEZONES_LIST.pool) {
1608  }
1609 
1610  if (NODE) {
1612  }
1613 
1614  return SWITCH_STATUS_SUCCESS;
1615 }
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 2340 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().

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

◆ 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 2028 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().

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

◆ tzparse()

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

Definition at line 2118 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().

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

◆ tztime()

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

Definition at line 2446 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().

2447 {
2448  struct state *tzptr, *sp;
2449  const time_t t = *timep;
2450  register int i;
2451  register const struct ttinfo *ttisp;
2452 
2453  if (tzstring == NULL)
2454  tzstring = gmt;
2455 
2456  tzptr = (struct state *) malloc(sizeof(struct state));
2457  sp = tzptr;
2458 
2459  if (tzptr != NULL) {
2460 
2461  memset(tzptr, 0, sizeof(struct state));
2462 
2463  (void) tzparse(tzstring, tzptr, FALSE);
2464 
2465  if (sp->timecnt == 0 || t < sp->ats[0]) {
2466  i = 0;
2467  while (sp->ttis[i].tt_isdst)
2468  if (++i >= sp->typecnt) {
2469  i = 0;
2470  break;
2471  }
2472  } else {
2473  for (i = 1; i < sp->timecnt; ++i)
2474  if (t < sp->ats[i])
2475  break;
2476  i = sp->types[i - 1]; // DST begin or DST end
2477  }
2478  ttisp = &sp->ttis[i];
2479 
2480  /*
2481  To get (wrong) behavior that's compatible with System V Release 2.0
2482  you'd replace the statement below with
2483  t += ttisp->tt_gmtoff;
2484  timesub(&t, 0L, sp, tmp);
2485  */
2486  if (tmp != NULL) { /* Just a check not to assert */
2487  timesub(&t, ttisp->tt_gmtoff, sp, tmp);
2488  tmp->tm_isdst = ttisp->tt_isdst;
2489 #if defined(HAVE_STRUCT_TM_TM_ZONE)
2490  tmp->tm_zone = &sp->chars[ttisp->tt_abbrind];
2491 #endif
2492  }
2493 
2494  free(tzptr);
2495  }
2496 
2497 }
time_t ats[TZ_MAX_TIMES]
Definition: switch_time.c:1837
static const char gmt[]
Definition: switch_time.c:1806
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:2340
static int tzparse(const char *name, register struct state *const sp, const int lastditch)
Definition: switch_time.c:2118
long tt_gmtoff
Definition: switch_time.c:1819
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: switch_time.c:1839
unsigned char types[TZ_MAX_TIMES]
Definition: switch_time.c:1838
int timecnt
Definition: switch_time.c:1834
char chars[CHARS_DEF]
Definition: switch_time.c:1840
int tt_abbrind
Definition: switch_time.c:1821
int tt_isdst
Definition: switch_time.c:1820
int typecnt
Definition: switch_time.c:1835
#define FALSE
Definition: switch_time.c:1646
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 1806 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 1845 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:1699
#define DAYSPERLYEAR
Definition: switch_time.c:1700

Definition at line 1850 of file switch_time.c.

Referenced by timesub(), and tzparse().