Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Functions | Variables
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"
Include dependency graph for timing.c:

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

◆ _ast_register_timing_interface()

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

Definition at line 73 of file timing.c.

References ast_calloc, ast_heap_push, ast_heap_unlock, ast_heap_wrlock, timing_holder::iface, timing_holder::mod, NULL, 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_fd, 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.

75 {
76  struct timing_holder *h;
77 
78  if (!funcs->timer_open ||
79  !funcs->timer_close ||
80  !funcs->timer_set_rate ||
81  !funcs->timer_ack ||
82  !funcs->timer_get_event ||
83  !funcs->timer_get_max_rate ||
84  !funcs->timer_enable_continuous ||
85  !funcs->timer_disable_continuous ||
86  !funcs->timer_fd) {
87  return NULL;
88  }
89 
90  if (!(h = ast_calloc(1, sizeof(*h)))) {
91  return NULL;
92  }
93 
94  h->iface = funcs;
95  h->mod = mod;
96 
100 
101  return h;
102 }
struct ast_timing_interface * iface
Definition: timing.c:49
#define ast_heap_unlock(h)
Definition: heap.h:248
void(* timer_close)(void *data)
Definition: timing.h:75
enum ast_timer_event(* timer_get_event)(void *data)
Definition: timing.h:80
void *(* timer_open)(void)
Definition: timing.h:74
#define NULL
Definition: resample.c:96
int(* timer_disable_continuous)(void *data)
Definition: timing.h:79
#define ast_heap_push(h, elm)
Definition: heap.h:126
int(* timer_fd)(void *data)
Definition: timing.h:82
int(* timer_set_rate)(void *data, unsigned int rate)
Definition: timing.h:76
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
unsigned int(* timer_get_max_rate)(void *data)
Definition: timing.h:81
static struct ast_heap * timing_interfaces
Definition: timing.c:52
struct ast_module * mod
Definition: timing.c:48
int(* timer_enable_continuous)(void *data)
Definition: timing.h:78
int(* timer_ack)(void *data, unsigned int quantity)
Definition: timing.h:77
#define ast_heap_wrlock(h)
Definition: heap.h:246

◆ ast_timer_ack()

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 171 of file timing.c.

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

Referenced by __ast_read(), hook_event_cb(), monmp3thread(), snoop_read(), softmix_mixing_loop(), spandsp_fax_read(), timing_read(), and timing_test().

172 {
173  return handle->holder->iface->timer_ack(handle->data, quantity);
174 }
struct ast_timing_interface * iface
Definition: timing.c:49
void * data
Definition: timing.c:55
struct timing_holder * holder
Definition: timing.c:56
int(* timer_ack)(void *data, unsigned int quantity)
Definition: timing.h:77

◆ ast_timer_close()

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 154 of file timing.c.

References ast_free, ast_module_unref, ast_timer::data, 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(), jb_framedata_destroy(), load_module(), local_ast_moh_start(), moh_class_destructor(), session_destroy(), snoop_destroy(), softmix_bridge_data_destroy(), and timing_test().

155 {
156  handle->holder->iface->timer_close(handle->data);
157  ast_module_unref(handle->holder->mod);
158  ast_free(handle);
159 }
struct ast_timing_interface * iface
Definition: timing.c:49
void(* timer_close)(void *data)
Definition: timing.h:75
void * data
Definition: timing.c:55
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
struct timing_holder * holder
Definition: timing.c:56
#define ast_free(a)
Definition: astmm.h:182
struct ast_module * mod
Definition: timing.c:48

◆ ast_timer_disable_continuous()

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 181 of file timing.c.

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

Referenced by __ast_read().

182 {
183  return handle->holder->iface->timer_disable_continuous(handle->data);
184 }
struct ast_timing_interface * iface
Definition: timing.c:49
void * data
Definition: timing.c:55
int(* timer_disable_continuous)(void *data)
Definition: timing.h:79
struct timing_holder * holder
Definition: timing.c:56

◆ ast_timer_enable_continuous()

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 176 of file timing.c.

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

Referenced by __ast_queue_frame().

177 {
178  return handle->holder->iface->timer_enable_continuous(handle->data);
179 }
struct ast_timing_interface * iface
Definition: timing.c:49
void * data
Definition: timing.c:55
struct timing_holder * holder
Definition: timing.c:56
int(* timer_enable_continuous)(void *data)
Definition: timing.h:78

◆ ast_timer_fd()

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 161 of file timing.c.

References ast_timer::data, ast_timer::holder, timing_holder::iface, and ast_timing_interface::timer_fd.

Referenced by __ast_channel_alloc_ap(), jb_framedata_init(), monmp3thread(), network_thread(), softmix_mixing_loop(), spandsp_fax_new(), stasis_app_control_snoop(), and timing_test().

162 {
163  return handle->holder->iface->timer_fd(handle->data);
164 }
struct ast_timing_interface * iface
Definition: timing.c:49
void * data
Definition: timing.c:55
int(* timer_fd)(void *data)
Definition: timing.h:82
struct timing_holder * holder
Definition: timing.c:56

◆ ast_timer_get_event()

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 186 of file timing.c.

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

Referenced by __ast_read().

187 {
188  return handle->holder->iface->timer_get_event(handle->data);
189 }
struct ast_timing_interface * iface
Definition: timing.c:49
enum ast_timer_event(* timer_get_event)(void *data)
Definition: timing.h:80
void * data
Definition: timing.c:55
struct timing_holder * holder
Definition: timing.c:56

◆ ast_timer_get_max_rate()

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 191 of file timing.c.

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

Referenced by ast_settimeout_full().

192 {
193  return handle->holder->iface->timer_get_max_rate(handle->data);
194 }
struct ast_timing_interface * iface
Definition: timing.c:49
void * data
Definition: timing.c:55
struct timing_holder * holder
Definition: timing.c:56
unsigned int(* timer_get_max_rate)(void *data)
Definition: timing.h:81

◆ ast_timer_get_name()

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 196 of file timing.c.

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

Referenced by __ast_channel_alloc_ap().

197 {
198  return handle->holder->iface->name;
199 }
const char * name
Definition: timing.h:70
struct ast_timing_interface * iface
Definition: timing.c:49
struct timing_holder * holder
Definition: timing.c:56

◆ ast_timer_open()

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 122 of file timing.c.

References ast_calloc, ast_heap_peek(), ast_heap_rdlock, ast_heap_unlock, ast_module_running_ref, ast_module_unref, ast_timer::data, ast_timer::holder, timing_holder::iface, timing_holder::mod, NULL, ast_timing_interface::timer_close, and ast_timing_interface::timer_open.

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

123 {
124  void *data = NULL;
125  struct timing_holder *h;
126  struct ast_timer *t = NULL;
127  int idx = 1;
128 
130 
131  while ((h = ast_heap_peek(timing_interfaces, idx))) {
132  if (ast_module_running_ref(h->mod)) {
133  data = h->iface->timer_open();
134  break;
135  }
136  idx++;
137  }
138 
139  if (data) {
140  if (!(t = ast_calloc(1, sizeof(*t)))) {
141  h->iface->timer_close(data);
142  ast_module_unref(h->mod);
143  } else {
144  t->data = data;
145  t->holder = h;
146  }
147  }
148 
150 
151  return t;
152 }
struct ast_timing_interface * iface
Definition: timing.c:49
#define ast_heap_unlock(h)
Definition: heap.h:248
void(* timer_close)(void *data)
Definition: timing.h:75
void *(* timer_open)(void)
Definition: timing.h:74
void * data
Definition: timing.c:55
#define NULL
Definition: resample.c:96
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
struct timing_holder * holder
Definition: timing.c:56
#define ast_heap_rdlock(h)
Definition: heap.h:247
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static struct ast_heap * timing_interfaces
Definition: timing.c:52
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:455
struct ast_module * mod
Definition: timing.c:48
void * ast_heap_peek(struct ast_heap *h, unsigned int index)
Peek at an element on a heap.
Definition: heap.c:267

◆ ast_timer_set_rate()

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 166 of file timing.c.

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

Referenced by __ast_read(), ast_deactivate_generator(), ast_settimeout_full(), hook_event_cb(), init_app_class(), jb_framedata_init(), load_module(), local_ast_moh_start(), set_config(), softmix_mixing_loop(), spandsp_fax_start(), stasis_app_control_snoop(), and timing_test().

167 {
168  return handle->holder->iface->timer_set_rate(handle->data, rate);
169 }
struct ast_timing_interface * iface
Definition: timing.c:49
void * data
Definition: timing.c:55
struct timing_holder * holder
Definition: timing.c:56
int(* timer_set_rate)(void *data, unsigned int rate)
Definition: timing.h:76

◆ ast_timing_init()

int ast_timing_init ( void  )

Provided by timing.c

Definition at line 289 of file timing.c.

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

Referenced by asterisk_daemon().

290 {
292  return -1;
293  }
294 
296 
298 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static void timing_shutdown(void)
Definition: timing.c:281
static int timing_holder_cmp(void *_h1, void *_h2)
Definition: timing.c:59
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
static struct ast_heap * timing_interfaces
Definition: timing.c:52
#define ast_heap_create(init_height, cmp_fn, index_offset)
Definition: heap.h:102
static struct ast_cli_entry cli_timing[]
Definition: timing.c:277

◆ ast_unregister_timing_interface()

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 104 of file timing.c.

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

Referenced by unload_module().

105 {
106  struct timing_holder *h = handle;
107  int res = -1;
108 
112 
113  if (h) {
114  ast_free(h);
115  h = NULL;
116  res = 0;
117  }
118 
119  return res;
120 }
#define ast_heap_unlock(h)
Definition: heap.h:248
#define NULL
Definition: resample.c:96
#define ast_free(a)
Definition: astmm.h:182
static struct ast_heap * timing_interfaces
Definition: timing.c:52
void * ast_heap_remove(struct ast_heap *h, void *elm)
Remove a specific element from a heap.
Definition: heap.c:251
#define ast_heap_wrlock(h)
Definition: heap.h:246

◆ timing_holder_cmp()

static int timing_holder_cmp ( void *  _h1,
void *  _h2 
)
static

Definition at line 59 of file timing.c.

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

Referenced by ast_timing_init().

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

◆ timing_shutdown()

static void timing_shutdown ( void  )
static

Definition at line 281 of file timing.c.

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

Referenced by ast_timing_init().

282 {
284 
287 }
#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: clicompat.c:30
struct ast_heap * ast_heap_destroy(struct ast_heap *h)
Destroy a max heap.
Definition: heap.c:146
#define NULL
Definition: resample.c:96
static struct ast_heap * timing_interfaces
Definition: timing.c:52
static struct ast_cli_entry cli_timing[]
Definition: timing.c:277

◆ timing_test()

static char* timing_test ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 201 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, NULL, timer, and ast_cli_entry::usage.

202 {
203  struct ast_timer *timer;
204  int count = 0;
205  struct timeval start, end;
206  unsigned int test_rate = 50;
207 
208  switch (cmd) {
209  case CLI_INIT:
210  e->command = "timing test";
211  e->usage = "Usage: timing test <rate>\n"
212  " Test a timer with a specified rate, 50/sec by default.\n"
213  "";
214  return NULL;
215  case CLI_GENERATE:
216  return NULL;
217  }
218 
219  if (a->argc != 2 && a->argc != 3) {
220  return CLI_SHOWUSAGE;
221  }
222 
223  if (a->argc == 3) {
224  unsigned int rate;
225  if (sscanf(a->argv[2], "%30u", &rate) == 1) {
226  test_rate = rate;
227  } else {
228  ast_cli(a->fd, "Invalid rate '%s', using default of %u\n", a->argv[2], test_rate);
229  }
230  }
231 
232  ast_cli(a->fd, "Attempting to test a timer with %u ticks per second.\n", test_rate);
233 
234  if (!(timer = ast_timer_open())) {
235  ast_cli(a->fd, "Failed to open timing fd\n");
236  return CLI_FAILURE;
237  }
238 
239  ast_cli(a->fd, "Using the '%s' timing module for this test.\n", timer->holder->iface->name);
240 
241  start = ast_tvnow();
242 
243  ast_timer_set_rate(timer, test_rate);
244 
245  while (ast_tvdiff_ms((end = ast_tvnow()), start) < 1000) {
246  int res;
247  struct pollfd pfd = {
248  .fd = ast_timer_fd(timer),
249  .events = POLLIN | POLLPRI,
250  };
251 
252  res = ast_poll(&pfd, 1, 100);
253 
254  if (res == 1) {
255  count++;
256  if (ast_timer_ack(timer, 1) < 0) {
257  ast_cli(a->fd, "Timer failed to acknowledge.\n");
258  ast_timer_close(timer);
259  return CLI_FAILURE;
260  }
261  } else if (!res) {
262  ast_cli(a->fd, "poll() timed out! This is bad.\n");
263  } else if (errno != EAGAIN && errno != EINTR) {
264  ast_cli(a->fd, "poll() returned error: %s\n", strerror(errno));
265  }
266  }
267 
268  ast_timer_close(timer);
269  timer = NULL;
270 
271  ast_cli(a->fd, "It has been %" PRIi64 " milliseconds, and we got %d timer ticks\n",
272  ast_tvdiff_ms(end, start), count);
273 
274  return CLI_SUCCESS;
275 }
void ast_timer_close(struct ast_timer *handle)
Close an opened timing handle.
Definition: timing.c:154
const char * name
Definition: timing.h:70
struct ast_timing_interface * iface
Definition: timing.c:49
const int argc
Definition: cli.h:160
struct ast_timer * ast_timer_open(void)
Open a timer.
Definition: timing.c:122
Definition: cli.h:152
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
#define ast_poll(a, b, c)
Definition: poll-compat.h:88
struct timing_holder * holder
Definition: timing.c:56
const char *const * argv
Definition: cli.h:161
int ast_timer_fd(const struct ast_timer *handle)
Get a poll()-able file descriptor for a timer.
Definition: timing.c:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
int errno
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
int ast_timer_ack(const struct ast_timer *handle, unsigned int quantity)
Acknowledge a timer event.
Definition: timing.c:171
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
int ast_timer_set_rate(const struct ast_timer *handle, unsigned int rate)
Set the timing tick rate.
Definition: timing.c:166
static struct ast_timer * timer
Definition: chan_iax2.c:360

Variable Documentation

◆ cli_timing

struct ast_cli_entry cli_timing[]
static
Initial value:
= {
{ .handler = timing_test , .summary = "Run a timing test" ,},
}
static char * timing_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: timing.c:201

Definition at line 277 of file timing.c.

◆ timing_interfaces

struct ast_heap* timing_interfaces
static

Definition at line 52 of file timing.c.