FreeSWITCH API Documentation  1.7.0
Data Structures | Macros | Typedefs | Functions | Variables
switch_time.c File Reference
#include <switch.h>
#include <stdio.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

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

Definition at line 1725 of file switch_time.c.

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

Definition at line 206 of file switch_time.c.

Referenced by switch_time_calibrate_clock().

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

Definition at line 1792 of file switch_time.c.

#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:137
uint32_t roll
Definition: switch_time.c:130
uintptr_t switch_size_t
uint64_t tick
Definition: switch_time.c:128

Definition at line 749 of file switch_time.c.

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

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

Definition at line 1690 of file switch_time.c.

Referenced by getrule(), and transtime().

#define DAYSPERLYEAR   366

Definition at line 1684 of file switch_time.c.

Referenced by getrule().

#define DAYSPERNYEAR   365

Definition at line 1683 of file switch_time.c.

Referenced by getrule(), and timesub().

#define DAYSPERWEEK   7

Definition at line 1682 of file switch_time.c.

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

#define DISABLE_1MS_COND

Definition at line 43 of file switch_time.c.

#define EPOCH_WDAY   TM_THURSDAY

Definition at line 1783 of file switch_time.c.

Referenced by timesub().

#define EPOCH_WDAY   TM_THURSDAY

Definition at line 1783 of file switch_time.c.

#define EPOCH_YEAR   1970

Definition at line 1782 of file switch_time.c.

Referenced by timesub(), and tzparse().

#define EPOCH_YEAR   1970

Definition at line 1782 of file switch_time.c.

#define FALSE   0

Definition at line 1630 of file switch_time.c.

Referenced by tzparse(), and tztime().

#define HOURSPERDAY   24

Definition at line 1681 of file switch_time.c.

Referenced by getsecs().

#define IDLE_SPEED   100

Definition at line 53 of file switch_time.c.

#define INITIALIZE (   x)

Definition at line 1754 of file switch_time.c.

Referenced by transtime(), and tzparse().

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

Definition at line 1723 of file switch_time.c.

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

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

Definition at line 1727 of file switch_time.c.

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

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

Definition at line 1689 of file switch_time.c.

Referenced by getrule(), and transtime().

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

Referenced by timesub().

#define MAX_ELEMENTS   3600

Definition at line 52 of file switch_time.c.

Referenced by SWITCH_MODULE_RUNTIME_FUNCTION(), and timer_destroy().

#define MAX_TICK   UINT32_MAX - 1024

Definition at line 50 of file switch_time.c.

Referenced by SWITCH_MODULE_RUNTIME_FUNCTION().

#define MINSPERHOUR   60

Definition at line 1680 of file switch_time.c.

Referenced by getsecs().

#define MONSPERYEAR   12

Definition at line 1687 of file switch_time.c.

Referenced by getrule().

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

Definition at line 1691 of file switch_time.c.

Referenced by getrule(), and transtime().

#define MY_TZNAME_MAX   255

Definition at line 1675 of file switch_time.c.

#define SECSPERDAY   ((long) SECSPERHOUR * HOURSPERDAY)

Definition at line 1686 of file switch_time.c.

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

#define SECSPERHOUR   (SECSPERMIN * MINSPERHOUR)

Definition at line 1685 of file switch_time.c.

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

#define SECSPERMIN   60

Definition at line 1679 of file switch_time.c.

Referenced by getsecs(), and timesub().

#define switch_assert (   expr)    assert(expr)

Definition at line 2322 of file switch_time.c.

Referenced by timesub().

#define TM_APRIL   3

Definition at line 1770 of file switch_time.c.

#define TM_AUGUST   7

Definition at line 1774 of file switch_time.c.

#define TM_DECEMBER   11

Definition at line 1778 of file switch_time.c.

#define TM_FEBRUARY   1

Definition at line 1768 of file switch_time.c.

#define TM_FRIDAY   5

Definition at line 1764 of file switch_time.c.

#define TM_JANUARY   0

Definition at line 1767 of file switch_time.c.

#define TM_JULY   6

Definition at line 1773 of file switch_time.c.

#define TM_JUNE   5

Definition at line 1772 of file switch_time.c.

#define TM_MARCH   2

Definition at line 1769 of file switch_time.c.

#define TM_MAY   4

Definition at line 1771 of file switch_time.c.

#define TM_MONDAY   1

Definition at line 1760 of file switch_time.c.

#define TM_NOVEMBER   10

Definition at line 1777 of file switch_time.c.

#define TM_OCTOBER   9

Definition at line 1776 of file switch_time.c.

#define TM_SATURDAY   6

Definition at line 1765 of file switch_time.c.

#define TM_SEPTEMBER   8

Definition at line 1775 of file switch_time.c.

#define TM_SUNDAY   0

Definition at line 1759 of file switch_time.c.

#define TM_THURSDAY   4

Definition at line 1763 of file switch_time.c.

#define TM_TUESDAY   2

Definition at line 1761 of file switch_time.c.

#define TM_WEDNESDAY   3

Definition at line 1762 of file switch_time.c.

#define TM_YEAR_BASE   1900

Definition at line 1780 of file switch_time.c.

Referenced by timesub().

#define TRUE   1

Definition at line 1626 of file switch_time.c.

Referenced by tzparse().

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

Definition at line 1662 of file switch_time.c.

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

Definition at line 1667 of file switch_time.c.

#define TZ_MAX_TIMES   370

Definition at line 1642 of file switch_time.c.

Referenced by tzparse().

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

Definition at line 1648 of file switch_time.c.

#define TZDEFRULES   "posixrules"

Definition at line 1708 of file switch_time.c.

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

Definition at line 1719 of file switch_time.c.

#define UINT32_MAX   0xffffffff

Definition at line 47 of file switch_time.c.

Referenced by timer_step().

Typedef Documentation

typedef struct timer_matrix timer_matrix_t

Definition at line 135 of file switch_time.c.

Definition at line 125 of file switch_time.c.

Function Documentation

static switch_interval_time_t average_time ( switch_interval_time_t  t,
int  reps 
)
static

Definition at line 190 of file switch_time.c.

References do_sleep(), and switch_time_ref().

Referenced by switch_time_calibrate_clock().

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

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

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

Definition at line 1418 of file switch_time.c.

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

Referenced by SWITCH_MODULE_LOAD_FUNCTION().

1419 {
1420  switch_mutex_lock(globals.mutex);
1423 }
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
static struct @7 globals
void switch_load_timezones(switch_bool_t reload)
Definition: switch_time.c:1376
static const char* getnum ( register const char *  strp,
int *const  nump,
const int  min,
const int  max 
)
static

Definition at line 1867 of file switch_time.c.

References is_digit.

Referenced by getrule(), and getsecs().

1868 {
1869  register char c;
1870  register int num;
1871 
1872  if (strp == NULL || !is_digit(c = *strp))
1873  return NULL;
1874  num = 0;
1875  do {
1876  num = num * 10 + (c - '0');
1877  if (num > max)
1878  return NULL; /* illegal value */
1879  c = *++strp;
1880  } while (is_digit(c));
1881  if (num < min)
1882  return NULL; /* illegal value */
1883  *nump = num;
1884  return strp;
1885 }
#define is_digit(c)
Definition: switch_time.c:1723
static const char* getoffset ( register const char *  strp,
long *const  offsetp 
)
static

Definition at line 1934 of file switch_time.c.

References getsecs().

Referenced by tzparse().

1935 {
1936  register int neg = 0;
1937 
1938  if (*strp == '-') {
1939  neg = 1;
1940  ++strp;
1941  } else if (*strp == '+')
1942  ++strp;
1943  strp = getsecs(strp, offsetp);
1944  if (strp == NULL)
1945  return NULL; /* illegal time */
1946  if (neg)
1947  *offsetp = -*offsetp;
1948  return strp;
1949 }
static const char * getsecs(register const char *strp, long *const secsp)
Definition: switch_time.c:1895
static const char* getrule ( const char *  strp,
register struct rule *const  rulep 
)
static

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

1959 {
1960  if (*strp == 'J') {
1961  /*
1962  ** Julian day.
1963  */
1964  rulep->r_type = JULIAN_DAY;
1965  ++strp;
1966  strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
1967  } else if (*strp == 'M') {
1968  /*
1969  ** Month, week, day.
1970  */
1971  rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
1972  ++strp;
1973  strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
1974  if (strp == NULL)
1975  return NULL;
1976  if (*strp++ != '.')
1977  return NULL;
1978  strp = getnum(strp, &rulep->r_week, 1, 5);
1979  if (strp == NULL)
1980  return NULL;
1981  if (*strp++ != '.')
1982  return NULL;
1983  strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
1984  } else if (is_digit(*strp)) {
1985  /*
1986  ** Day of year.
1987  */
1988  rulep->r_type = DAY_OF_YEAR;
1989  strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
1990  } else
1991  return NULL; /* invalid format */
1992  if (strp == NULL)
1993  return NULL;
1994  if (*strp == '/') {
1995  /*
1996  ** Time specified.
1997  */
1998  ++strp;
1999  strp = getsecs(strp, &rulep->r_time);
2000  } else
2001  rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
2002  return strp;
2003 }
#define JULIAN_DAY
Definition: switch_time.c:1689
#define is_digit(c)
Definition: switch_time.c:1723
#define SECSPERHOUR
Definition: switch_time.c:1685
static const char * getsecs(register const char *strp, long *const secsp)
Definition: switch_time.c:1895
#define DAYSPERWEEK
Definition: switch_time.c:1682
#define MONTH_NTH_DAY_OF_WEEK
Definition: switch_time.c:1691
static const char * getnum(register const char *strp, int *const nump, const int min, const int max)
Definition: switch_time.c:1867
#define MONSPERYEAR
Definition: switch_time.c:1687
#define DAYSPERNYEAR
Definition: switch_time.c:1683
#define DAYSPERLYEAR
Definition: switch_time.c:1684
#define DAY_OF_YEAR
Definition: switch_time.c:1690
static const char* getsecs ( register const char *  strp,
long *const  secsp 
)
static

Definition at line 1895 of file switch_time.c.

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

Referenced by getoffset(), and getrule().

1896 {
1897  int num;
1898 
1899  /*
1900  ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
1901  ** "M10.4.6/26", which does not conform to Posix,
1902  ** but which specifies the equivalent of
1903  ** ``02:00 on the first Sunday on or after 23 Oct''.
1904  */
1905  strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
1906  if (strp == NULL)
1907  return NULL;
1908  *secsp = num * (long) SECSPERHOUR;
1909  if (*strp == ':') {
1910  ++strp;
1911  strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
1912  if (strp == NULL)
1913  return NULL;
1914  *secsp += num * SECSPERMIN;
1915  if (*strp == ':') {
1916  ++strp;
1917  /* `SECSPERMIN' allows for leap seconds. */
1918  strp = getnum(strp, &num, 0, SECSPERMIN);
1919  if (strp == NULL)
1920  return NULL;
1921  *secsp += num;
1922  }
1923  }
1924  return strp;
1925 }
#define HOURSPERDAY
Definition: switch_time.c:1681
#define SECSPERMIN
Definition: switch_time.c:1679
#define MINSPERHOUR
Definition: switch_time.c:1680
#define SECSPERHOUR
Definition: switch_time.c:1685
#define DAYSPERWEEK
Definition: switch_time.c:1682
static const char * getnum(register const char *strp, int *const nump, const int min, const int max)
Definition: switch_time.c:1867
static const char* getzname ( register const char *  strp)
static

Definition at line 1850 of file switch_time.c.

References is_digit.

Referenced by tzparse().

1851 {
1852  register char c;
1853 
1854  while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && c != '+')
1855  ++strp;
1856  return strp;
1857 }
#define is_digit(c)
Definition: switch_time.c:1723
void switch_load_timezones ( switch_bool_t  reload)

Definition at line 1376 of file switch_time.c.

References switch_timezones_list_t::hash, memset(), 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(), and zstr.

Referenced by event_handler(), and SWITCH_MODULE_LOAD_FUNCTION().

1377 {
1378  switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, cfg = NULL;
1379  unsigned total = 0;
1380 
1381  if (TIMEZONES_LIST.hash) {
1383  }
1384 
1385  if (TIMEZONES_LIST.pool) {
1387  }
1388 
1389  memset(&TIMEZONES_LIST, 0, sizeof(TIMEZONES_LIST));
1392 
1393  if ((xml = switch_xml_open_cfg("timezones.conf", &cfg, NULL))) {
1394  if ((x_lists = switch_xml_child(cfg, "timezones"))) {
1395  for (x_list = switch_xml_child(x_lists, "zone"); x_list; x_list = x_list->next) {
1396  const char *name = switch_xml_attr(x_list, "name");
1397  const char *value = switch_xml_attr(x_list, "value");
1398 
1399  if (zstr(name)) {
1400  continue;
1401  }
1402 
1403  if (zstr(value)) {
1404  continue;
1405  }
1406 
1408  total++;
1409  }
1410  }
1411 
1412  switch_xml_free(xml);
1413  }
1414 
1415  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Timezone %sloaded %d definitions\n", reload ? "re" : "", total);
1416 }
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's master pool.
Definition: switch_core.h:631
#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:1390
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
static switch_timezones_list_t TIMEZONES_LIST
Definition: switch_time.c:1358
A representation of an XML tree.
Definition: switch_xml.h:76
#define zstr(x)
Definition: switch_utils.h:281
switch_xml_t next
Definition: switch_xml.h:88
switch_memory_pool_t * pool
Definition: switch_time.c:1354
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:1410
switch_hash_t * hash
Definition: switch_time.c:1355
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.
memset(buf, 0, buflen)
SWITCH_MODULE_DEFINITION ( CORE_SOFTTIMER_MODULE  ,
softtimer_load  ,
softtimer_shutdown  ,
softtimer_runtime   
)
SWITCH_MODULE_LOAD_FUNCTION ( softtimer_load  )

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

1496 {
1497  switch_timer_interface_t *timer_interface;
1498  module_pool = pool;
1499 
1500 #ifdef WIN32
1501  timeBeginPeriod(1);
1502 
1503  InitializeCriticalSection(&timer_section);
1504 
1505  win32_init_timers(); /* Init timers for Windows, if we should use timeGetTime() or QueryPerformanceCounters() */
1506 #endif
1507 
1508  memset(&globals, 0, sizeof(globals));
1510 
1513  }
1515 
1516  /* connect my internal structure to the blank pointer passed to me */
1517  *module_interface = switch_loadable_module_create_module_interface(pool, modname);
1518  timer_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_TIMER_INTERFACE);
1519  timer_interface->interface_name = "soft";
1520  timer_interface->timer_init = timer_init;
1521  timer_interface->timer_next = timer_next;
1522  timer_interface->timer_step = timer_step;
1523  timer_interface->timer_sync = timer_sync;
1524  timer_interface->timer_check = timer_check;
1525  timer_interface->timer_destroy = timer_destroy;
1526 
1529  }
1530 
1533  }
1534 
1535  if (TFD) {
1537  }
1538 
1539 #ifdef WIN32
1541  MONO = 1;
1542 
1543  if (win32_use_qpc) {
1544  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Enabled Windows monotonic clock, using QueryPerformanceCounter()\n");
1545  } else {
1546  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Enabled Windows monotonic clock, using timeGetTime()\n");
1547  }
1548 
1549  runtime.initiated = switch_mono_micro_time_now(); /* Update mono_initiated, since now is the first time the real clock is enabled */
1550  }
1551 
1552  /* No need to calibrate clock in Win32, we will only sleep ms anyway, it's just not accurate enough */
1554 #endif
1555 
1557  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Calibrating timer, please wait...\n");
1559  } else {
1560  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clock calibration disabled.\n");
1561  }
1562 
1563  /* indicate that the module should continue to be loaded */
1564  return SWITCH_STATUS_SUCCESS;
1565 }
static switch_status_t timer_sync(switch_timer_t *timer)
Definition: switch_time.c:791
static switch_status_t timer_init(switch_timer_t *timer)
Definition: switch_time.c:679
static switch_status_t timer_step(switch_timer_t *timer)
Definition: switch_time.c:756
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:365
switch_memory_pool_t * pool
static int TFD
Definition: switch_time.c:80
static switch_memory_pool_t * module_pool
Definition: switch_time.c:99
A table of functions that a timer module implements.
struct switch_runtime runtime
Definition: switch_core.c:64
static switch_status_t timer_destroy(switch_timer_t *timer)
Definition: switch_time.c:925
static switch_status_t timer_next(switch_timer_t *timer)
Definition: switch_time.c:821
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:655
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
static int MONO
Definition: switch_time.c:63
switch_status_t(* timer_next)(switch_timer_t *)
switch_status_t(* timer_init)(switch_timer_t *)
switch_status_t(* timer_sync)(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:270
static struct @7 globals
static switch_status_t timer_check(switch_timer_t *timer, switch_bool_t step)
Definition: switch_time.c:884
static switch_event_node_t * NODE
Definition: switch_time.c:1359
void switch_load_timezones(switch_bool_t reload)
Definition: switch_time.c:1376
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:207
switch_status_t(* timer_check)(switch_timer_t *, switch_bool_t)
switch_time_t switch_mono_micro_time_now(void)
Definition: switch_time.c:315
void switch_time_set_cond_yield(switch_bool_t enable)
Definition: switch_time.c:372
switch_status_t(* timer_destroy)(switch_timer_t *)
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
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.
switch_status_t(* timer_step)(switch_timer_t *)
static void event_handler(switch_event_t *event)
Definition: switch_time.c:1418
static void win32_init_timers(void)
Definition: switch_time.c:970
memset(buf, 0, buflen)
void * switch_loadable_module_create_interface(switch_loadable_module_interface_t *mod, switch_module_interface_name_t iname)
SWITCH_MODULE_RUNTIME_FUNCTION ( softtimer_runtime  )

Definition at line 1019 of file switch_time.c.

References COND, 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_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().

1020 {
1021  switch_time_t too_late = runtime.microseconds_per_tick * 1000;
1022  uint32_t current_ms = 0;
1023  uint32_t x, tick = 0, sps_interval_ticks = 0;
1024  switch_time_t ts = 0, last = 0;
1025  int fwd_errs = 0, rev_errs = 0;
1026  int profile_tick = 0;
1027  int tfd = -1;
1028  uint32_t time_sync = runtime.time_sync;
1029 
1030 #ifdef HAVE_TIMERFD_CREATE
1031  int last_MICROSECONDS_PER_TICK = runtime.microseconds_per_tick;
1032 
1033  struct itimerspec spec = { { 0 } };
1034 
1035  if (MONO && TFD) {
1036  tfd = timerfd_create(CLOCK_MONOTONIC, 0);
1037 
1038  if (tfd > -1) {
1039  spec.it_interval.tv_sec = 0;
1040  spec.it_interval.tv_nsec = runtime.microseconds_per_tick * 1000;
1041  spec.it_value.tv_sec = 0;
1042  spec.it_value.tv_nsec = 100000;
1043 
1044  if (timerfd_settime(tfd, 0, &spec, NULL)) {
1045  close(tfd);
1046  tfd = -1;
1047  }
1048  }
1049 
1050  if (tfd > -1) MATRIX = 0;
1051  }
1052 #else
1053  tfd = -1;
1054 #endif
1055 
1058 
1059  if (runtime.timer_affinity > -1) {
1061  }
1062 
1063  switch_time_sync();
1064  time_sync = runtime.time_sync;
1065 
1066  globals.STARTED = globals.RUNNING = 1;
1070 
1071  if (MONO) {
1072  int loops;
1073  for (loops = 0; loops < 3; loops++) {
1074  ts = switch_time_ref();
1075  /* if it returns the same value every time it won't be of much use. */
1076  if (ts == last) {
1077  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Broken MONOTONIC Clock Detected!, Support Disabled.\n");
1078  MONO = 0;
1079  NANO = 0;
1082  break;
1083  }
1085  last = ts;
1086  }
1087  }
1088 
1089  ts = 0;
1090  last = 0;
1091  fwd_errs = rev_errs = 0;
1092 
1093 #ifndef DISABLE_1MS_COND
1094  if (!NANO) {
1097  }
1098 #endif
1099 
1100 
1101  switch_time_sync();
1102  time_sync = runtime.time_sync;
1103 
1104  globals.use_cond_yield = COND;
1105  globals.RUNNING = 1;
1106 
1107  while (globals.RUNNING == 1) {
1108 
1109 #ifdef HAVE_TIMERFD_CREATE
1110  if (last_MICROSECONDS_PER_TICK != runtime.microseconds_per_tick) {
1111  spec.it_interval.tv_nsec = runtime.microseconds_per_tick * 1000;
1112  timerfd_settime(tfd, 0, &spec, NULL);
1113  }
1114 
1115  last_MICROSECONDS_PER_TICK = runtime.microseconds_per_tick;
1116 #endif
1117 
1119 
1120  while (((ts = time_now(runtime.offset)) + 100) < runtime.reference) {
1121  if (ts < last) {
1122  if (MONO) {
1124 
1125  if (time_sync == runtime.time_sync) { /* Only resync if not in the middle of switch_time_sync() already */
1126  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n");
1127  win32_init_timers(); /* Make sure to reinit timers on WIN32 */
1128  switch_time_sync();
1129  time_sync = runtime.time_sync;
1130  }
1131  } else {
1132  int64_t diff = (int64_t) (ts - last);
1133  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Reverse Clock Skew Detected!\n");
1135  current_ms = 0;
1136  tick = 0;
1137  runtime.initiated += diff;
1138  rev_errs++;
1139  }
1140 
1141  if (!MONO || time_sync == runtime.time_sync) {
1142 #if defined(HAVE_CLOCK_NANOSLEEP)
1144  "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. I AM *FREE* afterall.\n");
1145 #else
1147  "If you see this message many times consider a nicer machine to run me on. I AM *FREE* afterall.\n");
1148 #endif
1149  }
1150  } else {
1151  rev_errs = 0;
1152  }
1153 
1154  if (runtime.tipping_point && globals.timer_count >= runtime.tipping_point) {
1155  switch_os_yield();
1156  } else {
1157  if (tfd > -1 && globals.RUNNING == 1) {
1158  uint64_t exp;
1159  int r;
1160  r = read(tfd, &exp, sizeof(exp));
1161  r++;
1162  } else {
1163  switch_time_t timediff = runtime.reference - ts;
1164 
1165  if (runtime.microseconds_per_tick < timediff) {
1166  /* Only sleep for runtime.microseconds_per_tick if this value is lower then the actual time diff we need to sleep */
1168  } else {
1169 #ifdef WIN32
1170  /* Windows only sleeps in ms precision, try to round the usec value as good as possible */
1171  do_sleep((switch_interval_time_t)floor((timediff / 1000.0) + 0.5) * 1000);
1172 #else
1173  do_sleep(timediff);
1174 #endif
1175  }
1176  }
1177  }
1178 
1179  last = ts;
1180  }
1181 
1182  if (ts > (runtime.reference + too_late)) {
1183  if (MONO) {
1185 
1186  if (time_sync == runtime.time_sync) { /* Only resync if not in the middle of switch_time_sync() already */
1187  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n");
1188  win32_init_timers(); /* Make sure to reinit timers on WIN32 */
1189  switch_time_sync();
1190  time_sync = runtime.time_sync;
1191  }
1192  } else {
1194  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Forward Clock Skew Detected!\n");
1195  fwd_errs++;
1197  current_ms = 0;
1198  tick = 0;
1199  runtime.initiated += diff;
1200  }
1201  } else {
1202  fwd_errs = 0;
1203  }
1204 
1205  if (fwd_errs > 9 || rev_errs > 9) {
1206  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Auto Re-Syncing clock.\n");
1207  switch_time_sync();
1208  time_sync = runtime.time_sync;
1209  fwd_errs = rev_errs = 0;
1210  }
1211 
1212  runtime.timestamp = ts;
1213  current_ms += (runtime.microseconds_per_tick / 1000);
1214  tick++;
1215 
1216  if (time_sync < runtime.time_sync) {
1217  time_sync++; /* Only step once for each loop, we want to make sure to keep this thread safe */
1218  }
1219 
1220  if (tick >= (1000000 / runtime.microseconds_per_tick)) {
1221  if (++profile_tick == 1) {
1223  profile_tick = 0;
1224  }
1225 
1226  if (runtime.sps <= 0) {
1227  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Rate of %d!\n", runtime.sps_total);
1228  }
1231 
1232  if (sps_interval_ticks >= 300) {
1234  sps_interval_ticks = 0;
1238  }
1239 
1240  sps_interval_ticks++;
1241 
1244  }
1245 
1246  if (runtime.sps_last > runtime.sps_peak) {
1248  }
1251  tick = 0;
1252  }
1253 #ifndef DISABLE_1MS_COND
1254  TIMER_MATRIX[1].tick++;
1258  }
1259  if (TIMER_MATRIX[1].tick == MAX_TICK) {
1260  TIMER_MATRIX[1].tick = 0;
1261  TIMER_MATRIX[1].roll++;
1262  }
1263 #endif
1264 
1265 
1266  if (MATRIX && (current_ms % (runtime.microseconds_per_tick / 1000)) == 0) {
1267  for (x = (runtime.microseconds_per_tick / 1000); x <= MAX_ELEMENTS; x += (runtime.microseconds_per_tick / 1000)) {
1268  if ((current_ms % x) == 0) {
1269  if (TIMER_MATRIX[x].count) {
1270  TIMER_MATRIX[x].tick++;
1271 #ifdef DISABLE_1MS_COND
1272 
1276  }
1277 #endif
1278  if (TIMER_MATRIX[x].tick == MAX_TICK) {
1279  TIMER_MATRIX[x].tick = 0;
1280  TIMER_MATRIX[x].roll++;
1281  }
1282  }
1283  }
1284  }
1285  }
1286 
1287  if (current_ms == MAX_ELEMENTS) {
1288  current_ms = 0;
1289  }
1290  }
1291 
1292  globals.use_cond_yield = 0;
1293 
1294  for (x = (runtime.microseconds_per_tick / 1000); x <= MAX_ELEMENTS; x += (runtime.microseconds_per_tick / 1000)) {
1298  }
1299  }
1300 
1301  if (tfd > -1) {
1302  close(tfd);
1303  tfd = -1;
1304  }
1305 
1306 
1307  switch_mutex_lock(globals.mutex);
1308  globals.RUNNING = 0;
1310 
1312 
1313  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Soft timer thread exiting.\n");
1314 
1315  return SWITCH_STATUS_TERM;
1316 }
void switch_time_sync(void)
Definition: switch_time.c:589
switch_status_t switch_thread_cond_create(switch_thread_cond_t **cond, switch_memory_pool_t *pool)
Definition: switch_apr.c:350
#define SWITCH_CHANNEL_LOG
switch_time_t initiated
switch_status_t switch_mutex_trylock(switch_mutex_t *lock)
Definition: switch_apr.c:295
static switch_time_t time_now(int64_t offset)
Definition: switch_time.c:520
void switch_os_yield(void)
Definition: switch_time.c:141
static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
Definition: switch_time.c:137
#define MAX_ELEMENTS
Definition: switch_time.c:52
int32_t timer_affinity
static int TFD
Definition: switch_time.c:80
#define MAX_TICK
Definition: switch_time.c:50
static switch_memory_pool_t * module_pool
Definition: switch_time.c:99
switch_mutex_t * throttle_mutex
struct switch_runtime runtime
Definition: switch_core.c:64
uint32_t microseconds_per_tick
switch_status_t switch_core_thread_set_cpu_affinity(int cpu)
Definition: switch_core.c:1723
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
static int MONO
Definition: switch_time.c:63
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:285
uint32_t roll
Definition: switch_time.c:130
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
switch_mutex_t * session_hash_mutex
static struct @7 globals
int64_t switch_interval_time_t
Definition: switch_apr.h:191
static int COND
Definition: switch_time.c:86
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:81
switch_time_t switch_mono_micro_time_now(void)
Definition: switch_time.c:315
uint64_t tick
Definition: switch_time.c:128
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 do_sleep(switch_interval_time_t t)
Definition: switch_time.c:150
switch_status_t switch_thread_cond_broadcast(switch_thread_cond_t *cond)
Definition: switch_apr.c:376
static void win32_init_timers(void)
Definition: switch_time.c:970
switch_time_t switch_time_now(void)
Definition: switch_apr.c:302
switch_mutex_t * mutex
Definition: switch_time.c:105
static int MATRIX
Definition: switch_time.c:88
switch_profile_timer_t * profile_timer
switch_time_t reference
switch_time_t switch_time_ref(void)
Definition: switch_time.c:576
SWITCH_MODULE_SHUTDOWN_FUNCTION ( softtimer_shutdown  )

Definition at line 1567 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.

1568 {
1569  globals.use_cond_yield = 0;
1570 
1571  if (globals.RUNNING == 1) {
1572  switch_mutex_lock(globals.mutex);
1573  globals.RUNNING = -1;
1575 
1576  while (globals.RUNNING == -1) {
1577  do_sleep(10000);
1578  }
1579  }
1580 #if defined(WIN32)
1581  timeEndPeriod(1);
1582  win32_tick_time_since_start = -1; /* we are not initialized anymore */
1583  DeleteCriticalSection(&timer_section);
1584 #endif
1585 
1586  if (TIMEZONES_LIST.hash) {
1588  }
1589 
1590  if (TIMEZONES_LIST.pool) {
1592  }
1593 
1594  if (NODE) {
1596  }
1597 
1598  return SWITCH_STATUS_SUCCESS;
1599 }
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:640
static switch_timezones_list_t TIMEZONES_LIST
Definition: switch_time.c:1358
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
switch_memory_pool_t * pool
Definition: switch_time.c:1354
static struct @7 globals
static switch_event_node_t * NODE
Definition: switch_time.c:1359
switch_hash_t * hash
Definition: switch_time.c:1355
static void do_sleep(switch_interval_time_t t)
Definition: switch_time.c:150
switch_status_t switch_event_unbind(switch_event_node_t **node)
Unbind a bound event consumer.
void switch_os_yield ( void  )

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

142 {
143 #if defined(WIN32)
144  SwitchToThread();
145 #else
146  sched_yield();
147 #endif
148 }
static switch_time_t time_now ( int64_t  offset)
static

Definition at line 520 of file switch_time.c.

References 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().

521 {
522  switch_time_t now;
523 
524 #if (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) || defined(WIN32)
525  if (MONO) {
526 #ifndef WIN32
527  struct timespec ts;
528  clock_gettime(offset ? CLOCK_MONOTONIC : CLOCK_REALTIME, &ts);
529  if (offset < 0) offset = 0;
530  now = ts.tv_sec * APR_USEC_PER_SEC + (ts.tv_nsec / 1000) + offset;
531 #else
532  if (offset == 0) {
533  return switch_time_now();
534  } else if (offset < 0) offset = 0;
535 
536 
537  if (win32_use_qpc) {
538  /* Use QueryPerformanceCounter */
539  uint64_t count = 0;
540  QueryPerformanceCounter((LARGE_INTEGER*)&count);
541  now = ((count * 1000000) / win32_qpc_freq) + offset;
542  } else {
543  /* Use good old timeGetTime() */
544  DWORD tick_now;
545  DWORD tick_diff;
546 
547  tick_now = timeGetTime();
548  if (win32_tick_time_since_start != -1) {
549  EnterCriticalSection(&timer_section);
550  /* just add diff (to make it work more than 50 days). */
551  tick_diff = tick_now - win32_last_get_time_tick;
552  win32_tick_time_since_start += tick_diff;
553 
554  win32_last_get_time_tick = tick_now;
555  now = (win32_tick_time_since_start * 1000) + offset;
556  LeaveCriticalSection(&timer_section);
557  } else {
558  /* If someone is calling us before timer is initialized,
559  * return the current tick + offset
560  */
561  now = (tick_now * 1000) + offset;
562  }
563  }
564 #endif
565  } else {
566 #endif
567  now = switch_time_now();
568 
569 #if (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) || defined(WIN32)
570  }
571 #endif
572 
573  return now;
574 }
static int MONO
Definition: switch_time.c:63
int64_t switch_time_t
Definition: switch_apr.h:188
switch_time_t switch_time_now(void)
Definition: switch_apr.c:302
static switch_status_t timer_check ( switch_timer_t timer,
switch_bool_t  step 
)
static

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

885 {
886  timer_private_t *private_info;
888 
889  if (timer->interval == 1) {
890  return SWITCH_STATUS_FALSE;
891  }
892 
893 #ifdef HAVE_TIMERFD_CREATE
894  if (TFD == 2) {
895  return _timerfd_check(timer, step);
896  }
897 #endif
898 
899  private_info = timer->private_info;
900 
901  if (globals.RUNNING != 1 || !private_info->ready) {
902  return SWITCH_STATUS_SUCCESS;
903  }
904 
905  check_roll();
906 
907  timer->tick = TIMER_MATRIX[timer->interval].tick;
908 
909  if (timer->tick < private_info->reference) {
910  timer->diff = (switch_size_t)(private_info->reference - timer->tick);
911  } else {
912  timer->diff = 0;
913  }
914 
915  if (timer->diff) {
916  status = SWITCH_STATUS_FALSE;
917  } else if (step) {
918  timer_step(timer);
919  }
920 
921 
922  return status;
923 }
#define check_roll()
Definition: switch_time.c:749
static switch_status_t timer_step(switch_timer_t *timer)
Definition: switch_time.c:756
static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
Definition: switch_time.c:137
static int TFD
Definition: switch_time.c:80
uintptr_t switch_size_t
static struct @7 globals
switch_size_t reference
Definition: switch_time.c:120
uint32_t ready
Definition: switch_time.c:123
switch_status_t
Common return values.
uint64_t tick
Definition: switch_time.c:128
static switch_status_t timer_destroy ( switch_timer_t timer)
static

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

926 {
927  timer_private_t *private_info;
928 
929  if (timer->interval == 1) {
930  switch_mutex_lock(globals.mutex);
931  if (globals.timer_count) {
932  globals.timer_count--;
933  }
935  return SWITCH_STATUS_SUCCESS;
936  }
937 
938 #ifdef HAVE_TIMERFD_CREATE
939  if (TFD == 2) {
940  return _timerfd_destroy(timer);
941  }
942 #endif
943 
944  private_info = timer->private_info;
945 
946  if (timer->interval < MAX_ELEMENTS) {
947  switch_mutex_lock(globals.mutex);
948  TIMER_MATRIX[timer->interval].count--;
949  if (TIMER_MATRIX[timer->interval].count == 0) {
950  TIMER_MATRIX[timer->interval].tick = 0;
951  }
953  }
954  if (private_info) {
955  private_info->ready = 0;
956  }
957 
958  switch_mutex_lock(globals.mutex);
959  if (globals.timer_count) {
960  globals.timer_count--;
961  if (runtime.tipping_point && globals.timer_count == (runtime.tipping_point - 1)) {
962  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Fell Below tipping point of %u, shifting into low-gear.\n", runtime.tipping_point);
963  }
964  }
966 
967  return SWITCH_STATUS_SUCCESS;
968 }
#define SWITCH_CHANNEL_LOG
static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
Definition: switch_time.c:137
#define MAX_ELEMENTS
Definition: switch_time.c:52
static int TFD
Definition: switch_time.c:80
struct switch_runtime runtime
Definition: switch_core.c:64
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
static struct @7 globals
uint32_t count
Definition: switch_time.c:129
uint32_t ready
Definition: switch_time.c:123
uint32_t tipping_point
uint64_t tick
Definition: switch_time.c:128
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 switch_status_t timer_generic_sync ( switch_timer_t timer)
static

Definition at line 381 of file switch_time.c.

References switch_timer::interval, switch_timer::samplecount, switch_timer::samples, switch_timer::start, SWITCH_STATUS_SUCCESS, switch_time_now(), and switch_timer::tick.

Referenced by timer_sync().

382 {
384  int64_t elapsed = (now - timer->start);
385 
386  timer->tick = (elapsed / timer->interval) / 1000;
387  timer->samplecount = (uint32_t)(timer->tick * timer->samples);
388 
389  return SWITCH_STATUS_SUCCESS;
390 }
int64_t switch_time_t
Definition: switch_apr.h:188
switch_time_t switch_time_now(void)
Definition: switch_apr.c:302
static switch_status_t timer_init ( switch_timer_t timer)
static

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

680 {
681  timer_private_t *private_info;
682  int sanity = 0;
683 
684  timer->start = switch_micro_time_now();
685 
686  if (timer->interval == 1) {
688  switch_mutex_lock(globals.mutex);
689  globals.timer_count++;
691  return SWITCH_STATUS_SUCCESS;
692  }
693 
694 #ifdef HAVE_TIMERFD_CREATE
695  if (TFD == 2) {
696  return _timerfd_init(timer);
697  }
698 #endif
699 
700  while (globals.STARTED == 0) {
701  do_sleep(100000);
702  if (++sanity == 300) {
703  abort();
704  }
705  }
706 
707  if (globals.RUNNING != 1 || !globals.mutex || timer->interval < 1) {
708  return SWITCH_STATUS_FALSE;
709  }
710 
711  if ((private_info = switch_core_alloc(timer->memory_pool, sizeof(*private_info)))) {
712  switch_mutex_lock(globals.mutex);
713  if (!TIMER_MATRIX[timer->interval].mutex) {
716  }
717  TIMER_MATRIX[timer->interval].count++;
719  timer->private_info = private_info;
720  private_info->start = private_info->reference = (switch_size_t)TIMER_MATRIX[timer->interval].tick;
721  private_info->start -= 2; /* switch_core_timer_init sets samplecount to samples, this makes first next() step once */
722  private_info->roll = TIMER_MATRIX[timer->interval].roll;
723  private_info->ready = 1;
724 
725  if (runtime.microseconds_per_tick > 10000 && (timer->interval % (int)(runtime.microseconds_per_tick / 1000)) != 0 && (timer->interval % 10) == 0) {
726  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Increasing global timer resolution to 10ms to handle interval %d\n", timer->interval);
728  }
729 
730  if (timer->interval > 0 && (timer->interval < (int)(runtime.microseconds_per_tick / 1000) || (timer->interval % 10) != 0)) {
731  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Increasing global timer resolution to 1ms to handle interval %d\n", timer->interval);
734  }
735 
736  switch_mutex_lock(globals.mutex);
737  globals.timer_count++;
738  if (runtime.tipping_point && globals.timer_count == (runtime.tipping_point + 1)) {
739  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Crossed tipping point of %u, shifting into high-gear.\n", runtime.tipping_point);
740  }
742 
743  return SWITCH_STATUS_SUCCESS;
744  }
745 
746  return SWITCH_STATUS_MEMERR;
747 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:310
void switch_time_sync(void)
Definition: switch_time.c:589
switch_status_t switch_thread_cond_create(switch_thread_cond_t **cond, switch_memory_pool_t *pool)
Definition: switch_apr.c:350
#define SWITCH_CHANNEL_LOG
static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
Definition: switch_time.c:137
static int TFD
Definition: switch_time.c:80
static switch_memory_pool_t * module_pool
Definition: switch_time.c:99
struct switch_runtime runtime
Definition: switch_core.c:64
uint32_t microseconds_per_tick
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
#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:285
switch_memory_pool_t * memory_pool
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
switch_size_t start
Definition: switch_time.c:121
uint32_t roll
Definition: switch_time.c:130
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
uintptr_t switch_size_t
static struct @7 globals
switch_size_t reference
Definition: switch_time.c:120
uint32_t count
Definition: switch_time.c:129
uint32_t ready
Definition: switch_time.c:123
switch_thread_cond_t * cond
Definition: switch_time.c:132
uint32_t tipping_point
switch_mutex_t * mutex
Definition: switch_time.c:131
uint64_t tick
Definition: switch_time.c:128
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:122
static void do_sleep(switch_interval_time_t t)
Definition: switch_time.c:150
static switch_status_t timer_next ( switch_timer_t timer)
static

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

822 {
823  timer_private_t *private_info;
824 
825 #ifdef DISABLE_1MS_COND
826  int cond_index = timer->interval;
827 #else
828  int cond_index = 1;
829 #endif
830  int delta;
831 
832  if (timer->interval == 1) {
833  return SWITCH_STATUS_FALSE;
834  }
835 
836 #ifdef HAVE_TIMERFD_CREATE
837  if (TFD == 2) {
838  return _timerfd_next(timer);
839  }
840 #endif
841 
842  private_info = timer->private_info;
843 
844  delta = (int) (private_info->reference - TIMER_MATRIX[timer->interval].tick);
845 
846 
847 
848  /* sync up timer if it's not been called for a while otherwise it will return instantly several times until it catches up */
849  if (delta < -1) {
850  private_info->reference = (switch_size_t)(timer->tick = TIMER_MATRIX[timer->interval].tick);
851  }
852  timer_step(timer);
853 
854  if (!MATRIX) {
855  do_sleep(1000 * timer->interval);
856  goto end;
857  }
858 
859  while (globals.RUNNING == 1 && private_info->ready && TIMER_MATRIX[timer->interval].tick < private_info->reference) {
860  check_roll();
861 
862  switch_os_yield();
863 
864 
865  if (runtime.tipping_point && globals.timer_count >= runtime.tipping_point) {
866  globals.use_cond_yield = 0;
867  } else {
868  if (globals.use_cond_yield == 1) {
869  switch_mutex_lock(TIMER_MATRIX[cond_index].mutex);
870  if (TIMER_MATRIX[timer->interval].tick < private_info->reference) {
871  switch_thread_cond_wait(TIMER_MATRIX[cond_index].cond, TIMER_MATRIX[cond_index].mutex);
872  }
874  } else {
875  do_sleep(1000);
876  }
877  }
878  }
879 
880  end:
881  return globals.RUNNING == 1 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
882 }
#define check_roll()
Definition: switch_time.c:749
static switch_status_t timer_step(switch_timer_t *timer)
Definition: switch_time.c:756
void switch_os_yield(void)
Definition: switch_time.c:141
static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
Definition: switch_time.c:137
static int TFD
Definition: switch_time.c:80
switch_status_t switch_thread_cond_wait(switch_thread_cond_t *cond, switch_mutex_t *mutex)
Definition: switch_apr.c:355
struct switch_runtime runtime
Definition: switch_core.c:64
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
uintptr_t switch_size_t
static struct @7 globals
switch_size_t reference
Definition: switch_time.c:120
uint32_t ready
Definition: switch_time.c:123
uint32_t tipping_point
uint64_t tick
Definition: switch_time.c:128
static void do_sleep(switch_interval_time_t t)
Definition: switch_time.c:150
switch_mutex_t * mutex
Definition: switch_time.c:105
static int MATRIX
Definition: switch_time.c:88
static switch_status_t timer_step ( switch_timer_t timer)
static

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

757 {
758  timer_private_t *private_info;
759  uint64_t samples;
760 
761  if (timer->interval == 1) {
762  return SWITCH_STATUS_FALSE;
763  }
764 
765 #ifdef HAVE_TIMERFD_CREATE
766  if (TFD == 2) {
767  return _timerfd_step(timer);
768  }
769 #endif
770 
771  private_info = timer->private_info;
772 
773  if (globals.RUNNING != 1 || private_info->ready == 0) {
774  return SWITCH_STATUS_FALSE;
775  }
776 
777  check_roll();
778  samples = (uint64_t)timer->samples * (private_info->reference - private_info->start);
779 
780  if (samples > UINT32_MAX) {
781  private_info->start = private_info->reference - 1; /* Must have a diff */
782  samples = timer->samples;
783  }
784 
785  timer->samplecount = (uint32_t) samples;
786  private_info->reference++;
787 
788  return SWITCH_STATUS_SUCCESS;
789 }
#define check_roll()
Definition: switch_time.c:749
static int TFD
Definition: switch_time.c:80
switch_size_t start
Definition: switch_time.c:121
#define UINT32_MAX
Definition: switch_time.c:47
static struct @7 globals
switch_size_t reference
Definition: switch_time.c:120
uint32_t ready
Definition: switch_time.c:123
static switch_status_t timer_sync ( switch_timer_t timer)
static

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

792 {
793  timer_private_t *private_info;
794 
795  if (timer->interval == 1) {
796  return timer_generic_sync(timer);
797  }
798 
799 #ifdef HAVE_TIMERFD_CREATE
800  if (TFD == 2) {
801  return timer_generic_sync(timer);
802  }
803 #endif
804 
805  private_info = timer->private_info;
806 
807  if (globals.RUNNING != 1 || private_info->ready == 0) {
808  return SWITCH_STATUS_FALSE;
809  }
810 
811  /* sync the clock */
812  private_info->reference = (switch_size_t)(timer->tick = TIMER_MATRIX[timer->interval].tick);
813 
814  /* apply timestamp */
815  timer_step(timer);
816 
817  return SWITCH_STATUS_SUCCESS;
818 }
static switch_status_t timer_step(switch_timer_t *timer)
Definition: switch_time.c:756
static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
Definition: switch_time.c:137
static int TFD
Definition: switch_time.c:80
uintptr_t switch_size_t
static struct @7 globals
switch_size_t reference
Definition: switch_time.c:120
uint32_t ready
Definition: switch_time.c:123
static switch_status_t timer_generic_sync(switch_timer_t *timer)
Definition: switch_time.c:381
uint64_t tick
Definition: switch_time.c:128
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 2325 of file switch_time.c.

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

Referenced by tztime().

2326 {
2327  register const struct lsinfo *lp;
2328  register long days;
2329  register time_t rem;
2330  register int y;
2331  register int yleap;
2332  register const int *ip;
2333  register long corr;
2334  register int hit;
2335  register int i;
2336 
2337  switch_assert(timep != NULL);
2338  switch_assert(sp != NULL);
2339  switch_assert(tmp != NULL);
2340 
2341  corr = 0;
2342  hit = 0;
2343  i = (sp == NULL) ? 0 : sp->leapcnt;
2344 
2345  while (--i >= 0) {
2346  lp = &sp->lsis[i];
2347  if (*timep >= lp->ls_trans) {
2348  if (*timep == lp->ls_trans) {
2349  hit = ((i == 0 && lp->ls_corr > 0) || (i > 0 && lp->ls_corr > sp->lsis[i - 1].ls_corr));
2350  if (hit)
2351  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) {
2352  ++hit;
2353  --i;
2354  }
2355  }
2356  corr = lp->ls_corr;
2357  break;
2358  }
2359  }
2360  days = (long) (*timep / SECSPERDAY);
2361  rem = *timep % SECSPERDAY;
2362 
2363 
2364 #ifdef mc68k
2365  /* If this is for CPU bugs workarounds, i would remove this anyway. Who would use it on an old mc68k ? */
2366  if (*timep == 0x80000000) {
2367  /*
2368  ** A 3B1 muffs the division on the most negative number.
2369  */
2370  days = -24855;
2371  rem = -11648;
2372  }
2373 #endif
2374 
2375  rem += (offset - corr);
2376  while (rem < 0) {
2377  rem += SECSPERDAY;
2378  --days;
2379  }
2380  while (rem >= SECSPERDAY) {
2381  rem -= SECSPERDAY;
2382  ++days;
2383  }
2384  tmp->tm_hour = (int) (rem / SECSPERHOUR);
2385  rem = rem % SECSPERHOUR;
2386  tmp->tm_min = (int) (rem / SECSPERMIN);
2387 
2388  /*
2389  ** A positive leap second requires a special
2390  ** representation. This uses "... ??:59:60" et seq.
2391  */
2392  tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
2393  tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
2394 
2395  if (tmp->tm_wday < 0)
2396  tmp->tm_wday += DAYSPERWEEK;
2397 
2398  y = EPOCH_YEAR;
2399 
2400 #define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
2401 
2402  while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
2403  register int newy;
2404 
2405  newy = (int) (y + days / DAYSPERNYEAR);
2406  if (days < 0)
2407  --newy;
2408  days -= (newy - y) * DAYSPERNYEAR + LEAPS_THRU_END_OF(newy - 1) - LEAPS_THRU_END_OF(y - 1);
2409  y = newy;
2410  }
2411 
2412  tmp->tm_year = y - TM_YEAR_BASE;
2413  tmp->tm_yday = (int) days;
2414 
2415  ip = mon_lengths[yleap];
2416 
2417  for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
2418  days = days - (long) ip[tmp->tm_mon];
2419 
2420  tmp->tm_mday = (int) (days + 1);
2421  tmp->tm_isdst = 0;
2422 #if defined(HAVE_STRUCT_TM_TM_GMTOFF)
2423  tmp->tm_gmtoff = offset;
2424 #endif
2425 }
#define SECSPERMIN
Definition: switch_time.c:1679
static const int year_lengths[2]
Definition: switch_time.c:1834
#define EPOCH_WDAY
Definition: switch_time.c:1783
static const int mon_lengths[2][MONSPERYEAR]
Definition: switch_time.c:1829
long ls_corr
Definition: switch_time.c:1812
#define switch_assert(expr)
Definition: switch_time.c:2322
#define isleap(y)
Definition: switch_time.c:1727
#define SECSPERHOUR
Definition: switch_time.c:1685
#define SECSPERDAY
Definition: switch_time.c:1686
#define LEAPS_THRU_END_OF(y)
#define DAYSPERWEEK
Definition: switch_time.c:1682
#define TM_YEAR_BASE
Definition: switch_time.c:1780
while(unpack->bits_cur<=SWITCH_BITS_PER_BYTE)
#define EPOCH_YEAR
Definition: switch_time.c:1782
time_t ls_trans
Definition: switch_time.c:1811
#define DAYSPERNYEAR
Definition: switch_time.c:1683
static void tm2switchtime ( struct tm *  tm,
switch_time_exp_t xt 
)
static

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

1325 {
1326 
1327  if (!xt || !tm) {
1328  return;
1329  }
1330  memset(xt, 0, sizeof(*xt));
1331 
1332  xt->tm_sec = tm->tm_sec;
1333  xt->tm_min = tm->tm_min;
1334  xt->tm_hour = tm->tm_hour;
1335  xt->tm_mday = tm->tm_mday;
1336  xt->tm_mon = tm->tm_mon;
1337  xt->tm_year = tm->tm_year;
1338  xt->tm_wday = tm->tm_wday;
1339  xt->tm_yday = tm->tm_yday;
1340  xt->tm_isdst = tm->tm_isdst;
1341 
1342 #if defined(HAVE_STRUCT_TM_TM_GMTOFF)
1343  xt->tm_gmtoff = tm->tm_gmtoff;
1344 #endif
1345 
1346  return;
1347 }
memset(buf, 0, buflen)
static time_t transtime ( const time_t  janfirst,
const int  year,
register const struct rule *const  rulep,
const long  offset 
)
static

Definition at line 2012 of file switch_time.c.

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

Referenced by tzparse().

2013 {
2014  register int leapyear;
2015  register time_t value;
2016  register int i;
2017  int d, m1, yy0, yy1, yy2, dow;
2018 
2019  INITIALIZE(value);
2020  leapyear = isleap(year);
2021  switch (rulep->r_type) {
2022 
2023  case JULIAN_DAY:
2024  /*
2025  ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
2026  ** years.
2027  ** In non-leap years, or if the day number is 59 or less, just
2028  ** add SECSPERDAY times the day number-1 to the time of
2029  ** January 1, midnight, to get the day.
2030  */
2031  value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
2032  if (leapyear && rulep->r_day >= 60)
2033  value += SECSPERDAY;
2034  break;
2035 
2036  case DAY_OF_YEAR:
2037  /*
2038  ** n - day of year.
2039  ** Just add SECSPERDAY times the day number to the time of
2040  ** January 1, midnight, to get the day.
2041  */
2042  value = janfirst + rulep->r_day * SECSPERDAY;
2043  break;
2044 
2045  case MONTH_NTH_DAY_OF_WEEK:
2046  /*
2047  ** Mm.n.d - nth "dth day" of month m.
2048  */
2049  value = janfirst;
2050  for (i = 0; i < rulep->r_mon - 1; ++i)
2051  value += mon_lengths[leapyear][i] * SECSPERDAY;
2052 
2053  /*
2054  ** Use Zeller's Congruence to get day-of-week of first day of
2055  ** month.
2056  */
2057  m1 = (rulep->r_mon + 9) % 12 + 1;
2058  yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
2059  yy1 = yy0 / 100;
2060  yy2 = yy0 % 100;
2061  dow = ((26 * m1 - 2) / 10 + 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
2062  if (dow < 0)
2063  dow += DAYSPERWEEK;
2064 
2065  /*
2066  ** "dow" is the day-of-week of the first day of the month. Get
2067  ** the day-of-month (zero-origin) of the first "dow" day of the
2068  ** month.
2069  */
2070  d = rulep->r_day - dow;
2071  if (d < 0)
2072  d += DAYSPERWEEK;
2073  for (i = 1; i < rulep->r_week; ++i) {
2074  if (d + DAYSPERWEEK >= mon_lengths[leapyear][rulep->r_mon - 1])
2075  break;
2076  d += DAYSPERWEEK;
2077  }
2078 
2079  /*
2080  ** "d" is the day-of-month (zero-origin) of the day we want.
2081  */
2082  value += d * SECSPERDAY;
2083  break;
2084  }
2085 
2086  /*
2087  ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
2088  ** question. To get the Epoch-relative time of the specified local
2089  ** time on that day, add the transition time and the current offset
2090  ** from UTC.
2091  */
2092  return value + rulep->r_time + offset;
2093 }
#define JULIAN_DAY
Definition: switch_time.c:1689
static const int mon_lengths[2][MONSPERYEAR]
Definition: switch_time.c:1829
#define INITIALIZE(x)
Definition: switch_time.c:1754
#define isleap(y)
Definition: switch_time.c:1727
#define SECSPERDAY
Definition: switch_time.c:1686
#define DAYSPERWEEK
Definition: switch_time.c:1682
#define MONTH_NTH_DAY_OF_WEEK
Definition: switch_time.c:1691
#define DAY_OF_YEAR
Definition: switch_time.c:1690
static int tzparse ( const char *  name,
register struct state *const  sp,
const int  lastditch 
)
static

Definition at line 2102 of file switch_time.c.

References state::ats, state::charcnt, state::chars, EPOCH_YEAR, FALSE, getoffset(), getrule(), getzname(), if(), INITIALIZE, isleap, state::leapcnt, 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, and TZ_MAX_TIMES.

Referenced by tztime().

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

Definition at line 2431 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 switch_strftime_tz(), and switch_time_exp_tz_name().

2432 {
2433  struct state *tzptr, *sp;
2434  const time_t t = *timep;
2435  register int i;
2436  register const struct ttinfo *ttisp;
2437 
2438  if (tzstring == NULL)
2439  tzstring = gmt;
2440 
2441  tzptr = (struct state *) malloc(sizeof(struct state));
2442  sp = tzptr;
2443 
2444  if (tzptr != NULL) {
2445 
2446  memset(tzptr, 0, sizeof(struct state));
2447 
2448  (void) tzparse(tzstring, tzptr, FALSE);
2449 
2450  if (sp->timecnt == 0 || t < sp->ats[0]) {
2451  i = 0;
2452  while (sp->ttis[i].tt_isdst)
2453  if (++i >= sp->typecnt) {
2454  i = 0;
2455  break;
2456  }
2457  } else {
2458  for (i = 1; i < sp->timecnt; ++i)
2459  if (t < sp->ats[i])
2460  break;
2461  i = sp->types[i - 1]; // DST begin or DST end
2462  }
2463  ttisp = &sp->ttis[i];
2464 
2465  /*
2466  To get (wrong) behavior that's compatible with System V Release 2.0
2467  you'd replace the statement below with
2468  t += ttisp->tt_gmtoff;
2469  timesub(&t, 0L, sp, tmp);
2470  */
2471  if (tmp != NULL) { /* Just a check not to assert */
2472  timesub(&t, ttisp->tt_gmtoff, sp, tmp);
2473  tmp->tm_isdst = ttisp->tt_isdst;
2474 #if defined(HAVE_STRUCT_TM_TM_ZONE)
2475  tmp->tm_zone = &sp->chars[ttisp->tt_abbrind];
2476 #endif
2477  }
2478 
2479  free(tzptr);
2480  }
2481 
2482 }
time_t ats[TZ_MAX_TIMES]
Definition: switch_time.c:1821
static const char gmt[]
Definition: switch_time.c:1790
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:2325
static int tzparse(const char *name, register struct state *const sp, const int lastditch)
Definition: switch_time.c:2102
char chars[CHARS_DEF]
Definition: switch_time.c:1824
long tt_gmtoff
Definition: switch_time.c:1803
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: switch_time.c:1823
unsigned char types[TZ_MAX_TIMES]
Definition: switch_time.c:1822
int timecnt
Definition: switch_time.c:1818
int tt_abbrind
Definition: switch_time.c:1805
int tt_isdst
Definition: switch_time.c:1804
int typecnt
Definition: switch_time.c:1819
#define FALSE
Definition: switch_time.c:1630
memset(buf, 0, buflen)
static void win32_init_timers ( void  )
static

Definition at line 970 of file switch_time.c.

Referenced by SWITCH_MODULE_LOAD_FUNCTION(), and SWITCH_MODULE_RUNTIME_FUNCTION().

971 {
972 #ifdef WIN32
973  OSVERSIONINFOEX version_info; /* Used to fetch current OS version from Windows */
974 
975  EnterCriticalSection(&timer_section);
976 
977  ZeroMemory(&version_info, sizeof(OSVERSIONINFOEX));
978  version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
979 
980  /* Check if we should use timeGetTime() (pre-Vista) or QueryPerformanceCounter() (Vista and later) */
981 
982  if (GetVersionEx((OSVERSIONINFO*) &version_info)) {
983  if (version_info.dwPlatformId == VER_PLATFORM_WIN32_NT && version_info.dwMajorVersion >= 6) {
984  if (QueryPerformanceFrequency((LARGE_INTEGER*)&win32_qpc_freq) && win32_qpc_freq > 0) {
985  /* At least Vista, and QueryPerformanceFrequency() suceeded, enable qpc */
986  win32_use_qpc = 1;
987  } else {
988  /* At least Vista, but QueryPerformanceFrequency() failed, disable qpc */
989  win32_use_qpc = 0;
990  }
991  } else {
992  /* Older then Vista, disable qpc */
993  win32_use_qpc = 0;
994  }
995  } else {
996  /* Unknown version - we want at least Vista, disable qpc */
997  win32_use_qpc = 0;
998  }
999 
1000  if (win32_use_qpc) {
1001  uint64_t count = 0;
1002 
1003  if (!QueryPerformanceCounter((LARGE_INTEGER*)&count) || count == 0) {
1004  /* Call to QueryPerformanceCounter() failed, disable qpc again */
1005  win32_use_qpc = 0;
1006  }
1007  }
1008 
1009  if (!win32_use_qpc) {
1010  /* This will enable timeGetTime() instead, qpc init failed */
1011  win32_last_get_time_tick = timeGetTime();
1012  win32_tick_time_since_start = win32_last_get_time_tick;
1013  }
1014 
1015  LeaveCriticalSection(&timer_section);
1016 #endif
1017 }

Variable Documentation

int COND = 1
static

Definition at line 86 of file switch_time.c.

Referenced by SWITCH_MODULE_RUNTIME_FUNCTION(), and switch_time_set_cond_yield().

struct { ... } globals
const char gmt[] = "GMT"
static

Definition at line 1790 of file switch_time.c.

Referenced by tztime().

switch_time_t last_time = 0
static

Definition at line 587 of file switch_time.c.

int MATRIX = 1
static
switch_memory_pool_t* module_pool = NULL
static
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 1829 of file switch_time.c.

int MONO = 0
static
int NANO = 0
static
switch_event_node_t* NODE = NULL
static

Definition at line 1359 of file switch_time.c.

int OFFSET = 0
static

Definition at line 84 of file switch_time.c.

Referenced by do_sleep(), and switch_time_calibrate_clock().

int32_t RUNNING

Definition at line 102 of file switch_time.c.

int32_t STARTED

Definition at line 103 of file switch_time.c.

int SYSTEM_TIME = 0
static
int TFD = 0
static
uint32_t timer_count

Definition at line 106 of file switch_time.c.

timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
static

Definition at line 137 of file switch_time.c.

switch_timezones_list_t TIMEZONES_LIST = { 0 }
static

Definition at line 1358 of file switch_time.c.

int32_t use_cond_yield

Definition at line 104 of file switch_time.c.

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

Definition at line 1834 of file switch_time.c.