Wed Jan 8 2020 09:50:21

Asterisk developer's documentation


timing.c File Reference

Timing source management. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/timing.h"
#include "asterisk/lock.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/time.h"
#include "asterisk/heap.h"
#include "asterisk/module.h"
#include "asterisk/poll-compat.h"

Go to the source code of this file.

Data Structures

struct  ast_timer
 
struct  timing_holder
 

Functions

void * _ast_register_timing_interface (struct ast_timing_interface *funcs, struct ast_module *mod)
 
int ast_timer_ack (const struct ast_timer *handle, unsigned int quantity)
 Acknowledge a timer event. More...
 
void ast_timer_close (struct ast_timer *handle)
 Close an opened timing handle. More...
 
int ast_timer_disable_continuous (const struct ast_timer *handle)
 Disable continuous mode. More...
 
int ast_timer_enable_continuous (const struct ast_timer *handle)
 Enable continuous mode. More...
 
int ast_timer_fd (const struct ast_timer *handle)
 Get a poll()-able file descriptor for a timer. More...
 
enum ast_timer_event ast_timer_get_event (const struct ast_timer *handle)
 Retrieve timing event. More...
 
unsigned int ast_timer_get_max_rate (const struct ast_timer *handle)
 Get maximum rate supported for a timer. More...
 
const char * ast_timer_get_name (const struct ast_timer *handle)
 Get name of timer in use. More...
 
struct ast_timerast_timer_open (void)
 Open a timer. More...
 
int ast_timer_set_rate (const struct ast_timer *handle, unsigned int rate)
 Set the timing tick rate. More...
 
int ast_timing_init (void)
 
int ast_unregister_timing_interface (void *handle)
 Unregister a previously registered timing interface. More...
 
static int timing_holder_cmp (void *_h1, void *_h2)
 
static void timing_shutdown (void)
 
static char * timing_test (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 

Variables

static struct ast_cli_entry cli_timing []
 
static struct ast_heaptiming_interfaces
 

Detailed Description

Timing source management.

Author
Kevin P. Fleming kpfle.nosp@m.ming.nosp@m.@digi.nosp@m.um.c.nosp@m.om
Russell Bryant russe.nosp@m.ll@d.nosp@m.igium.nosp@m..com

Definition in file timing.c.

Function Documentation

void* _ast_register_timing_interface ( struct ast_timing_interface funcs,
struct ast_module mod 
)

Definition at line 75 of file timing.c.

References ast_calloc, ast_heap_push(), ast_heap_unlock, ast_heap_wrlock, timing_holder::iface, timing_holder::mod, ast_timing_interface::timer_ack, ast_timing_interface::timer_close, ast_timing_interface::timer_disable_continuous, ast_timing_interface::timer_enable_continuous, ast_timing_interface::timer_get_event, ast_timing_interface::timer_get_max_rate, ast_timing_interface::timer_open, and ast_timing_interface::timer_set_rate.

77 {
78  struct timing_holder *h;
79 
80  if (!funcs->timer_open ||
81  !funcs->timer_close ||
82  !funcs->timer_set_rate ||
83  !funcs->timer_ack ||
84  !funcs->timer_get_event ||
85  !funcs->timer_get_max_rate ||
86  !funcs->timer_enable_continuous ||
87  !funcs->timer_disable_continuous) {
88  return NULL;
89  }
90 
91  if (!(h = ast_calloc(1, sizeof(*h)))) {
92  return NULL;
93  }
94 
95  h->iface = funcs;
96  h->mod = mod;
97 
101 
102  return h;
103 }
struct ast_timing_interface * iface
Definition: timing.c:51
int(* timer_open)(void)
Definition: timing.h:74
#define ast_heap_unlock(h)
Definition: heap.h:252
int ast_heap_push(struct ast_heap *h, void *elm)
Push an element on to a heap.
Definition: heap.c:250
int(* timer_enable_continuous)(int handle)
Definition: timing.h:78
enum ast_timer_event(* timer_get_event)(int handle)
Definition: timing.h:80
void(* timer_close)(int handle)
Definition: timing.h:75
int(* timer_disable_continuous)(int handle)
Definition: timing.h:79
int(* timer_set_rate)(int handle, unsigned int rate)
Definition: timing.h:76
int(* timer_ack)(int handle, unsigned int quantity)
Definition: timing.h:77
unsigned int(* timer_get_max_rate)(int handle)
Definition: timing.h:81
static struct ast_heap * timing_interfaces
Definition: timing.c:54
#define ast_calloc(a, b)
Definition: astmm.h:82
struct ast_module * mod
Definition: timing.c:50
#define ast_heap_wrlock(h)
Definition: heap.h:250
int ast_timer_ack ( const struct ast_timer handle,
unsigned int  quantity 
)

Acknowledge a timer event.

Parameters
handletimer handle returned from timer_open()
quantitynumber of timer events to acknowledge
Note
This function should only be called if timer_get_event() returned AST_TIMING_EVENT_EXPIRED.
Return values
-1failure, with errno set
0success
Since
10.5.2

Definition at line 172 of file timing.c.

References ast_timer::fd, ast_timer::holder, timing_holder::iface, and ast_timing_interface::timer_ack.

Referenced by __ast_read(), monmp3thread(), softmix_bridge_thread(), spandsp_fax_read(), timing_read(), and timing_test().

173 {
174  int res = -1;
175 
176  res = handle->holder->iface->timer_ack(handle->fd, quantity);
177 
178  return res;
179 }
struct ast_timing_interface * iface
Definition: timing.c:51
struct timing_holder * holder
Definition: timing.c:58
int(* timer_ack)(int handle, unsigned int quantity)
Definition: timing.h:77
int fd
Definition: timing.c:57
void ast_timer_close ( struct ast_timer handle)

Close an opened timing handle.

Parameters
handletimer handle returned from timer_open()
Returns
nothing
Since
1.6.1

Definition at line 150 of file timing.c.

References ast_free, ast_module_unref(), ast_timer::fd, ast_timer::holder, timing_holder::iface, timing_holder::mod, and ast_timing_interface::timer_close.

Referenced by __unload_module(), ast_channel_destructor(), init_app_class(), load_module(), local_ast_moh_start(), moh_class_destructor(), session_destroy(), softmix_bridge_destroy(), and timing_test().

151 {
152  handle->holder->iface->timer_close(handle->fd);
153  handle->fd = -1;
154  ast_module_unref(handle->holder->mod);
155  ast_free(handle);
156 }
void ast_module_unref(struct ast_module *)
Definition: loader.c:1312
struct ast_timing_interface * iface
Definition: timing.c:51
void(* timer_close)(int handle)
Definition: timing.h:75
struct timing_holder * holder
Definition: timing.c:58
int fd
Definition: timing.c:57
#define ast_free(a)
Definition: astmm.h:97
struct ast_module * mod
Definition: timing.c:50
int ast_timer_disable_continuous ( const struct ast_timer handle)

Disable continuous mode.

Parameters
handletimer handle returned from timer_close()
Return values
-1failure, with errno set
0success
Since
1.6.1

Definition at line 190 of file timing.c.

References ast_timer::fd, ast_timer::holder, timing_holder::iface, and ast_timing_interface::timer_disable_continuous.

Referenced by __ast_read().

191 {
192  int res = -1;
193 
194  res = handle->holder->iface->timer_disable_continuous(handle->fd);
195 
196  return res;
197 }
struct ast_timing_interface * iface
Definition: timing.c:51
int(* timer_disable_continuous)(int handle)
Definition: timing.h:79
struct timing_holder * holder
Definition: timing.c:58
int fd
Definition: timing.c:57
int ast_timer_enable_continuous ( const struct ast_timer handle)

Enable continuous mode.

Parameters
handletimer handle returned from timer_open()

Continuous mode causes poll() on the timer's fd to immediately return always until continuous mode is disabled.

Return values
-1failure, with errno set
0success
Since
1.6.1

Definition at line 181 of file timing.c.

References ast_timer::fd, ast_timer::holder, timing_holder::iface, and ast_timing_interface::timer_enable_continuous.

Referenced by __ast_queue_frame().

182 {
183  int res = -1;
184 
185  res = handle->holder->iface->timer_enable_continuous(handle->fd);
186 
187  return res;
188 }
struct ast_timing_interface * iface
Definition: timing.c:51
int(* timer_enable_continuous)(int handle)
Definition: timing.h:78
struct timing_holder * holder
Definition: timing.c:58
int fd
Definition: timing.c:57
int ast_timer_fd ( const struct ast_timer handle)

Get a poll()-able file descriptor for a timer.

Parameters
handletimer handle returned from timer_open()
Returns
file descriptor which can be used with poll() to wait for events
Since
1.6.1

Definition at line 158 of file timing.c.

References ast_timer::fd.

Referenced by __ast_channel_alloc_ap(), monmp3thread(), network_thread(), softmix_bridge_thread(), spandsp_fax_new(), and timing_test().

159 {
160  return handle->fd;
161 }
int fd
Definition: timing.c:57
enum ast_timer_event ast_timer_get_event ( const struct ast_timer handle)

Retrieve timing event.

Parameters
handletimer handle returned by timer_open()

After poll() indicates that there is input on the timer's fd, this will be called to find out what triggered it.

Returns
which event triggered the timer
Since
1.6.1

Definition at line 199 of file timing.c.

References ast_timer::fd, ast_timer::holder, timing_holder::iface, and ast_timing_interface::timer_get_event.

Referenced by __ast_read().

200 {
201  enum ast_timer_event res = -1;
202 
203  res = handle->holder->iface->timer_get_event(handle->fd);
204 
205  return res;
206 }
struct ast_timing_interface * iface
Definition: timing.c:51
ast_timer_event
Definition: timing.h:57
enum ast_timer_event(* timer_get_event)(int handle)
Definition: timing.h:80
struct timing_holder * holder
Definition: timing.c:58
int fd
Definition: timing.c:57
unsigned int ast_timer_get_max_rate ( const struct ast_timer handle)

Get maximum rate supported for a timer.

Parameters
handletimer handle returned by timer_open()
Returns
maximum rate supported by timer
Since
1.6.1

Definition at line 208 of file timing.c.

References ast_timer::fd, ast_timer::holder, timing_holder::iface, and ast_timing_interface::timer_get_max_rate.

Referenced by ast_settimeout_full().

209 {
210  unsigned int res = 0;
211 
212  res = handle->holder->iface->timer_get_max_rate(handle->fd);
213 
214  return res;
215 }
struct ast_timing_interface * iface
Definition: timing.c:51
struct timing_holder * holder
Definition: timing.c:58
unsigned int(* timer_get_max_rate)(int handle)
Definition: timing.h:81
int fd
Definition: timing.c:57
const char* ast_timer_get_name ( const struct ast_timer handle)

Get name of timer in use.

Parameters
handletimer handle returned by timer_open()
Returns
name of timer
Since
1.6.2

Definition at line 217 of file timing.c.

References ast_timer::holder, timing_holder::iface, and ast_timing_interface::name.

Referenced by __ast_channel_alloc_ap().

218 {
219  return handle->holder->iface->name;
220 }
const char * name
Definition: timing.h:70
struct ast_timing_interface * iface
Definition: timing.c:51
struct timing_holder * holder
Definition: timing.c:58
struct ast_timer* ast_timer_open ( void  )

Open a timer.

Return values
NULLon error, with errno set
non-NULLtimer handle on success
Since
1.6.1

Definition at line 123 of file timing.c.

References ast_calloc, ast_heap_peek(), ast_heap_rdlock, ast_heap_unlock, ast_module_ref(), ast_timer::fd, ast_timer::holder, timing_holder::iface, timing_holder::mod, ast_timing_interface::timer_close, and ast_timing_interface::timer_open.

Referenced by __ast_channel_alloc_ap(), init_app_class(), load_module(), local_ast_moh_start(), softmix_bridge_create(), spandsp_fax_new(), and timing_test().

124 {
125  int fd = -1;
126  struct timing_holder *h;
127  struct ast_timer *t = NULL;
128 
130 
131  if ((h = ast_heap_peek(timing_interfaces, 1))) {
132  fd = h->iface->timer_open();
133  ast_module_ref(h->mod);
134  }
135 
136  if (fd != -1) {
137  if (!(t = ast_calloc(1, sizeof(*t)))) {
138  h->iface->timer_close(fd);
139  } else {
140  t->fd = fd;
141  t->holder = h;
142  }
143  }
144 
146 
147  return t;
148 }
struct ast_timing_interface * iface
Definition: timing.c:51
int(* timer_open)(void)
Definition: timing.h:74
#define ast_heap_unlock(h)
Definition: heap.h:252
void(* timer_close)(int handle)
Definition: timing.h:75
struct timing_holder * holder
Definition: timing.c:58
#define ast_heap_rdlock(h)
Definition: heap.h:251
int fd
Definition: timing.c:57
static struct ast_heap * timing_interfaces
Definition: timing.c:54
#define ast_calloc(a, b)
Definition: astmm.h:82
struct ast_module * mod
Definition: timing.c:50
void * ast_heap_peek(struct ast_heap *h, unsigned int index)
Peek at an element on a heap.
Definition: heap.c:300
struct ast_module * ast_module_ref(struct ast_module *)
Definition: loader.c:1300
int ast_timer_set_rate ( const struct ast_timer handle,
unsigned int  rate 
)

Set the timing tick rate.

Parameters
handletimer handle returned from timer_open()
rateticks per second, 0 turns the ticks off if needed

Use this function if you want the timer to show input at a certain rate. The other alternative use of a timer is the continuous mode.

Return values
-1error, with errno set
0success
Since
1.6.1

Definition at line 163 of file timing.c.

References ast_timer::fd, ast_timer::holder, timing_holder::iface, and ast_timing_interface::timer_set_rate.

Referenced by __ast_read(), ast_settimeout_full(), init_app_class(), load_module(), local_ast_moh_start(), set_config(), softmix_bridge_thread(), spandsp_fax_start(), and timing_test().

164 {
165  int res = -1;
166 
167  res = handle->holder->iface->timer_set_rate(handle->fd, rate);
168 
169  return res;
170 }
struct ast_timing_interface * iface
Definition: timing.c:51
int(* timer_set_rate)(int handle, unsigned int rate)
Definition: timing.h:76
struct timing_holder * holder
Definition: timing.c:58
int fd
Definition: timing.c:57
int ast_timing_init ( void  )

Provided by timing.c

Definition at line 310 of file timing.c.

References ARRAY_LEN, ast_cli_register_multiple(), ast_heap_create(), ast_register_atexit(), timing_holder_cmp(), and timing_shutdown().

Referenced by main().

311 {
313  return -1;
314  }
315 
317 
319 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static void timing_shutdown(void)
Definition: timing.c:302
static int timing_holder_cmp(void *_h1, void *_h2)
Definition: timing.c:61
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:998
static struct ast_heap * timing_interfaces
Definition: timing.c:54
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
struct ast_heap * ast_heap_create(unsigned int init_height, ast_heap_cmp_fn cmp_fn, ssize_t index_offset)
Create a max heap.
Definition: heap.c:118
static struct ast_cli_entry cli_timing[]
Definition: timing.c:298
int ast_unregister_timing_interface ( void *  handle)

Unregister a previously registered timing interface.

Parameters
handleThe handle returned from a prior successful call to ast_register_timing_interface().
Return values
0success
non-zerofailure
Since
1.6.1

Definition at line 105 of file timing.c.

References ast_free, ast_heap_remove(), ast_heap_unlock, and ast_heap_wrlock.

Referenced by unload_module().

106 {
107  struct timing_holder *h = handle;
108  int res = -1;
109 
113 
114  if (h) {
115  ast_free(h);
116  h = NULL;
117  res = 0;
118  }
119 
120  return res;
121 }
#define ast_heap_unlock(h)
Definition: heap.h:252
#define ast_free(a)
Definition: astmm.h:97
static struct ast_heap * timing_interfaces
Definition: timing.c:54
void * ast_heap_remove(struct ast_heap *h, void *elm)
Remove a specific element from a heap.
Definition: heap.c:284
#define ast_heap_wrlock(h)
Definition: heap.h:250
static int timing_holder_cmp ( void *  _h1,
void *  _h2 
)
static

Definition at line 61 of file timing.c.

References timing_holder::iface, and ast_timing_interface::priority.

Referenced by ast_timing_init().

62 {
63  struct timing_holder *h1 = _h1;
64  struct timing_holder *h2 = _h2;
65 
66  if (h1->iface->priority > h2->iface->priority) {
67  return 1;
68  } else if (h1->iface->priority == h2->iface->priority) {
69  return 0;
70  } else {
71  return -1;
72  }
73 }
struct ast_timing_interface * iface
Definition: timing.c:51
unsigned int priority
Definition: timing.h:73
static void timing_shutdown ( void  )
static

Definition at line 302 of file timing.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), and ast_heap_destroy().

Referenced by ast_timing_init().

303 {
305 
307  timing_interfaces = NULL;
308 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
struct ast_heap * ast_heap_destroy(struct ast_heap *h)
Destroy a max heap.
Definition: heap.c:163
static struct ast_heap * timing_interfaces
Definition: timing.c:54
static struct ast_cli_entry cli_timing[]
Definition: timing.c:298
static char* timing_test ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 222 of file timing.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_poll, ast_timer_ack(), ast_timer_close(), ast_timer_fd(), ast_timer_open(), ast_timer_set_rate(), ast_tvdiff_ms(), ast_tvnow(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, errno, ast_cli_args::fd, ast_timer::holder, timing_holder::iface, ast_timing_interface::name, timer, and ast_cli_entry::usage.

223 {
224  struct ast_timer *timer;
225  int count = 0;
226  struct timeval start, end;
227  unsigned int test_rate = 50;
228 
229  switch (cmd) {
230  case CLI_INIT:
231  e->command = "timing test";
232  e->usage = "Usage: timing test <rate>\n"
233  " Test a timer with a specified rate, 50/sec by default.\n"
234  "";
235  return NULL;
236  case CLI_GENERATE:
237  return NULL;
238  }
239 
240  if (a->argc != 2 && a->argc != 3) {
241  return CLI_SHOWUSAGE;
242  }
243 
244  if (a->argc == 3) {
245  unsigned int rate;
246  if (sscanf(a->argv[2], "%30u", &rate) == 1) {
247  test_rate = rate;
248  } else {
249  ast_cli(a->fd, "Invalid rate '%s', using default of %u\n", a->argv[2], test_rate);
250  }
251  }
252 
253  ast_cli(a->fd, "Attempting to test a timer with %u ticks per second.\n", test_rate);
254 
255  if (!(timer = ast_timer_open())) {
256  ast_cli(a->fd, "Failed to open timing fd\n");
257  return CLI_FAILURE;
258  }
259 
260  ast_cli(a->fd, "Using the '%s' timing module for this test.\n", timer->holder->iface->name);
261 
262  start = ast_tvnow();
263 
264  ast_timer_set_rate(timer, test_rate);
265 
266  while (ast_tvdiff_ms((end = ast_tvnow()), start) < 1000) {
267  int res;
268  struct pollfd pfd = {
269  .fd = ast_timer_fd(timer),
270  .events = POLLIN | POLLPRI,
271  };
272 
273  res = ast_poll(&pfd, 1, 100);
274 
275  if (res == 1) {
276  count++;
277  if (ast_timer_ack(timer, 1) < 0) {
278  ast_cli(a->fd, "Timer failed to acknowledge.\n");
279  ast_timer_close(timer);
280  return CLI_FAILURE;
281  }
282  } else if (!res) {
283  ast_cli(a->fd, "poll() timed out! This is bad.\n");
284  } else if (errno != EAGAIN && errno != EINTR) {
285  ast_cli(a->fd, "poll() returned error: %s\n", strerror(errno));
286  }
287  }
288 
289  ast_timer_close(timer);
290  timer = NULL;
291 
292  ast_cli(a->fd, "It has been %" PRIi64 " milliseconds, and we got %d timer ticks\n",
293  ast_tvdiff_ms(end, start), count);
294 
295  return CLI_SUCCESS;
296 }
const char * name
Definition: timing.h:70
struct ast_timing_interface * iface
Definition: timing.c:51
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_timer_close(struct ast_timer *handle)
Close an opened timing handle.
Definition: timing.c:150
struct ast_timer * ast_timer_open(void)
Open a timer.
Definition: timing.c:123
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
#define ast_poll(a, b, c)
Definition: poll-compat.h:88
struct timing_holder * holder
Definition: timing.c:58
const char *const * argv
Definition: cli.h:155
int ast_timer_ack(const struct ast_timer *handle, unsigned int quantity)
Acknowledge a timer event.
Definition: timing.c:172
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define CLI_FAILURE
Definition: cli.h:45
int errno
char * command
Definition: cli.h:180
int ast_timer_fd(const struct ast_timer *handle)
Get a poll()-able file descriptor for a timer.
Definition: timing.c:158
int ast_timer_set_rate(const struct ast_timer *handle, unsigned int rate)
Set the timing tick rate.
Definition: timing.c:163
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static struct ast_timer * timer
Definition: chan_iax2.c:313

Variable Documentation

struct ast_cli_entry cli_timing[]
static
Initial value:
= {
AST_CLI_DEFINE(timing_test, "Run a timing test"),
}
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
static char * timing_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: timing.c:222

Definition at line 298 of file timing.c.

struct ast_heap* timing_interfaces
static

Definition at line 54 of file timing.c.