#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) |
void | 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. | |
ast_timer * | ast_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 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_heap * | timing_interfaces |
Russell Bryant <russell@digium.com>
Definition in file timing.c.
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::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, ast_timing_interface::timer_set_rate, and timing_interfaces.
00077 { 00078 struct timing_holder *h; 00079 00080 if (!funcs->timer_open || 00081 !funcs->timer_close || 00082 !funcs->timer_set_rate || 00083 !funcs->timer_ack || 00084 !funcs->timer_get_event || 00085 !funcs->timer_get_max_rate || 00086 !funcs->timer_enable_continuous || 00087 !funcs->timer_disable_continuous) { 00088 return NULL; 00089 } 00090 00091 if (!(h = ast_calloc(1, sizeof(*h)))) { 00092 return NULL; 00093 } 00094 00095 h->iface = funcs; 00096 h->mod = mod; 00097 00098 ast_heap_wrlock(timing_interfaces); 00099 ast_heap_push(timing_interfaces, h); 00100 ast_heap_unlock(timing_interfaces); 00101 00102 return h; 00103 }
void ast_timer_ack | ( | const struct ast_timer * | handle, | |
unsigned int | quantity | |||
) |
Acknowledge a timer event.
handle | timer handle returned from timer_open() | |
quantity | number of timer events to acknowledge |
Definition at line 171 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().
void ast_timer_close | ( | struct ast_timer * | handle | ) |
Close an opened timing handle.
handle | timer handle returned from timer_open() |
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().
00151 { 00152 handle->holder->iface->timer_close(handle->fd); 00153 ast_module_unref(handle->holder->mod); 00154 ast_free(handle); 00155 }
int ast_timer_disable_continuous | ( | const struct ast_timer * | handle | ) |
Disable continuous mode.
handle | timer handle returned from timer_close() |
-1 | failure, with errno set | |
0 | success |
Definition at line 185 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().
00186 { 00187 int res = -1; 00188 00189 res = handle->holder->iface->timer_disable_continuous(handle->fd); 00190 00191 return res; 00192 }
int ast_timer_enable_continuous | ( | const struct ast_timer * | handle | ) |
Enable continuous mode.
handle | timer handle returned from timer_open() |
-1 | failure, with errno set | |
0 | success |
Definition at line 176 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().
00177 { 00178 int res = -1; 00179 00180 res = handle->holder->iface->timer_enable_continuous(handle->fd); 00181 00182 return res; 00183 }
int ast_timer_fd | ( | const struct ast_timer * | handle | ) |
Get a poll()-able file descriptor for a timer.
handle | timer handle returned from timer_open() |
Definition at line 157 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().
00158 { 00159 return handle->fd; 00160 }
enum ast_timer_event ast_timer_get_event | ( | const struct ast_timer * | handle | ) |
Retrieve timing event.
handle | timer handle returned by timer_open() |
Definition at line 194 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().
00195 { 00196 enum ast_timer_event res = -1; 00197 00198 res = handle->holder->iface->timer_get_event(handle->fd); 00199 00200 return res; 00201 }
unsigned int ast_timer_get_max_rate | ( | const struct ast_timer * | handle | ) |
Get maximum rate supported for a timer.
handle | timer handle returned by timer_open() |
Definition at line 203 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().
00204 { 00205 unsigned int res = 0; 00206 00207 res = handle->holder->iface->timer_get_max_rate(handle->fd); 00208 00209 return res; 00210 }
const char* ast_timer_get_name | ( | const struct ast_timer * | handle | ) |
Get name of timer in use.
handle | timer handle returned by timer_open() |
Definition at line 212 of file timing.c.
References ast_timer::holder, timing_holder::iface, and ast_timing_interface::name.
Referenced by __ast_channel_alloc_ap().
struct ast_timer* ast_timer_open | ( | void | ) |
Open a timer.
NULL | on error, with errno set | |
non-NULL | timer handle on success |
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, timing_holder::iface, timing_holder::mod, ast_timing_interface::timer_close, ast_timing_interface::timer_open, and timing_interfaces.
Referenced by __ast_channel_alloc_ap(), init_app_class(), load_module(), local_ast_moh_start(), softmix_bridge_create(), spandsp_fax_new(), and timing_test().
00124 { 00125 int fd = -1; 00126 struct timing_holder *h; 00127 struct ast_timer *t = NULL; 00128 00129 ast_heap_rdlock(timing_interfaces); 00130 00131 if ((h = ast_heap_peek(timing_interfaces, 1))) { 00132 fd = h->iface->timer_open(); 00133 ast_module_ref(h->mod); 00134 } 00135 00136 if (fd != -1) { 00137 if (!(t = ast_calloc(1, sizeof(*t)))) { 00138 h->iface->timer_close(fd); 00139 } else { 00140 t->fd = fd; 00141 t->holder = h; 00142 } 00143 } 00144 00145 ast_heap_unlock(timing_interfaces); 00146 00147 return t; 00148 }
int ast_timer_set_rate | ( | const struct ast_timer * | handle, | |
unsigned int | rate | |||
) |
Set the timing tick rate.
handle | timer handle returned from timer_open() | |
rate | ticks per second, 0 turns the ticks off if needed |
-1 | error, with errno set | |
0 | success |
Definition at line 162 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(), init_app_class(), load_module(), local_ast_moh_start(), set_config(), softmix_bridge_thread(), spandsp_fax_start(), and timing_test().
00163 { 00164 int res = -1; 00165 00166 res = handle->holder->iface->timer_set_rate(handle->fd, rate); 00167 00168 return res; 00169 }
int ast_timing_init | ( | void | ) |
Provided by timing.c
Definition at line 292 of file timing.c.
References ARRAY_LEN, ast_cli_register_multiple(), ast_heap_create(), cli_timing, timing_holder_cmp(), and timing_interfaces.
Referenced by main().
00293 { 00294 if (!(timing_interfaces = ast_heap_create(2, timing_holder_cmp, 0))) { 00295 return -1; 00296 } 00297 00298 return ast_cli_register_multiple(cli_timing, ARRAY_LEN(cli_timing)); 00299 }
int ast_unregister_timing_interface | ( | void * | handle | ) |
Unregister a previously registered timing interface.
handle | The handle returned from a prior successful call to ast_register_timing_interface(). |
0 | success | |
non-zero | failure |
Definition at line 105 of file timing.c.
References ast_free, ast_heap_remove(), ast_heap_unlock, ast_heap_wrlock, and timing_interfaces.
Referenced by unload_module().
00106 { 00107 struct timing_holder *h = handle; 00108 int res = -1; 00109 00110 ast_heap_wrlock(timing_interfaces); 00111 h = ast_heap_remove(timing_interfaces, h); 00112 ast_heap_unlock(timing_interfaces); 00113 00114 if (h) { 00115 ast_free(h); 00116 h = NULL; 00117 res = 0; 00118 } 00119 00120 return res; 00121 }
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().
00062 { 00063 struct timing_holder *h1 = _h1; 00064 struct timing_holder *h2 = _h2; 00065 00066 if (h1->iface->priority > h2->iface->priority) { 00067 return 1; 00068 } else if (h1->iface->priority == h2->iface->priority) { 00069 return 0; 00070 } else { 00071 return -1; 00072 } 00073 }
static char* timing_test | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 217 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.
00218 { 00219 struct ast_timer *timer; 00220 int count = 0; 00221 struct timeval start, end; 00222 unsigned int test_rate = 50; 00223 00224 switch (cmd) { 00225 case CLI_INIT: 00226 e->command = "timing test"; 00227 e->usage = "Usage: timing test <rate>\n" 00228 " Test a timer with a specified rate, 50/sec by default.\n" 00229 ""; 00230 return NULL; 00231 case CLI_GENERATE: 00232 return NULL; 00233 } 00234 00235 if (a->argc != 2 && a->argc != 3) { 00236 return CLI_SHOWUSAGE; 00237 } 00238 00239 if (a->argc == 3) { 00240 unsigned int rate; 00241 if (sscanf(a->argv[2], "%30u", &rate) == 1) { 00242 test_rate = rate; 00243 } else { 00244 ast_cli(a->fd, "Invalid rate '%s', using default of %u\n", a->argv[2], test_rate); 00245 } 00246 } 00247 00248 ast_cli(a->fd, "Attempting to test a timer with %u ticks per second.\n", test_rate); 00249 00250 if (!(timer = ast_timer_open())) { 00251 ast_cli(a->fd, "Failed to open timing fd\n"); 00252 return CLI_FAILURE; 00253 } 00254 00255 ast_cli(a->fd, "Using the '%s' timing module for this test.\n", timer->holder->iface->name); 00256 00257 start = ast_tvnow(); 00258 00259 ast_timer_set_rate(timer, test_rate); 00260 00261 while (ast_tvdiff_ms((end = ast_tvnow()), start) < 1000) { 00262 int res; 00263 struct pollfd pfd = { 00264 .fd = ast_timer_fd(timer), 00265 .events = POLLIN | POLLPRI, 00266 }; 00267 00268 res = ast_poll(&pfd, 1, 100); 00269 00270 if (res == 1) { 00271 count++; 00272 ast_timer_ack(timer, 1); 00273 } else if (!res) { 00274 ast_cli(a->fd, "poll() timed out! This is bad.\n"); 00275 } else if (errno != EAGAIN && errno != EINTR) { 00276 ast_cli(a->fd, "poll() returned error: %s\n", strerror(errno)); 00277 } 00278 } 00279 00280 ast_timer_close(timer); 00281 00282 ast_cli(a->fd, "It has been %" PRIi64 " milliseconds, and we got %d timer ticks\n", 00283 ast_tvdiff_ms(end, start), count); 00284 00285 return CLI_SUCCESS; 00286 }
struct ast_cli_entry cli_timing[] [static] |
Initial value:
{ { .handler = timing_test , .summary = "Run a timing test" ,__VA_ARGS__ }, }
Definition at line 288 of file timing.c.
Referenced by ast_timing_init().
struct ast_heap* timing_interfaces [static] |
Definition at line 54 of file timing.c.
Referenced by _ast_register_timing_interface(), ast_timer_open(), ast_timing_init(), and ast_unregister_timing_interface().