Asterisk - The Open Source Telephony Project GIT-master-b023714
Loading...
Searching...
No Matches
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.
 
void ast_timer_close (struct ast_timer *handle)
 Close an opened timing handle.
 
int ast_timer_disable_continuous (const struct ast_timer *handle)
 Disable continuous mode.
 
int ast_timer_enable_continuous (const struct ast_timer *handle)
 Enable continuous mode.
 
int ast_timer_fd (const struct ast_timer *handle)
 Get a poll()-able file descriptor for a timer.
 
enum ast_timer_event ast_timer_get_event (const struct ast_timer *handle)
 Retrieve timing event.
 
unsigned int ast_timer_get_max_rate (const struct ast_timer *handle)
 Get maximum rate supported for a timer.
 
const char * ast_timer_get_name (const struct ast_timer *handle)
 Get name of timer in use.
 
struct ast_timerast_timer_open (void)
 Open a timer.
 
int ast_timer_set_rate (const struct ast_timer *handle, unsigned int rate)
 Set the timing tick rate.
 
int ast_timing_init (void)
 
int ast_unregister_timing_interface (void *handle)
 Unregister a previously registered timing interface.
 
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.

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 ||
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}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition astmm.h:202
#define ast_heap_unlock(h)
Definition heap.h:249
#define ast_heap_push(h, elm)
Push an element on to a heap.
Definition heap.h:125
#define ast_heap_wrlock(h)
Definition heap.h:247
#define NULL
Definition resample.c:96
int(* timer_set_rate)(void *data, unsigned int rate)
Definition timing.h:76
enum ast_timer_event(* timer_get_event)(void *data)
Definition timing.h:80
int(* timer_disable_continuous)(void *data)
Definition timing.h:79
int(* timer_enable_continuous)(void *data)
Definition timing.h:78
void *(* timer_open)(void)
Definition timing.h:74
void(* timer_close)(void *data)
Definition timing.h:75
int(* timer_fd)(void *data)
Definition timing.h:82
int(* timer_ack)(void *data, unsigned int quantity)
Definition timing.h:77
unsigned int(* timer_get_max_rate)(void *data)
Definition timing.h:81
struct ast_module * mod
Definition timing.c:48
struct ast_timing_interface * iface
Definition timing.c:49
static struct ast_heap * timing_interfaces
Definition timing.c:52

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, ast_timing_interface::timer_set_rate, and timing_interfaces.

◆ 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.

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

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(), timing_test(), and webchan_read().

◆ ast_timer_close()

void ast_timer_close ( struct ast_timer handle)

Close an opened timing handle.

Parameters
handletimer handle returned from timer_open()
Since
1.6.1

Definition at line 154 of file timing.c.

155{
156 handle->holder->iface->timer_close(handle->data);
157 ast_module_unref(handle->holder->mod);
158 ast_free(handle);
159}
#define ast_free(a)
Definition astmm.h:180
#define ast_module_unref(mod)
Release a reference to the module.
Definition module.h:483

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(), timing_test(), and websocket_destructor().

◆ 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.

182{
183 return handle->holder->iface->timer_disable_continuous(handle->data);
184}

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

Referenced by __ast_read().

◆ 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.

177{
178 return handle->holder->iface->timer_enable_continuous(handle->data);
179}

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

Referenced by __ast_queue_frame().

◆ 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.

162{
163 return handle->holder->iface->timer_fd(handle->data);
164}

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(), set_channel_timer(), softmix_mixing_loop(), spandsp_fax_new(), stasis_app_control_snoop(), and timing_test().

◆ 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.

187{
188 return handle->holder->iface->timer_get_event(handle->data);
189}

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

Referenced by __ast_read(), and webchan_read().

◆ 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.

192{
193 return handle->holder->iface->timer_get_max_rate(handle->data);
194}

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

Referenced by ast_settimeout_full().

◆ 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.

197{
198 return handle->holder->iface->name;
199}
const char * name
Definition timing.h:70

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

Referenced by __ast_channel_alloc_ap().

◆ 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.

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)))) {
143 } else {
144 t->data = data;
145 t->holder = h;
146 }
147 }
148
150
151 return t;
152}
#define ast_heap_rdlock(h)
Definition heap.h:248
void * ast_heap_peek(struct ast_heap *h, unsigned int index)
Peek at an element on a heap.
Definition heap.c:267
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition module.h:469

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, ast_timing_interface::timer_open, and timing_interfaces.

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

◆ 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.

167{
168 return handle->holder->iface->timer_set_rate(handle->data, rate);
169}

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_channel_timer(), set_config(), softmix_mixing_loop(), spandsp_fax_start(), stasis_app_control_snoop(), and timing_test().

◆ ast_timing_init()

int ast_timing_init ( void  )

Provided by timing.c

Definition at line 289 of file timing.c.

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

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

Referenced by asterisk_daemon().

◆ 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.

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}
void * ast_heap_remove(struct ast_heap *h, void *elm)
Remove a specific element from a heap.
Definition heap.c:251

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

Referenced by unload_module(), unload_module(), unload_module(), and unload_module().

◆ timing_holder_cmp()

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

Definition at line 59 of file timing.c.

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}
unsigned int priority
Definition timing.h:73

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

Referenced by ast_timing_init().

◆ timing_shutdown()

static void timing_shutdown ( void  )
static

Definition at line 281 of file timing.c.

282{
284
287}
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408
struct ast_heap * ast_heap_destroy(struct ast_heap *h)
Destroy a max heap.
Definition heap.c:146

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

Referenced by ast_timing_init().

◆ 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.

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");
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
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}
static struct ast_timer * timer
Definition chan_iax2.c:388
#define CLI_SHOWUSAGE
Definition cli.h:45
#define CLI_SUCCESS
Definition cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition clicompat.c:6
@ CLI_INIT
Definition cli.h:152
@ CLI_GENERATE
Definition cli.h:153
#define CLI_FAILURE
Definition cli.h:46
char * end
Definition eagi_proxy.c:73
int errno
#define ast_poll(a, b, c)
Definition poll-compat.h:88
char * command
Definition cli.h:186
const char * usage
Definition cli.h:177
static struct test_val a
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition time.h:107
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition time.h:159
void ast_timer_close(struct ast_timer *handle)
Close an opened timing handle.
Definition timing.c:154
int ast_timer_ack(const struct ast_timer *handle, unsigned int quantity)
Acknowledge a timer event.
Definition timing.c:171
int ast_timer_set_rate(const struct ast_timer *handle, unsigned int rate)
Set the timing tick rate.
Definition timing.c:166
struct ast_timer * ast_timer_open(void)
Open a timer.
Definition timing.c:122
int ast_timer_fd(const struct ast_timer *handle)
Get a poll()-able file descriptor for a timer.
Definition timing.c:161

References a, 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, end, errno, ast_timer::holder, timing_holder::iface, ast_timing_interface::name, NULL, timer, and ast_cli_entry::usage.

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.

277 {
278 AST_CLI_DEFINE(timing_test, "Run a timing test"),
279};
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197

Referenced by ast_timing_init(), and timing_shutdown().

◆ timing_interfaces

struct ast_heap* timing_interfaces
static