Asterisk - The Open Source Telephony Project GIT-master-b023714
Loading...
Searching...
No Matches
Data Structures | Macros | Enumerations | Functions | Variables
res_timing_pthread.c File Reference

pthread timing interface More...

#include "asterisk.h"
#include <stdbool.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
#include "asterisk/module.h"
#include "asterisk/timing.h"
#include "asterisk/utils.h"
#include "asterisk/astobj2.h"
#include "asterisk/time.h"
#include "asterisk/lock.h"
Include dependency graph for res_timing_pthread.c:

Go to the source code of this file.

Data Structures

struct  pthread_timer
 

Macros

#define MAX_RATE   100
 
#define PTHREAD_TIMER_BUCKETS   563
 

Enumerations

enum  { PIPE_READ = 0 , PIPE_WRITE = 1 }
 
enum  pthread_timer_state { TIMER_STATE_IDLE , TIMER_STATE_TICKING }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static void ack_ticks (struct pthread_timer *timer, unsigned int num)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int check_timer (struct pthread_timer *timer)
 
static void * do_timing (void *arg)
 
static int init_timing_thread (void)
 
static int load_module (void)
 
static int pthread_timer_ack (void *data, unsigned int quantity)
 
static void pthread_timer_close (void *data)
 
static int pthread_timer_cmp (void *obj, void *arg, int flags)
 
static void pthread_timer_destructor (void *obj)
 
static int pthread_timer_disable_continuous (void *data)
 
static int pthread_timer_enable_continuous (void *data)
 
static int pthread_timer_fd (void *data)
 
static enum ast_timer_event pthread_timer_get_event (void *data)
 
static unsigned int pthread_timer_get_max_rate (void *data)
 
static int pthread_timer_hash (const void *obj, const int flags)
 
static void * pthread_timer_open (void)
 
static int pthread_timer_set_rate (void *data, unsigned int rate)
 
static int run_timer (void *obj, void *arg, int flags)
 
static void signal_pipe (struct pthread_timer *timer)
 
static int unload_module (void)
 
static void unsignal_pipe (struct pthread_timer *timer)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "pthread Timing Interface" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_TIMING, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ao2_containerpthread_timers
 
static struct ast_timing_interface pthread_timing
 
static void * timing_funcs_handle
 
struct { 
 
   ast_cond_t   cond 
 
   ast_mutex_t   lock 
 
   unsigned int   stop:1 
 
   pthread_t   thread 
 
timing_thread 
 Data for the timing thread.
 

Detailed Description

pthread timing interface

Author
Russell Bryant russe.nosp@m.ll@d.nosp@m.igium.nosp@m..com

Definition in file res_timing_pthread.c.

Macro Definition Documentation

◆ MAX_RATE

#define MAX_RATE   100

Definition at line 71 of file res_timing_pthread.c.

◆ PTHREAD_TIMER_BUCKETS

#define PTHREAD_TIMER_BUCKETS   563

Definition at line 74 of file res_timing_pthread.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
PIPE_READ 
PIPE_WRITE 

Definition at line 76 of file res_timing_pthread.c.

76 {
77 PIPE_READ = 0,
78 PIPE_WRITE = 1
79};
@ PIPE_WRITE
@ PIPE_READ

◆ pthread_timer_state

Enumerator
TIMER_STATE_IDLE 
TIMER_STATE_TICKING 

Definition at line 81 of file res_timing_pthread.c.

81 {
84};
@ TIMER_STATE_TICKING
@ TIMER_STATE_IDLE

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 476 of file res_timing_pthread.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 476 of file res_timing_pthread.c.

◆ ack_ticks()

static void ack_ticks ( struct pthread_timer timer,
unsigned int  num 
)
static

Definition at line 312 of file res_timing_pthread.c.

313{
314 int pending_ticks = timer->pending_ticks;
315
316 ast_assert(quantity);
317
318 if (quantity > pending_ticks) {
319 quantity = pending_ticks;
320 }
321
322 if (!quantity) {
323 return;
324 }
325
326 timer->pending_ticks -= quantity;
327
328 if ((0 == timer->pending_ticks) && !timer->continuous) {
330 }
331}
static struct ast_timer * timer
Definition chan_iax2.c:388
static void unsignal_pipe(struct pthread_timer *timer)
#define ast_assert(a)
Definition utils.h:776

References ast_assert, timer, and unsignal_pipe().

Referenced by pthread_timer_ack().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 476 of file res_timing_pthread.c.

◆ check_timer()

static int check_timer ( struct pthread_timer timer)
static
Return values
0no timer tick needed
non-zerowrite to the timing pipe needed

Definition at line 286 of file res_timing_pthread.c.

287{
288 struct timeval now;
289
290 if (timer->state == TIMER_STATE_IDLE) {
291 return 0;
292 }
293
294 now = ast_tvnow();
295
296 if (timer->tick_count < (ast_tvdiff_ms(now, timer->start) / timer->interval)) {
297 timer->tick_count++;
298 if (!timer->tick_count) {
299 /* Handle overflow. */
300 timer->start = now;
301 }
302 return 1;
303 }
304
305 return 0;
306}
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

References ast_tvdiff_ms(), ast_tvnow(), timer, and TIMER_STATE_IDLE.

Referenced by run_timer().

◆ do_timing()

static void * do_timing ( void *  arg)
static

Definition at line 395 of file res_timing_pthread.c.

396{
397 struct timeval next_wakeup = ast_tvnow();
398
399 while (!timing_thread.stop) {
400 struct timespec ts = { 0, };
401
403
404 next_wakeup = ast_tvadd(next_wakeup, ast_tv(0, 5000));
405
406 ts.tv_sec = next_wakeup.tv_sec;
407 ts.tv_nsec = next_wakeup.tv_usec * 1000;
408
410 if (!timing_thread.stop) {
413 } else {
415 }
416 }
418 }
419
420 return NULL;
421}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition astobj2.h:1693
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
@ OBJ_NODATA
Definition astobj2.h:1044
#define ast_cond_wait(cond, mutex)
Definition lock.h:212
#define ast_cond_timedwait(cond, mutex, time)
Definition lock.h:213
#define ast_mutex_unlock(a)
Definition lock.h:197
#define ast_mutex_lock(a)
Definition lock.h:196
static int run_timer(void *obj, void *arg, int flags)
static struct @521 timing_thread
Data for the timing thread.
static struct ao2_container * pthread_timers
#define NULL
Definition resample.c:96
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition extconf.c:2280
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition time.h:235

References ao2_callback, ao2_container_count(), ast_cond_timedwait, ast_cond_wait, ast_mutex_lock, ast_mutex_unlock, ast_tv(), ast_tvadd(), ast_tvnow(), NULL, OBJ_NODATA, pthread_timers, run_timer(), and timing_thread.

Referenced by init_timing_thread().

◆ init_timing_thread()

static int init_timing_thread ( void  )
static

Definition at line 423 of file res_timing_pthread.c.

424{
427
429 ast_log(LOG_ERROR, "Unable to start timing thread.\n");
430 return -1;
431 }
432
433 return 0;
434}
#define ast_log
Definition astobj2.c:42
#define LOG_ERROR
#define ast_cond_init(cond, attr)
Definition lock.h:208
#define ast_mutex_init(pmutex)
Definition lock.h:193
static void * do_timing(void *arg)
#define ast_pthread_create_background(a, b, c, d)
Definition utils.h:629

References ast_cond_init, ast_log, ast_mutex_init, ast_pthread_create_background, do_timing(), LOG_ERROR, NULL, and timing_thread.

Referenced by load_module().

◆ load_module()

static int load_module ( void  )
static

Definition at line 436 of file res_timing_pthread.c.

437{
440 if (!pthread_timers) {
442 }
443
444 if (init_timing_thread()) {
448 }
449
452}
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition astobj2.h:363
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition astobj2.h:1303
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition module.h:78
static int pthread_timer_hash(const void *obj, const int flags)
static int init_timing_thread(void)
#define PTHREAD_TIMER_BUCKETS
static void * timing_funcs_handle
static struct ast_timing_interface pthread_timing
static int pthread_timer_cmp(void *obj, void *arg, int flags)
#define ast_register_timing_interface(i)
Register a set of timing functions.
Definition timing.h:95

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_ref, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_timing_interface, init_timing_thread(), NULL, PTHREAD_TIMER_BUCKETS, pthread_timer_cmp(), pthread_timer_hash(), pthread_timers, pthread_timing, and timing_funcs_handle.

◆ pthread_timer_ack()

static int pthread_timer_ack ( void *  data,
unsigned int  quantity 
)
static

Definition at line 180 of file res_timing_pthread.c.

181{
182 struct pthread_timer *timer = data;
183
184 ast_assert(quantity > 0);
185
189
190 return 0;
191}
#define ao2_unlock(a)
Definition astobj2.h:729
#define ao2_lock(a)
Definition astobj2.h:717
static void ack_ticks(struct pthread_timer *timer, unsigned int num)
struct timeval start

References ack_ticks(), ao2_lock, ao2_unlock, ast_assert, pthread_timer::start, and timer.

◆ pthread_timer_close()

static void pthread_timer_close ( void *  data)
static

Definition at line 143 of file res_timing_pthread.c.

144{
145 struct pthread_timer *timer = data;
146
148 ao2_ref(timer, -1);
149}
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition astobj2.h:1578

References ao2_ref, ao2_unlink, pthread_timers, and timer.

◆ pthread_timer_cmp()

static int pthread_timer_cmp ( void *  obj,
void *  arg,
int  flags 
)
static
Note
only PIPE_READ is guaranteed valid

Definition at line 275 of file res_timing_pthread.c.

276{
277 struct pthread_timer *timer1 = obj, *timer2 = arg;
278
279 return (timer1->pipe[PIPE_READ] == timer2->pipe[PIPE_READ]) ? CMP_MATCH | CMP_STOP : 0;
280}
@ CMP_MATCH
Definition astobj2.h:1027
@ CMP_STOP
Definition astobj2.h:1028

References CMP_MATCH, CMP_STOP, PIPE_READ, and pthread_timer::start.

Referenced by load_module().

◆ pthread_timer_destructor()

static void pthread_timer_destructor ( void *  obj)
static

Definition at line 247 of file res_timing_pthread.c.

248{
249 struct pthread_timer *timer = obj;
250
251 if (timer->pipe[PIPE_READ] > -1) {
252 close(timer->pipe[PIPE_READ]);
253 timer->pipe[PIPE_READ] = -1;
254 }
255
256 if (timer->pipe[PIPE_WRITE] > -1) {
257 close(timer->pipe[PIPE_WRITE]);
258 timer->pipe[PIPE_WRITE] = -1;
259 }
260}

References PIPE_READ, PIPE_WRITE, and timer.

Referenced by pthread_timer_open().

◆ pthread_timer_disable_continuous()

static int pthread_timer_disable_continuous ( void *  data)
static

Definition at line 207 of file res_timing_pthread.c.

208{
209 struct pthread_timer *timer = data;
210
212 if (timer->continuous) {
213 timer->continuous = false;
215 }
217
218 return 0;
219}

References ao2_lock, ao2_unlock, timer, and unsignal_pipe().

◆ pthread_timer_enable_continuous()

static int pthread_timer_enable_continuous ( void *  data)
static

Definition at line 193 of file res_timing_pthread.c.

194{
195 struct pthread_timer *timer = data;
196
198 if (!timer->continuous) {
199 timer->continuous = true;
201 }
203
204 return 0;
205}
static void signal_pipe(struct pthread_timer *timer)

References ao2_lock, ao2_unlock, signal_pipe(), and timer.

◆ pthread_timer_fd()

static int pthread_timer_fd ( void *  data)
static

Definition at line 240 of file res_timing_pthread.c.

241{
242 struct pthread_timer *timer = data;
243
244 return timer->pipe[PIPE_READ];
245}

References PIPE_READ, and timer.

◆ pthread_timer_get_event()

static enum ast_timer_event pthread_timer_get_event ( void *  data)
static

Definition at line 221 of file res_timing_pthread.c.

222{
223 struct pthread_timer *timer = data;
225
227 if (timer->continuous) {
229 }
231
232 return res;
233}
ast_timer_event
Definition timing.h:57
@ AST_TIMING_EVENT_CONTINUOUS
Definition timing.h:59
@ AST_TIMING_EVENT_EXPIRED
Definition timing.h:58

References ao2_lock, ao2_unlock, AST_TIMING_EVENT_CONTINUOUS, AST_TIMING_EVENT_EXPIRED, pthread_timer::start, and timer.

◆ pthread_timer_get_max_rate()

static unsigned int pthread_timer_get_max_rate ( void *  data)
static

Definition at line 235 of file res_timing_pthread.c.

236{
237 return MAX_RATE;
238}
#define MAX_RATE

References MAX_RATE.

◆ pthread_timer_hash()

static int pthread_timer_hash ( const void *  obj,
const int  flags 
)
static
Note
only PIPE_READ is guaranteed valid

Definition at line 265 of file res_timing_pthread.c.

266{
267 const struct pthread_timer *timer = obj;
268
269 return timer->pipe[PIPE_READ];
270}

References PIPE_READ, and timer.

Referenced by load_module().

◆ pthread_timer_open()

static void * pthread_timer_open ( void  )
static

Definition at line 114 of file res_timing_pthread.c.

115{
116 struct pthread_timer *timer;
117
118 if (!(timer = ao2_alloc(sizeof(*timer), pthread_timer_destructor))) {
119 errno = ENOMEM;
120 return NULL;
121 }
122
123 timer->pipe[PIPE_READ] = timer->pipe[PIPE_WRITE] = -1;
124 timer->state = TIMER_STATE_IDLE;
125
126 if (ast_pipe_nonblock(timer->pipe)) {
127 ao2_ref(timer, -1);
128 return NULL;
129 }
130
136 }
139
140 return timer;
141}
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
Definition astobj2.h:1554
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
Definition astobj2.h:1063
#define ao2_alloc(data_size, destructor_fn)
Definition astobj2.h:409
#define ast_cond_signal(cond)
Definition lock.h:210
int errno
static void pthread_timer_destructor(void *obj)
#define ast_pipe_nonblock(filedes)
Create a non-blocking pipe.
Definition utils.h:1127

References ao2_alloc, ao2_container_count(), ao2_link_flags, ao2_lock, ao2_ref, ao2_unlock, ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, ast_pipe_nonblock, errno, NULL, OBJ_NOLOCK, PIPE_READ, PIPE_WRITE, pthread_timer_destructor(), pthread_timers, pthread_timer::start, timer, TIMER_STATE_IDLE, and timing_thread.

◆ pthread_timer_set_rate()

static int pthread_timer_set_rate ( void *  data,
unsigned int  rate 
)
static

Definition at line 151 of file res_timing_pthread.c.

152{
153 struct pthread_timer *timer = data;
154
155 if (rate > MAX_RATE) {
156 ast_log(LOG_ERROR, "res_timing_pthread only supports timers at a "
157 "max rate of %d / sec\n", MAX_RATE);
158 errno = EINVAL;
159 return -1;
160 }
161
163
164 if ((timer->rate = rate)) {
165 timer->interval = roundf(1000.0 / ((float) rate));
166 timer->start = ast_tvnow();
167 timer->state = TIMER_STATE_TICKING;
168 } else {
169 timer->interval = 0;
170 timer->start = ast_tv(0, 0);
171 timer->state = TIMER_STATE_IDLE;
172 }
173 timer->tick_count = 0;
174
176
177 return 0;
178}
float roundf(float x)
unsigned int rate

References ao2_lock, ao2_unlock, ast_log, ast_tv(), ast_tvnow(), errno, LOG_ERROR, MAX_RATE, pthread_timer::rate, roundf(), pthread_timer::start, timer, TIMER_STATE_IDLE, and TIMER_STATE_TICKING.

◆ run_timer()

static int run_timer ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 377 of file res_timing_pthread.c.

378{
379 struct pthread_timer *timer = obj;
380
381 if (timer->state == TIMER_STATE_IDLE) {
382 return 0;
383 }
384
386 if (check_timer(timer)) {
387 timer->pending_ticks++;
389 }
391
392 return 0;
393}
static int check_timer(struct pthread_timer *timer)

References ao2_lock, ao2_unlock, check_timer(), signal_pipe(), timer, and TIMER_STATE_IDLE.

Referenced by do_timing().

◆ signal_pipe()

static void signal_pipe ( struct pthread_timer timer)
static

Definition at line 337 of file res_timing_pthread.c.

338{
339 ssize_t res;
340 unsigned char x = 42;
341
342 if (timer->pipe_signaled) {
343 return;
344 }
345
346 res = write(timer->pipe[PIPE_WRITE], &x, 1);
347 if (-1 == res) {
348 ast_log(LOG_ERROR, "Error writing to timing pipe: %s\n",
349 strerror(errno));
350 } else {
351 timer->pipe_signaled = true;
352 }
353}

References ast_log, errno, LOG_ERROR, PIPE_WRITE, and timer.

Referenced by pthread_timer_enable_continuous(), and run_timer().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 454 of file res_timing_pthread.c.

455{
456 int res;
457
459 timing_thread.stop = 1;
462 pthread_join(timing_thread.thread, NULL);
463
467 }
468
469 return res;
470}
int ast_unregister_timing_interface(void *handle)
Unregister a previously registered timing interface.
Definition timing.c:104

References ao2_ref, ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, ast_unregister_timing_interface(), NULL, pthread_timers, timing_funcs_handle, and timing_thread.

◆ unsignal_pipe()

static void unsignal_pipe ( struct pthread_timer timer)
static

Definition at line 359 of file res_timing_pthread.c.

360{
361 ssize_t res;
362 unsigned long buffer;
363
364 if (!timer->pipe_signaled) {
365 return;
366 }
367
368 res = read(timer->pipe[PIPE_READ], &buffer, sizeof(buffer));
369 if (-1 == res) {
370 ast_log(LOG_ERROR, "Error reading from pipe: %s\n",
371 strerror(errno));
372 } else {
373 timer->pipe_signaled = false;
374 }
375}

References ast_log, errno, LOG_ERROR, PIPE_READ, and timer.

Referenced by ack_ticks(), and pthread_timer_disable_continuous().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "pthread Timing Interface" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_TIMING, }
static

Definition at line 476 of file res_timing_pthread.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 476 of file res_timing_pthread.c.

◆ cond

ast_cond_t cond

Definition at line 110 of file res_timing_pthread.c.

◆ lock

Definition at line 109 of file res_timing_pthread.c.

◆ pthread_timers

struct ao2_container* pthread_timers
static

◆ pthread_timing

struct ast_timing_interface pthread_timing
static

Definition at line 56 of file res_timing_pthread.c.

56 {
57 .name = "pthread",
58 .priority = 0, /* use this as a last resort */
59 .timer_open = pthread_timer_open,
60 .timer_close = pthread_timer_close,
61 .timer_set_rate = pthread_timer_set_rate,
62 .timer_ack = pthread_timer_ack,
63 .timer_enable_continuous = pthread_timer_enable_continuous,
64 .timer_disable_continuous = pthread_timer_disable_continuous,
65 .timer_get_event = pthread_timer_get_event,
66 .timer_get_max_rate = pthread_timer_get_max_rate,
67 .timer_fd = pthread_timer_fd,
68};
static int pthread_timer_disable_continuous(void *data)
static int pthread_timer_enable_continuous(void *data)
static unsigned int pthread_timer_get_max_rate(void *data)
static int pthread_timer_fd(void *data)
static void * pthread_timer_open(void)
static void pthread_timer_close(void *data)
static int pthread_timer_set_rate(void *data, unsigned int rate)
static int pthread_timer_ack(void *data, unsigned int quantity)
static enum ast_timer_event pthread_timer_get_event(void *data)

Referenced by load_module().

◆ stop

unsigned int stop

Definition at line 111 of file res_timing_pthread.c.

◆ thread

pthread_t thread

Definition at line 108 of file res_timing_pthread.c.

◆ timing_funcs_handle

void* timing_funcs_handle
static

Definition at line 44 of file res_timing_pthread.c.

Referenced by load_module(), and unload_module().

◆ [struct]

struct { ... } timing_thread

Data for the timing thread.

Referenced by do_timing(), init_timing_thread(), pthread_timer_open(), and unload_module().