Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
sched.c File Reference

Scheduler Routines (from cheops-NG) More...

#include "asterisk.h"
#include <sys/time.h>
#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/heap.h"
#include "asterisk/threadstorage.h"
Include dependency graph for sched.c:

Go to the source code of this file.

Data Structures

struct  ast_sched_context
 
struct  sched
 
struct  sched_id
 Scheduler ID holder. More...
 
struct  sched_thread
 

Macros

#define DEBUG(a)
 
#define ID_QUEUE_INCREMENT   16
 
#define SCHED_MAX_CACHE   128
 Max num of schedule structs. More...
 

Functions

static void __init_last_del_id (void)
 
static int add_ids (struct ast_sched_context *con)
 Add new scheduler IDs to the queue. More...
 
int ast_sched_add (struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data)
 Adds a scheduled event. More...
 
int ast_sched_add_variable (struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable)
 Schedule callback(data) to happen when ms into the future. More...
 
void ast_sched_clean_by_callback (struct ast_sched_context *con, ast_sched_cb match, ast_sched_cb cleanup_cb)
 Clean all scheduled events with matching callback. More...
 
struct ast_sched_contextast_sched_context_create (void)
 Create a scheduler context. More...
 
void ast_sched_context_destroy (struct ast_sched_context *con)
 destroys a schedule context More...
 
int ast_sched_del (struct ast_sched_context *con, int id)
 Delete the schedule entry with number "id". It's nearly impossible that there would be two or more in the list with that id. More...
 
void ast_sched_dump (struct ast_sched_context *con)
 Dump the contents of the scheduler to LOG_DEBUG. More...
 
const void * ast_sched_find_data (struct ast_sched_context *con, int id)
 Find a sched structure and return the data field associated with it. More...
 
int ast_sched_replace (int old_id, struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data)
 replace a scheduler entry More...
 
int ast_sched_replace_variable (int old_id, struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable)
 replace a scheduler entry More...
 
void ast_sched_report (struct ast_sched_context *con, struct ast_str **buf, struct ast_cb_names *cbnames)
 Show statics on what it is in the schedule queue. More...
 
int ast_sched_runq (struct ast_sched_context *con)
 Launch all events which need to be run at this time. More...
 
int ast_sched_start_thread (struct ast_sched_context *con)
 Start a thread for processing scheduler entries. More...
 
int ast_sched_wait (struct ast_sched_context *con)
 Return the number of milliseconds until the next scheduled event. More...
 
long ast_sched_when (struct ast_sched_context *con, int id)
 Returns the number of seconds before an event takes place. More...
 
static struct schedsched_alloc (struct ast_sched_context *con)
 
static struct schedsched_find (struct ast_sched_context *con, int id)
 
static void sched_free (struct sched *task)
 
static void sched_release (struct ast_sched_context *con, struct sched *tmp)
 
static void * sched_run (void *data)
 
static void sched_settime (struct timeval *t, int when)
 given the last event *tv and the offset in milliseconds 'when', computes the next value, More...
 
static void sched_thread_destroy (struct ast_sched_context *con)
 
static int sched_time_cmp (void *va, void *vb)
 
static void schedule (struct ast_sched_context *con, struct sched *s)
 Take a sched structure and put it in the queue, such that the soonest event is first in the list. More...
 
static int set_sched_id (struct ast_sched_context *con, struct sched *new_sched)
 

Variables

static struct ast_threadstorage last_del_id = { .once = PTHREAD_ONCE_INIT , .key_init = __init_last_del_id , .custom_init = NULL , }
 

Detailed Description

Scheduler Routines (from cheops-NG)

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file sched.c.

Macro Definition Documentation

◆ DEBUG

#define DEBUG (   a)

◆ ID_QUEUE_INCREMENT

#define ID_QUEUE_INCREMENT   16

Definition at line 303 of file sched.c.

Referenced by add_ids().

◆ SCHED_MAX_CACHE

#define SCHED_MAX_CACHE   128

Max num of schedule structs.

Note
The max number of schedule structs to keep around for use. Undefine to disable schedule structure caching. (Only disable this on very low memory machines)

Definition at line 56 of file sched.c.

Referenced by sched_release().

Function Documentation

◆ __init_last_del_id()

static void __init_last_del_id ( void  )
static

Definition at line 58 of file sched.c.

70 {

◆ add_ids()

static int add_ids ( struct ast_sched_context con)
static

Add new scheduler IDs to the queue.

Return values
Thenumber of IDs added to the queue

Definition at line 310 of file sched.c.

References ast_calloc, AST_LIST_INSERT_TAIL, sched_id::id, ast_sched_context::id_queue, ID_QUEUE_INCREMENT, ast_sched_context::id_queue_size, and sched_id::list.

Referenced by set_sched_id().

311 {
312  int new_size;
313  int original_size;
314  int i;
315 
316  original_size = con->id_queue_size;
317  /* So we don't go overboard with the mallocs here, we'll just up
318  * the size of the list by a fixed amount each time instead of
319  * multiplying the size by any particular factor
320  */
321  new_size = original_size + ID_QUEUE_INCREMENT;
322  if (new_size < 0) {
323  /* Overflow. Cap it at INT_MAX. */
324  new_size = INT_MAX;
325  }
326  for (i = original_size; i < new_size; ++i) {
327  struct sched_id *new_id;
328 
329  new_id = ast_calloc(1, sizeof(*new_id));
330  if (!new_id) {
331  break;
332  }
333 
334  /*
335  * According to the API doxygen a sched ID of 0 is valid.
336  * Unfortunately, 0 was never returned historically and
337  * several users incorrectly coded usage of the returned
338  * sched ID assuming that 0 was invalid.
339  */
340  new_id->id = ++con->id_queue_size;
341 
342  AST_LIST_INSERT_TAIL(&con->id_queue, new_id, list);
343  }
344 
345  return con->id_queue_size - original_size;
346 }
Scheduler ID holder.
Definition: sched.c:70
int id_queue_size
Definition: sched.c:129
struct sched_id::@414 list
struct ast_sched_context::@417 id_queue
#define ID_QUEUE_INCREMENT
Definition: sched.c:303
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
int id
Definition: sched.c:72

◆ ast_sched_add()

int ast_sched_add ( struct ast_sched_context con,
int  when,
ast_sched_cb  callback,
const void *  data 
)

Adds a scheduled event.

Schedule an event to take place at some point in the future. callback will be called with data as the argument, when milliseconds into the future (approximately)

If callback returns 0, no further events will be re-scheduled

Parameters
conScheduler context to add
whenhow many milliseconds to wait for event to occur
callbackfunction to call when the amount of time expires
datadata to pass to the callback
Returns
Returns a schedule item ID on success, -1 on failure

Definition at line 565 of file sched.c.

References ast_sched_add_variable().

Referenced by __sip_scheddestroy(), __start_mwi_subscription(), __start_register_timeout(), __start_reregister_timeout(), __start_session_timer(), __start_t38_abort_timer(), __update_provisional_keepalive_full(), ast_readaudio_callback(), ast_readvideo_callback(), ast_rtp_interpret(), ast_sched_replace(), ast_sip_schedule_task(), AST_TEST_DEFINE(), build_peer(), cc_generic_agent_start_offer_timer(), cc_generic_monitor_request_cc(), cleanup_registration(), create_esc_entry(), dialog_unlink_all(), dns_query_recurring_resolution_callback(), do_register(), dundi_discover(), dundi_query(), dundi_send(), handle_cli_sched_bench(), handle_command_response(), handle_keepalive_message(), handle_response_invite(), iax2_hangup(), iax2_key_rotate(), iax2_sched_add(), mbl_call(), memory_cache_stale_update_full(), memory_cache_stale_update_object(), mgcp_postrequest(), network_change_stasis_cb(), parse_register_contact(), populate_addr(), precache_trans(), qualify_peer(), rtcp_debug_test_addr(), rtp_instance_parse_transport_wide_cc(), rtp_raw_write(), rtp_red_init(), run_task(), sched_check_pendings(), schedule_cache_expiration(), schedule_notification(), shutdown_mwi_subscription(), sip_cancel_destroy(), sip_cc_agent_start_offer_timer(), sip_cc_monitor_request_cc(), sip_hangup(), sip_scheddestroy_full(), skinny_sched_add(), skinny_session(), start_mwi_subscription(), start_register_timeout(), start_reregister_timeout(), start_session_timer(), start_t38_abort_timer(), stop_provisional_keepalive(), stop_register_timeout(), stop_reinvite_retry(), stop_reinviteid(), stop_retrans_pkt(), stop_session_timer(), stop_t38_abort_timer(), and update_provisional_keepalive().

566 {
567  return ast_sched_add_variable(con, when, callback, data, 0);
568 }
int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable)
Schedule callback(data) to happen when ms into the future.
Definition: sched.c:524

◆ ast_sched_add_variable()

int ast_sched_add_variable ( struct ast_sched_context con,
int  when,
ast_sched_cb  callback,
const void *  data,
int  variable 
)

Schedule callback(data) to happen when ms into the future.

Adds a scheduled event with rescheduling support.

Definition at line 524 of file sched.c.

References ast_cond_signal, ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_sched_dump(), ast_tv(), sched::callback, sched_thread::cond, sched::data, DEBUG, sched::deleted, ast_sched_context::eventcnt, sched_id::id, ast_sched_context::lock, sched::resched, sched_alloc(), sched::sched_id, sched_settime(), ast_sched_context::sched_thread, schedule(), tmp(), sched::variable, and sched::when.

Referenced by __sip_reliable_xmit(), _misdn_tasks_add_variable(), apply_negotiated_sdp_stream(), ast_sched_add(), ast_sched_replace_variable(), dnsmgr_start_refresh(), do_reload(), global_loaded(), monitored_transport_state_callback(), start_batch_mode(), and stun_start_monitor().

525 {
526  struct sched *tmp;
527  int res = -1;
528 
529  DEBUG(ast_debug(1, "ast_sched_add()\n"));
530 
531  ast_mutex_lock(&con->lock);
532  if ((tmp = sched_alloc(con))) {
533  con->eventcnt++;
534  tmp->callback = callback;
535  tmp->data = data;
536  tmp->resched = when;
537  tmp->variable = variable;
538  tmp->when = ast_tv(0, 0);
539  tmp->deleted = 0;
540 
541  sched_settime(&tmp->when, when);
542  schedule(con, tmp);
543  res = tmp->sched_id->id;
544  }
545 #ifdef DUMP_SCHEDULER
546  /* Dump contents of the context while we have the lock so nothing gets screwed up by accident. */
547  ast_sched_dump(con);
548 #endif
549  if (con->sched_thread) {
551  }
552  ast_mutex_unlock(&con->lock);
553 
554  return res;
555 }
static struct sched * sched_alloc(struct ast_sched_context *con)
Definition: sched.c:378
unsigned int deleted
Definition: sched.c:100
struct sched_id * sched_id
Definition: sched.c:79
struct sched_thread * sched_thread
Definition: sched.c:116
static void sched_settime(struct timeval *t, int when)
given the last event *tv and the offset in milliseconds &#39;when&#39;, computes the next value...
Definition: sched.c:488
static int tmp()
Definition: bt_open.c:389
Definition: sched.c:76
#define ast_mutex_lock(a)
Definition: lock.h:187
int resched
Definition: sched.c:89
#define ast_cond_signal(cond)
Definition: lock.h:201
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static void schedule(struct ast_sched_context *con, struct sched *s)
Take a sched structure and put it in the queue, such that the soonest event is first in the list...
Definition: sched.c:458
struct timeval when
Definition: sched.c:80
void ast_sched_dump(struct ast_sched_context *con)
Dump the contents of the scheduler to LOG_DEBUG.
Definition: sched.c:712
const void * data
Definition: sched.c:91
ast_cond_t cond
Definition: sched.c:105
unsigned int eventcnt
Definition: sched.c:111
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:226
ast_mutex_t lock
Definition: sched.c:110
#define DEBUG(a)
Definition: sched.c:36
int variable
Definition: sched.c:90
ast_sched_cb callback
Definition: sched.c:92
int id
Definition: sched.c:72
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ast_sched_clean_by_callback()

void ast_sched_clean_by_callback ( struct ast_sched_context con,
ast_sched_cb  match,
ast_sched_cb  cleanup_cb 
)

Clean all scheduled events with matching callback.

Parameters
conScheduler Context
matchCallback to match
cleanup_cbCallback to run
Note
The return of cleanup_cb is ignored. No events are rescheduled.

Definition at line 407 of file sched.c.

References ast_heap_peek(), ast_heap_remove(), ast_mutex_lock, ast_mutex_unlock, sched::callback, cleanup_cb(), sched::data, ast_sched_context::lock, ast_sched_context::sched_heap, and sched_release().

Referenced by __unload_module(), ast_sip_destroy_transport_management(), and global_loaded().

408 {
409  int i = 1;
410  struct sched *current;
411 
412  ast_mutex_lock(&con->lock);
413  while ((current = ast_heap_peek(con->sched_heap, i))) {
414  if (current->callback != match) {
415  i++;
416  continue;
417  }
418 
419  ast_heap_remove(con->sched_heap, current);
420 
421  cleanup_cb(current->data);
422  sched_release(con, current);
423  }
424  ast_mutex_unlock(&con->lock);
425 }
struct ast_heap * sched_heap
Definition: sched.c:115
Definition: sched.c:76
#define ast_mutex_lock(a)
Definition: lock.h:187
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2315
static int cleanup_cb(void *obj, void *arg, int flags)
Definition: res_stasis.c:309
static void sched_release(struct ast_sched_context *con, struct sched *tmp)
Definition: sched.c:358
const void * data
Definition: sched.c:91
void * ast_heap_remove(struct ast_heap *h, void *elm)
Remove a specific element from a heap.
Definition: heap.c:251
void * ast_heap_peek(struct ast_heap *h, unsigned int index)
Peek at an element on a heap.
Definition: heap.c:267
ast_mutex_t lock
Definition: sched.c:110
ast_sched_cb callback
Definition: sched.c:92
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ast_sched_context_create()

struct ast_sched_context* ast_sched_context_create ( void  )

Create a scheduler context.

Returns
Returns a malloc'd sched_context structure, NULL on failure

Definition at line 236 of file sched.c.

References ast_calloc, ast_heap_create, AST_LIST_HEAD_INIT_NOLOCK, ast_mutex_init, ast_sched_context_destroy(), ast_sched_context::eventcnt, ast_sched_context::id_queue, ast_sched_context::lock, NULL, ast_sched_context::sched_heap, sched_time_cmp(), and tmp().

Referenced by __ast_channel_alloc_ap(), ast_sip_initialize_distributor(), ast_sip_initialize_scheduler(), ast_sip_initialize_transport_management(), AST_TEST_DEFINE(), dns_core_init(), handle_cli_sched_bench(), load_module(), mbl_load_device(), misdn_tasks_init(), and stun_start_monitor().

237 {
238  struct ast_sched_context *tmp;
239 
240  if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
241  return NULL;
242  }
243 
244  ast_mutex_init(&tmp->lock);
245  tmp->eventcnt = 1;
246 
248 
249  if (!(tmp->sched_heap = ast_heap_create(8, sched_time_cmp,
250  offsetof(struct sched, __heap_index)))) {
252  return NULL;
253  }
254 
255  return tmp;
256 }
static int sched_time_cmp(void *va, void *vb)
Definition: sched.c:223
struct ast_heap * sched_heap
Definition: sched.c:115
static int tmp()
Definition: bt_open.c:389
Definition: sched.c:76
void ast_sched_context_destroy(struct ast_sched_context *con)
destroys a schedule context
Definition: sched.c:269
#define NULL
Definition: resample.c:96
struct ast_sched_context::@417 id_queue
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define ast_heap_create(init_height, cmp_fn, index_offset)
Definition: heap.h:102
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680
unsigned int eventcnt
Definition: sched.c:111
ast_mutex_t lock
Definition: sched.c:110
#define ast_mutex_init(pmutex)
Definition: lock.h:184

◆ ast_sched_context_destroy()

void ast_sched_context_destroy ( struct ast_sched_context c)

destroys a schedule context

Parameters
cContext to free

Definition at line 269 of file sched.c.

References ast_free, ast_heap_destroy(), ast_heap_pop(), AST_LIST_REMOVE_HEAD, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_sched_context::id_queue, sched_id::list, ast_sched_context::lock, NULL, sched_free(), ast_sched_context::sched_heap, ast_sched_context::sched_thread, sched_thread_destroy(), and ast_sched_context::schedc.

Referenced by __unload_module(), ast_channel_destructor(), ast_hangup(), ast_sched_context_create(), ast_sched_context_destroy_wrapper(), ast_sip_destroy_distributor(), ast_sip_destroy_scheduler(), ast_sip_destroy_transport_management(), ast_sip_initialize_scheduler(), ast_sip_initialize_transport_management(), AST_TEST_DEFINE(), cdr_engine_shutdown(), dns_shutdown(), handle_cli_sched_bench(), load_module(), mbl_load_device(), misdn_tasks_destroy(), stun_start_monitor(), stun_stop_monitor(), and unload_module().

270 {
271  struct sched *s;
272  struct sched_id *sid;
273 
275  con->sched_thread = NULL;
276 
277  ast_mutex_lock(&con->lock);
278 
279 #ifdef SCHED_MAX_CACHE
280  while ((s = AST_LIST_REMOVE_HEAD(&con->schedc, list))) {
281  sched_free(s);
282  }
283 #endif
284 
285  if (con->sched_heap) {
286  while ((s = ast_heap_pop(con->sched_heap))) {
287  sched_free(s);
288  }
290  con->sched_heap = NULL;
291  }
292 
293  while ((sid = AST_LIST_REMOVE_HEAD(&con->id_queue, list))) {
294  ast_free(sid);
295  }
296 
297  ast_mutex_unlock(&con->lock);
298  ast_mutex_destroy(&con->lock);
299 
300  ast_free(con);
301 }
struct ast_heap * sched_heap
Definition: sched.c:115
struct sched_thread * sched_thread
Definition: sched.c:116
Definition: sched.c:76
struct ast_heap * ast_heap_destroy(struct ast_heap *h)
Destroy a max heap.
Definition: heap.c:146
Scheduler ID holder.
Definition: sched.c:70
#define ast_mutex_lock(a)
Definition: lock.h:187
static void sched_thread_destroy(struct ast_sched_context *con)
Definition: sched.c:173
#define NULL
Definition: resample.c:96
void * ast_heap_pop(struct ast_heap *h)
Pop the max element off of the heap.
Definition: heap.c:262
struct sched_id::@414 list
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct ast_sched_context::@417 id_queue
struct ast_sched_context::@416 schedc
static void sched_free(struct sched *task)
Definition: sched.c:258
#define ast_free(a)
Definition: astmm.h:182
ast_mutex_t lock
Definition: sched.c:110
#define ast_mutex_destroy(a)
Definition: lock.h:186
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ast_sched_del()

int ast_sched_del ( struct ast_sched_context con,
int  id 
)

Delete the schedule entry with number "id". It's nearly impossible that there would be two or more in the list with that id.

Deletes a scheduled event.

Definition at line 610 of file sched.c.

References ast_cond_signal, ast_cond_wait, ast_debug, ast_heap_remove(), ast_log, ast_log_backtrace(), ast_mutex_lock, ast_mutex_unlock, ast_sched_dump(), ast_threadstorage_get(), sched::callback, sched::cond, sched_thread::cond, ast_sched_context::currently_executing, DEBUG, sched::deleted, ast_sched_context::executing_thread_id, sched_id::id, last_del_id, ast_sched_context::lock, LOG_ERROR, LOG_WARNING, NULL, sched_find(), ast_sched_context::sched_heap, sched::sched_id, sched_release(), and ast_sched_context::sched_thread.

Referenced by ast_rtp_prop_set(), ast_rtp_stop(), ast_sip_sched_task_cancel(), AST_TEST_DEFINE(), cc_generic_agent_stop_offer_timer(), cc_generic_monitor_cancel_available_timer(), destroy_event(), handle_cli_sched_bench(), handle_keepalive_message(), skinny_register(), skinny_sched_del(), and skinny_session_cleanup().

611 {
612  struct sched *s = NULL;
613  int *last_id = ast_threadstorage_get(&last_del_id, sizeof(int));
614 
615  DEBUG(ast_debug(1, "ast_sched_del(%d)\n", id));
616 
617  if (id < 0) {
618  return 0;
619  }
620 
621  ast_mutex_lock(&con->lock);
622 
623  s = sched_find(con, id);
624  if (s) {
625  if (!ast_heap_remove(con->sched_heap, s)) {
626  ast_log(LOG_WARNING,"sched entry %d not in the sched heap?\n", s->sched_id->id);
627  }
628  sched_release(con, s);
629  } else if (con->currently_executing && (id == con->currently_executing->sched_id->id)) {
630  if (con->executing_thread_id == pthread_self()) {
631  /* The scheduled callback is trying to delete itself.
632  * Not good as that is a deadlock. */
634  "BUG! Trying to delete sched %d from within the callback %p. "
635  "Ignoring so we don't deadlock\n",
636  id, con->currently_executing->callback);
638  /* We'll return -1 below because s is NULL.
639  * The caller will rightly assume that the unscheduling failed. */
640  } else {
641  s = con->currently_executing;
642  s->deleted = 1;
643  /* Wait for executing task to complete so that the caller of
644  * ast_sched_del() does not free memory out from under the task. */
645  while (con->currently_executing && (id == con->currently_executing->sched_id->id)) {
646  ast_cond_wait(&s->cond, &con->lock);
647  }
648  /* Do not sched_release() here because ast_sched_runq() will do it */
649  }
650  }
651 
652 #ifdef DUMP_SCHEDULER
653  /* Dump contents of the context while we have the lock so nothing gets screwed up by accident. */
654  ast_sched_dump(con);
655 #endif
656  if (con->sched_thread) {
658  }
659  ast_mutex_unlock(&con->lock);
660 
661  if (!s && *last_id != id) {
662  ast_debug(1, "Attempted to delete nonexistent schedule entry %d!\n", id);
663  /* Removing nonexistent schedule entry shouldn't trigger assert (it was enabled in DEV_MODE);
664  * because in many places entries is deleted without having valid id. */
665  *last_id = id;
666  return -1;
667  } else if (!s) {
668  return -1;
669  }
670 
671  return 0;
672 }
static struct ast_threadstorage last_del_id
Definition: sched.c:58
unsigned int deleted
Definition: sched.c:100
struct sched_id * sched_id
Definition: sched.c:79
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
struct ast_heap * sched_heap
Definition: sched.c:115
#define LOG_WARNING
Definition: logger.h:274
struct sched_thread * sched_thread
Definition: sched.c:116
Definition: sched.c:76
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
#define ast_cond_signal(cond)
Definition: lock.h:201
void ast_log_backtrace(void)
Log a backtrace of the current thread&#39;s execution stack to the Asterisk log.
Definition: logger.c:2158
pthread_t executing_thread_id
Definition: sched.c:120
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static struct sched * sched_find(struct ast_sched_context *con, int id)
Definition: sched.c:570
static void sched_release(struct ast_sched_context *con, struct sched *tmp)
Definition: sched.c:358
#define LOG_ERROR
Definition: logger.h:285
void ast_sched_dump(struct ast_sched_context *con)
Dump the contents of the scheduler to LOG_DEBUG.
Definition: sched.c:712
struct sched * currently_executing
Definition: sched.c:118
ast_cond_t cond
Definition: sched.c:105
void * ast_heap_remove(struct ast_heap *h, void *elm)
Remove a specific element from a heap.
Definition: heap.c:251
ast_cond_t cond
Definition: sched.c:98
ast_mutex_t lock
Definition: sched.c:110
#define DEBUG(a)
Definition: sched.c:36
enum queue_result id
Definition: app_queue.c:1507
ast_sched_cb callback
Definition: sched.c:92
int id
Definition: sched.c:72
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ast_sched_dump()

void ast_sched_dump ( struct ast_sched_context con)

Dump the contents of the scheduler to LOG_DEBUG.

Dumps the scheduler contents.

Definition at line 712 of file sched.c.

References ast_heap_peek(), ast_heap_size(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_tvnow(), ast_tvsub(), DEBUG_ATLEAST, ast_sched_context::eventcnt, ast_sched_context::highwater, ast_sched_context::lock, LOG_DEBUG, ast_sched_context::sched_heap, and ast_sched_context::schedccnt.

Referenced by ast_sched_add_variable(), ast_sched_del(), handle_dump_sched(), sip_do_reload(), and unload_module().

713 {
714  struct sched *q;
715  struct timeval when;
716  int x;
717  size_t heap_size;
718 
719  if (!DEBUG_ATLEAST(1)) {
720  return;
721  }
722 
723  when = ast_tvnow();
724 #ifdef SCHED_MAX_CACHE
725  ast_log(LOG_DEBUG, "Asterisk Schedule Dump (%zu in Q, %u Total, %u Cache, %u high-water)\n",
726  ast_heap_size(con->sched_heap), con->eventcnt - 1, con->schedccnt, con->highwater);
727 #else
728  ast_log(LOG_DEBUG, "Asterisk Schedule Dump (%zu in Q, %u Total, %u high-water)\n",
729  ast_heap_size(con->sched_heap), con->eventcnt - 1, con->highwater);
730 #endif
731 
732  ast_log(LOG_DEBUG, "=============================================================\n");
733  ast_log(LOG_DEBUG, "|ID Callback Data Time (sec:ms) |\n");
734  ast_log(LOG_DEBUG, "+-----+-----------------+-----------------+-----------------+\n");
735  ast_mutex_lock(&con->lock);
736  heap_size = ast_heap_size(con->sched_heap);
737  for (x = 1; x <= heap_size; x++) {
738  struct timeval delta;
739  q = ast_heap_peek(con->sched_heap, x);
740  delta = ast_tvsub(q->when, when);
741  ast_log(LOG_DEBUG, "|%.4d | %-15p | %-15p | %.6ld : %.6ld |\n",
742  q->sched_id->id,
743  q->callback,
744  q->data,
745  (long)delta.tv_sec,
746  (long int)delta.tv_usec);
747  }
748  ast_mutex_unlock(&con->lock);
749  ast_log(LOG_DEBUG, "=============================================================\n");
750 }
struct ast_heap * sched_heap
Definition: sched.c:115
Definition: sched.c:76
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_mutex_lock(a)
Definition: lock.h:187
#define LOG_DEBUG
Definition: logger.h:241
#define ast_log
Definition: astobj2.c:42
unsigned int schedccnt
Definition: sched.c:124
unsigned int eventcnt
Definition: sched.c:111
size_t ast_heap_size(struct ast_heap *h)
Get the current size of a heap.
Definition: heap.c:276
void * ast_heap_peek(struct ast_heap *h, unsigned int index)
Peek at an element on a heap.
Definition: heap.c:267
ast_mutex_t lock
Definition: sched.c:110
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: extconf.c:2298
unsigned int highwater
Definition: sched.c:112
#define DEBUG_ATLEAST(level)
Definition: logger.h:441
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ast_sched_find_data()

const void* ast_sched_find_data ( struct ast_sched_context con,
int  id 
)

Find a sched structure and return the data field associated with it.

Parameters
conscheduling context in which to search fro the matching id
idID of the scheduled item to find
Returns
the data field from the matching sched struct if found; else return NULL if not found.
Since
1.6.1

Definition at line 587 of file sched.c.

References ast_mutex_lock, ast_mutex_unlock, sched::data, ast_sched_context::lock, NULL, and sched_find().

588 {
589  struct sched *s;
590  const void *data = NULL;
591 
592  ast_mutex_lock(&con->lock);
593 
594  s = sched_find(con, id);
595  if (s) {
596  data = s->data;
597  }
598 
599  ast_mutex_unlock(&con->lock);
600 
601  return data;
602 }
Definition: sched.c:76
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static struct sched * sched_find(struct ast_sched_context *con, int id)
Definition: sched.c:570
const void * data
Definition: sched.c:91
ast_mutex_t lock
Definition: sched.c:110
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ast_sched_replace()

int ast_sched_replace ( int  old_id,
struct ast_sched_context con,
int  when,
ast_sched_cb  callback,
const void *  data 
)

replace a scheduler entry

Deprecated:
You should use the AST_SCHED_REPLACE() macro instead.

This deletes the scheduler entry for old_id if it exists, and then calls ast_sched_add to create a new entry. A negative old_id will be ignored.

Return values
-1failure
otherwise,returnsscheduled item ID

Definition at line 557 of file sched.c.

References ast_sched_add(), and AST_SCHED_DEL.

Referenced by iax2_sched_replace().

558 {
559  if (old_id > -1) {
560  AST_SCHED_DEL(con, old_id);
561  }
562  return ast_sched_add(con, when, callback, data);
563 }
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data)
Adds a scheduled event.
Definition: sched.c:565
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition: sched.h:46
struct timeval when
Definition: sched.c:80
const void * data
Definition: sched.c:91
ast_sched_cb callback
Definition: sched.c:92

◆ ast_sched_replace_variable()

int ast_sched_replace_variable ( int  old_id,
struct ast_sched_context con,
int  when,
ast_sched_cb  callback,
const void *  data,
int  variable 
)

replace a scheduler entry

Deprecated:
You should use the AST_SCHED_REPLACE_VARIABLE() macro instead.

This deletes the scheduler entry for old_id if it exists, and then calls ast_sched_add to create a new entry. A negative old_id will be ignored.

Return values
-1failure
otherwise,returnsscheduled item ID

Definition at line 512 of file sched.c.

References ast_sched_add_variable(), and AST_SCHED_DEL.

513 {
514  /* 0 means the schedule item is new; do not delete */
515  if (old_id > 0) {
516  AST_SCHED_DEL(con, old_id);
517  }
519 }
int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable)
Schedule callback(data) to happen when ms into the future.
Definition: sched.c:524
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition: sched.h:46
struct timeval when
Definition: sched.c:80
const void * data
Definition: sched.c:91
int variable
Definition: sched.c:90
ast_sched_cb callback
Definition: sched.c:92

◆ ast_sched_report()

void ast_sched_report ( struct ast_sched_context con,
struct ast_str **  buf,
struct ast_cb_names cbnames 
)

Show statics on what it is in the schedule queue.

Parameters
conSchedule context to check
bufdynamic string to store report
cbnamesto check against
Since
1.6.1

Definition at line 674 of file sched.c.

References ast_heap_peek(), ast_heap_size(), ast_mutex_lock, ast_mutex_unlock, ast_str_append(), ast_str_set(), sched::callback, ast_cb_names::cblist, ast_sched_context::highwater, ast_cb_names::list, ast_sched_context::lock, ast_cb_names::numassocs, and ast_sched_context::sched_heap.

Referenced by sip_show_sched().

675 {
676  int i, x;
677  struct sched *cur;
678  int countlist[cbnames->numassocs + 1];
679  size_t heap_size;
680 
681  memset(countlist, 0, sizeof(countlist));
682  ast_str_set(buf, 0, " Highwater = %u\n schedcnt = %zu\n", con->highwater, ast_heap_size(con->sched_heap));
683 
684  ast_mutex_lock(&con->lock);
685 
686  heap_size = ast_heap_size(con->sched_heap);
687  for (x = 1; x <= heap_size; x++) {
688  cur = ast_heap_peek(con->sched_heap, x);
689  /* match the callback to the cblist */
690  for (i = 0; i < cbnames->numassocs; i++) {
691  if (cur->callback == cbnames->cblist[i]) {
692  break;
693  }
694  }
695  if (i < cbnames->numassocs) {
696  countlist[i]++;
697  } else {
698  countlist[cbnames->numassocs]++;
699  }
700  }
701 
702  ast_mutex_unlock(&con->lock);
703 
704  for (i = 0; i < cbnames->numassocs; i++) {
705  ast_str_append(buf, 0, " %s : %d\n", cbnames->list[i], countlist[i]);
706  }
707 
708  ast_str_append(buf, 0, " <unknown> : %d\n", countlist[cbnames->numassocs]);
709 }
char * list[10]
Definition: sched.h:191
struct ast_heap * sched_heap
Definition: sched.c:115
ast_sched_cb cblist[10]
Definition: sched.h:192
Definition: sched.c:76
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ast_mutex_lock(a)
Definition: lock.h:187
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
int numassocs
Definition: sched.h:190
size_t ast_heap_size(struct ast_heap *h)
Get the current size of a heap.
Definition: heap.c:276
void * ast_heap_peek(struct ast_heap *h, unsigned int index)
Peek at an element on a heap.
Definition: heap.c:267
ast_mutex_t lock
Definition: sched.c:110
unsigned int highwater
Definition: sched.c:112
ast_sched_cb callback
Definition: sched.c:92
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ast_sched_runq()

int ast_sched_runq ( struct ast_sched_context con)

Launch all events which need to be run at this time.

Runs the queue.

Definition at line 755 of file sched.c.

References ast_cond_signal, ast_debug, ast_heap_peek(), ast_heap_pop(), ast_mutex_lock, ast_mutex_unlock, ast_tv(), ast_tvadd(), ast_tvcmp(), ast_tvnow(), sched::callback, sched::cond, ast_sched_context::currently_executing, sched::data, DEBUG, sched::deleted, ast_sched_context::executing_thread_id, ast_sched_context::lock, NULL, sched::resched, ast_sched_context::sched_heap, sched_release(), sched_settime(), schedule(), sched::variable, and sched::when.

Referenced by AST_TEST_DEFINE(), background_detect_exec(), dial_exec_full(), do_cdr(), do_monitor(), do_monitor_headset(), do_refresh(), handle_speechrecognize(), misdn_tasks_thread_func(), network_thread(), reload_config(), sched_run(), speech_background(), unload_module(), wait_for_winner(), and waitstream_core().

756 {
757  struct sched *current;
758  struct timeval when;
759  int numevents;
760  int res;
761 
762  DEBUG(ast_debug(1, "ast_sched_runq()\n"));
763 
764  ast_mutex_lock(&con->lock);
765 
766  when = ast_tvadd(ast_tvnow(), ast_tv(0, 1000));
767  for (numevents = 0; (current = ast_heap_peek(con->sched_heap, 1)); numevents++) {
768  /* schedule all events which are going to expire within 1ms.
769  * We only care about millisecond accuracy anyway, so this will
770  * help us get more than one event at one time if they are very
771  * close together.
772  */
773  if (ast_tvcmp(current->when, when) != -1) {
774  break;
775  }
776 
777  current = ast_heap_pop(con->sched_heap);
778 
779  /*
780  * At this point, the schedule queue is still intact. We
781  * have removed the first event and the rest is still there,
782  * so it's permissible for the callback to add new events, but
783  * trying to delete itself won't work because it isn't in
784  * the schedule queue. If that's what it wants to do, it
785  * should return 0.
786  */
787 
788  con->currently_executing = current;
789  con->executing_thread_id = pthread_self();
790  ast_mutex_unlock(&con->lock);
791  res = current->callback(current->data);
792  ast_mutex_lock(&con->lock);
793  con->currently_executing = NULL;
794  ast_cond_signal(&current->cond);
795 
796  if (res && !current->deleted) {
797  /*
798  * If they return non-zero, we should schedule them to be
799  * run again.
800  */
801  sched_settime(&current->when, current->variable ? res : current->resched);
802  schedule(con, current);
803  } else {
804  /* No longer needed, so release it */
805  sched_release(con, current);
806  }
807  }
808 
809  ast_mutex_unlock(&con->lock);
810 
811  return numevents;
812 }
unsigned int deleted
Definition: sched.c:100
struct ast_heap * sched_heap
Definition: sched.c:115
static void sched_settime(struct timeval *t, int when)
given the last event *tv and the offset in milliseconds &#39;when&#39;, computes the next value...
Definition: sched.c:488
Definition: sched.c:76
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
void * ast_heap_pop(struct ast_heap *h)
Pop the max element off of the heap.
Definition: heap.c:262
int resched
Definition: sched.c:89
#define ast_cond_signal(cond)
Definition: lock.h:201
pthread_t executing_thread_id
Definition: sched.c:120
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static void schedule(struct ast_sched_context *con, struct sched *s)
Take a sched structure and put it in the queue, such that the soonest event is first in the list...
Definition: sched.c:458
struct timeval when
Definition: sched.c:80
static void sched_release(struct ast_sched_context *con, struct sched *tmp)
Definition: sched.c:358
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compres two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
Definition: time.h:128
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
const void * data
Definition: sched.c:91
struct sched * currently_executing
Definition: sched.c:118
ast_cond_t cond
Definition: sched.c:98
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:226
void * ast_heap_peek(struct ast_heap *h, unsigned int index)
Peek at an element on a heap.
Definition: heap.c:267
ast_mutex_t lock
Definition: sched.c:110
#define DEBUG(a)
Definition: sched.c:36
int variable
Definition: sched.c:90
ast_sched_cb callback
Definition: sched.c:92
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ast_sched_start_thread()

int ast_sched_start_thread ( struct ast_sched_context con)

Start a thread for processing scheduler entries.

Parameters
conthe scheduler context this thread will manage
Return values
0success
non-zerofailure

Definition at line 195 of file sched.c.

References ast_calloc, ast_cond_init, ast_log, ast_pthread_create_background, AST_PTHREADT_NULL, sched_thread::cond, LOG_ERROR, NULL, sched_run(), ast_sched_context::sched_thread, sched_thread_destroy(), and sched_thread::thread.

Referenced by ast_sip_initialize_distributor(), ast_sip_initialize_scheduler(), ast_sip_initialize_transport_management(), dns_core_init(), load_module(), and stun_start_monitor().

196 {
197  struct sched_thread *st;
198 
199  if (con->sched_thread) {
200  ast_log(LOG_ERROR, "Thread already started on this scheduler context\n");
201  return -1;
202  }
203 
204  if (!(st = ast_calloc(1, sizeof(*st)))) {
205  return -1;
206  }
207 
208  ast_cond_init(&st->cond, NULL);
209 
211 
212  con->sched_thread = st;
213 
215  ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
217  return -1;
218  }
219 
220  return 0;
221 }
pthread_t thread
Definition: sched.c:104
static void * sched_run(void *data)
Definition: sched.c:132
struct sched_thread * sched_thread
Definition: sched.c:116
#define ast_cond_init(cond, attr)
Definition: lock.h:199
static void sched_thread_destroy(struct ast_sched_context *con)
Definition: sched.c:173
#define NULL
Definition: resample.c:96
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:567
#define ast_log
Definition: astobj2.c:42
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define LOG_ERROR
Definition: logger.h:285
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
ast_cond_t cond
Definition: sched.c:105

◆ ast_sched_wait()

int ast_sched_wait ( struct ast_sched_context con)

Return the number of milliseconds until the next scheduled event.

Determines number of seconds until the next outstanding event to take place.

Definition at line 431 of file sched.c.

References ast_debug, ast_heap_peek(), ast_mutex_lock, ast_mutex_unlock, ast_tvdiff_ms(), ast_tvnow(), DEBUG, ast_sched_context::lock, ast_sched_context::sched_heap, and sched::when.

Referenced by AST_TEST_DEFINE(), background_detect_exec(), dial_exec_full(), do_cdr(), do_monitor(), do_monitor_headset(), do_refresh(), handle_speechrecognize(), misdn_tasks_thread_func(), network_thread(), sched_run(), speech_background(), wait_for_winner(), and waitstream_core().

432 {
433  int ms;
434  struct sched *s;
435 
436  DEBUG(ast_debug(1, "ast_sched_wait()\n"));
437 
438  ast_mutex_lock(&con->lock);
439  if ((s = ast_heap_peek(con->sched_heap, 1))) {
440  ms = ast_tvdiff_ms(s->when, ast_tvnow());
441  if (ms < 0) {
442  ms = 0;
443  }
444  } else {
445  ms = -1;
446  }
447  ast_mutex_unlock(&con->lock);
448 
449  return ms;
450 }
struct ast_heap * sched_heap
Definition: sched.c:115
Definition: sched.c:76
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_mutex_lock(a)
Definition: lock.h:187
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 ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct timeval when
Definition: sched.c:80
void * ast_heap_peek(struct ast_heap *h, unsigned int index)
Peek at an element on a heap.
Definition: heap.c:267
ast_mutex_t lock
Definition: sched.c:110
#define DEBUG(a)
Definition: sched.c:36
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ast_sched_when()

long ast_sched_when ( struct ast_sched_context con,
int  id 
)

Returns the number of seconds before an event takes place.

Parameters
conContext to use
idId to dump

Definition at line 814 of file sched.c.

References ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_tvnow(), DEBUG, ast_sched_context::lock, sched_find(), and sched::when.

Referenced by _sip_show_peer(), handle_cli_status(), and parse_register_contact().

815 {
816  struct sched *s;
817  long secs = -1;
818  DEBUG(ast_debug(1, "ast_sched_when()\n"));
819 
820  ast_mutex_lock(&con->lock);
821 
822  s = sched_find(con, id);
823  if (s) {
824  struct timeval now = ast_tvnow();
825  secs = s->when.tv_sec - now.tv_sec;
826  }
827 
828  ast_mutex_unlock(&con->lock);
829 
830  return secs;
831 }
Definition: sched.c:76
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static struct sched * sched_find(struct ast_sched_context *con, int id)
Definition: sched.c:570
struct timeval when
Definition: sched.c:80
ast_mutex_t lock
Definition: sched.c:110
#define DEBUG(a)
Definition: sched.c:36
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ sched_alloc()

static struct sched* sched_alloc ( struct ast_sched_context con)
static

Definition at line 378 of file sched.c.

References ast_calloc, ast_cond_init, AST_LIST_REMOVE_HEAD, sched::cond, sched_id::list, NULL, sched_release(), ast_sched_context::schedc, ast_sched_context::schedccnt, set_sched_id(), and tmp().

Referenced by ast_sched_add_variable().

379 {
380  struct sched *tmp;
381 
382  /*
383  * We keep a small cache of schedule entries
384  * to minimize the number of necessary malloc()'s
385  */
386 #ifdef SCHED_MAX_CACHE
387  if ((tmp = AST_LIST_REMOVE_HEAD(&con->schedc, list))) {
388  con->schedccnt--;
389  } else
390 #endif
391  {
392  tmp = ast_calloc(1, sizeof(*tmp));
393  if (!tmp) {
394  return NULL;
395  }
396  ast_cond_init(&tmp->cond, NULL);
397  }
398 
399  if (set_sched_id(con, tmp)) {
400  sched_release(con, tmp);
401  return NULL;
402  }
403 
404  return tmp;
405 }
static int tmp()
Definition: bt_open.c:389
Definition: sched.c:76
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define NULL
Definition: resample.c:96
unsigned int schedccnt
Definition: sched.c:124
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
static void sched_release(struct ast_sched_context *con, struct sched *tmp)
Definition: sched.c:358
struct sched::@415 list
struct ast_sched_context::@416 schedc
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
ast_cond_t cond
Definition: sched.c:98
static int set_sched_id(struct ast_sched_context *con, struct sched *new_sched)
Definition: sched.c:348

◆ sched_find()

static struct sched* sched_find ( struct ast_sched_context con,
int  id 
)
static

Definition at line 570 of file sched.c.

References ast_heap_peek(), ast_heap_size(), sched_id::id, NULL, ast_sched_context::sched_heap, and sched::sched_id.

Referenced by ast_sched_del(), ast_sched_find_data(), and ast_sched_when().

571 {
572  int x;
573  size_t heap_size;
574 
575  heap_size = ast_heap_size(con->sched_heap);
576  for (x = 1; x <= heap_size; x++) {
577  struct sched *cur = ast_heap_peek(con->sched_heap, x);
578 
579  if (cur->sched_id->id == id) {
580  return cur;
581  }
582  }
583 
584  return NULL;
585 }
struct sched_id * sched_id
Definition: sched.c:79
struct ast_heap * sched_heap
Definition: sched.c:115
Definition: sched.c:76
#define NULL
Definition: resample.c:96
size_t ast_heap_size(struct ast_heap *h)
Get the current size of a heap.
Definition: heap.c:276
void * ast_heap_peek(struct ast_heap *h, unsigned int index)
Peek at an element on a heap.
Definition: heap.c:267
int id
Definition: sched.c:72

◆ sched_free()

static void sched_free ( struct sched task)
static

Definition at line 258 of file sched.c.

References ast_cond_destroy, ast_free, sched::cond, and sched::sched_id.

Referenced by ast_sched_context_destroy(), and sched_release().

259 {
260  /* task->sched_id will be NULL most of the time, but when the
261  * scheduler context shuts down, it will free all scheduled
262  * tasks, and in that case, the task->sched_id will be non-NULL
263  */
264  ast_free(task->sched_id);
265  ast_cond_destroy(&task->cond);
266  ast_free(task);
267 }
struct sched_id * sched_id
Definition: sched.c:79
#define ast_cond_destroy(cond)
Definition: lock.h:200
#define ast_free(a)
Definition: astmm.h:182
ast_cond_t cond
Definition: sched.c:98

◆ sched_release()

static void sched_release ( struct ast_sched_context con,
struct sched tmp 
)
static

Definition at line 358 of file sched.c.

References AST_LIST_INSERT_HEAD, AST_LIST_INSERT_TAIL, ast_sched_context::id_queue, sched_id::list, NULL, sched_free(), sched::sched_id, SCHED_MAX_CACHE, ast_sched_context::schedc, and ast_sched_context::schedccnt.

Referenced by ast_sched_clean_by_callback(), ast_sched_del(), ast_sched_runq(), and sched_alloc().

359 {
360  if (tmp->sched_id) {
362  tmp->sched_id = NULL;
363  }
364 
365  /*
366  * Add to the cache, or just free() if we
367  * already have too many cache entries
368  */
369 #ifdef SCHED_MAX_CACHE
370  if (con->schedccnt < SCHED_MAX_CACHE) {
371  AST_LIST_INSERT_HEAD(&con->schedc, tmp, list);
372  con->schedccnt++;
373  } else
374 #endif
375  sched_free(tmp);
376 }
struct sched_id * sched_id
Definition: sched.c:79
#define NULL
Definition: resample.c:96
#define SCHED_MAX_CACHE
Max num of schedule structs.
Definition: sched.c:56
unsigned int schedccnt
Definition: sched.c:124
struct ast_sched_context::@417 id_queue
struct sched::@415 list
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
struct ast_sched_context::@416 schedc
static void sched_free(struct sched *task)
Definition: sched.c:258
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710

◆ sched_run()

static void* sched_run ( void *  data)
static

Definition at line 132 of file sched.c.

References ast_cond_timedwait, ast_cond_wait, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), ast_tvnow(), sched_thread::cond, ast_sched_context::lock, NULL, ast_sched_context::sched_thread, and sched_thread::stop.

Referenced by ast_sched_start_thread().

133 {
134  struct ast_sched_context *con = data;
135 
136  while (!con->sched_thread->stop) {
137  int ms;
138  struct timespec ts = {
139  .tv_sec = 0,
140  };
141 
142  ast_mutex_lock(&con->lock);
143 
144  if (con->sched_thread->stop) {
145  ast_mutex_unlock(&con->lock);
146  return NULL;
147  }
148 
149  ms = ast_sched_wait(con);
150 
151  if (ms == -1) {
152  ast_cond_wait(&con->sched_thread->cond, &con->lock);
153  } else {
154  struct timeval tv;
155  tv = ast_tvadd(ast_tvnow(), ast_samp2tv(ms, 1000));
156  ts.tv_sec = tv.tv_sec;
157  ts.tv_nsec = tv.tv_usec * 1000;
158  ast_cond_timedwait(&con->sched_thread->cond, &con->lock, &ts);
159  }
160 
161  ast_mutex_unlock(&con->lock);
162 
163  if (con->sched_thread->stop) {
164  return NULL;
165  }
166 
167  ast_sched_runq(con);
168  }
169 
170  return NULL;
171 }
struct sched_thread * sched_thread
Definition: sched.c:116
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:238
int ast_sched_runq(struct ast_sched_context *con)
Launch all events which need to be run at this time.
Definition: sched.c:755
int ast_sched_wait(struct ast_sched_context *con)
Return the number of milliseconds until the next scheduled event.
Definition: sched.c:431
unsigned int stop
Definition: sched.c:106
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
ast_cond_t cond
Definition: sched.c:105
ast_mutex_t lock
Definition: sched.c:110
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:204
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ sched_settime()

static void sched_settime ( struct timeval *  t,
int  when 
)
static

given the last event *tv and the offset in milliseconds 'when', computes the next value,

Definition at line 488 of file sched.c.

References ast_assert, ast_log, ast_samp2tv(), ast_tvadd(), ast_tvcmp(), ast_tvnow(), ast_tvzero(), and LOG_WARNING.

Referenced by ast_sched_add_variable(), and ast_sched_runq().

489 {
490  struct timeval now = ast_tvnow();
491 
492  if (when < 0) {
493  /*
494  * A negative when value is likely a bug as it
495  * represents a VERY large timeout time.
496  */
498  "Bug likely: Negative time interval %d (interpreted as %u ms) requested!\n",
499  when, (unsigned int) when);
500  ast_assert(0);
501  }
502 
503  /*ast_debug(1, "TV -> %lu,%lu\n", tv->tv_sec, tv->tv_usec);*/
504  if (ast_tvzero(*t)) /* not supplied, default to now */
505  *t = now;
506  *t = ast_tvadd(*t, ast_samp2tv(when, 1000));
507  if (ast_tvcmp(*t, now) < 0) {
508  *t = now;
509  }
510 }
#define LOG_WARNING
Definition: logger.h:274
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_assert(a)
Definition: utils.h:695
#define ast_log
Definition: astobj2.c:42
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:238
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compres two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
Definition: time.h:128
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283

◆ sched_thread_destroy()

static void sched_thread_destroy ( struct ast_sched_context con)
static

Definition at line 173 of file sched.c.

References ast_cond_destroy, ast_cond_signal, ast_free, ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, sched_thread::cond, ast_sched_context::lock, NULL, ast_sched_context::sched_thread, sched_thread::stop, and sched_thread::thread.

Referenced by ast_sched_context_destroy(), and ast_sched_start_thread().

174 {
175  if (!con->sched_thread) {
176  return;
177  }
178 
179  if (con->sched_thread->thread != AST_PTHREADT_NULL) {
180  ast_mutex_lock(&con->lock);
181  con->sched_thread->stop = 1;
183  ast_mutex_unlock(&con->lock);
184  pthread_join(con->sched_thread->thread, NULL);
186  }
187 
189 
190  ast_free(con->sched_thread);
191 
192  con->sched_thread = NULL;
193 }
pthread_t thread
Definition: sched.c:104
struct sched_thread * sched_thread
Definition: sched.c:116
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
#define ast_cond_signal(cond)
Definition: lock.h:201
#define AST_PTHREADT_NULL
Definition: lock.h:66
unsigned int stop
Definition: sched.c:106
#define ast_cond_destroy(cond)
Definition: lock.h:200
#define ast_free(a)
Definition: astmm.h:182
ast_cond_t cond
Definition: sched.c:105
ast_mutex_t lock
Definition: sched.c:110
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ sched_time_cmp()

static int sched_time_cmp ( void *  va,
void *  vb 
)
static

Definition at line 223 of file sched.c.

References a, ast_tvcmp(), b, sched::tie_breaker, and sched::when.

Referenced by ast_sched_context_create().

224 {
225  struct sched *a = va;
226  struct sched *b = vb;
227  int cmp;
228 
229  cmp = ast_tvcmp(b->when, a->when);
230  if (!cmp) {
231  cmp = b->tie_breaker - a->tie_breaker;
232  }
233  return cmp;
234 }
Definition: sched.c:76
struct timeval when
Definition: sched.c:80
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compres two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
Definition: time.h:128
static struct test_val b
unsigned int tie_breaker
Tie breaker in case the when is the same for multiple entries.
Definition: sched.c:88
static struct test_val a

◆ schedule()

static void schedule ( struct ast_sched_context con,
struct sched s 
)
static

Take a sched structure and put it in the queue, such that the soonest event is first in the list.

Definition at line 458 of file sched.c.

References ast_heap_push, ast_heap_size(), ast_sched_context::highwater, ast_sched_context::sched_heap, sched::tie_breaker, and ast_sched_context::tie_breaker.

Referenced by ast_sched_add_variable(), and ast_sched_runq().

459 {
460  size_t size;
461 
462  size = ast_heap_size(con->sched_heap);
463 
464  /* Record the largest the scheduler heap became for reporting purposes. */
465  if (con->highwater <= size) {
466  con->highwater = size + 1;
467  }
468 
469  /* Determine the tie breaker value for the new entry. */
470  if (size) {
471  ++con->tie_breaker;
472  } else {
473  /*
474  * Restart the sequence for the first entry to make integer
475  * roll over more unlikely.
476  */
477  con->tie_breaker = 0;
478  }
479  s->tie_breaker = con->tie_breaker;
480 
481  ast_heap_push(con->sched_heap, s);
482 }
struct ast_heap * sched_heap
Definition: sched.c:115
unsigned int tie_breaker
Definition: sched.c:114
#define ast_heap_push(h, elm)
Definition: heap.h:126
size_t ast_heap_size(struct ast_heap *h)
Get the current size of a heap.
Definition: heap.c:276
unsigned int highwater
Definition: sched.c:112
unsigned int tie_breaker
Tie breaker in case the when is the same for multiple entries.
Definition: sched.c:88

◆ set_sched_id()

static int set_sched_id ( struct ast_sched_context con,
struct sched new_sched 
)
static

Definition at line 348 of file sched.c.

References add_ids(), AST_LIST_EMPTY, AST_LIST_REMOVE_HEAD, ast_sched_context::id_queue, sched_id::list, and sched::sched_id.

Referenced by sched_alloc().

349 {
350  if (AST_LIST_EMPTY(&con->id_queue) && (add_ids(con) == 0)) {
351  return -1;
352  }
353 
354  new_sched->sched_id = AST_LIST_REMOVE_HEAD(&con->id_queue, list);
355  return 0;
356 }
struct sched_id * sched_id
Definition: sched.c:79
static int add_ids(struct ast_sched_context *con)
Add new scheduler IDs to the queue.
Definition: sched.c:310
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct ast_sched_context::@417 id_queue
struct sched::@415 list

Variable Documentation

◆ last_del_id

struct ast_threadstorage last_del_id = { .once = PTHREAD_ONCE_INIT , .key_init = __init_last_del_id , .custom_init = NULL , }
static

Definition at line 58 of file sched.c.

Referenced by ast_sched_del().