sched.h File Reference

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define SCHED_MAX_CACHE   128
 Max num of schedule structs.
#define AST_SCHED_CB(a)   ((ast_sched_cb)(a))

Typedefs

typedef int(* ast_sched_cb )(void *data)
 callback for a cheops scheduler

Functions

struct sched_contextsched_context_create (void)
 New schedule context.
void sched_context_destroy (struct sched_context *c)
 destroys a schedule context
int ast_sched_add (struct sched_context *con, int when, ast_sched_cb callback, void *data)
 Adds a scheduled event.
int ast_sched_del (struct sched_context *con, int id)
 Deletes a scheduled event.
int ast_sched_wait (struct sched_context *con)
 Determines number of seconds until the next outstanding event to take place.
int ast_sched_runq (struct sched_context *con)
 Runs the queue.
void ast_sched_dump (struct sched_context *con)
 Dumps the scheduler contents.
long ast_sched_when (struct sched_context *con, int id)


Define Documentation

#define AST_SCHED_CB (  )     ((ast_sched_cb)(a))

Definition at line 54 of file sched.h.

#define SCHED_MAX_CACHE   128

Max num of schedule structs.

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 28 of file sched.h.


Typedef Documentation

typedef int(* ast_sched_cb)(void *data)

callback for a cheops scheduler

A cheops scheduler callback takes a pointer with callback data and returns a 0 if it should not be run again, or non-zero if it should be rescheduled to run again

Definition at line 53 of file sched.h.


Function Documentation

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

Adds a scheduled event.

Parameters:
con Schduler context to add
when how many milliseconds to wait for event to occur
callback function to call when the amount of time expires
data data to pass to the callback 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) Returns a schedule item ID on success, -1 on failure

Definition at line 232 of file sched.c.

00233 {
00234    /*
00235     * Schedule callback(data) to happen when ms into the future
00236     */
00237    struct sched *tmp;
00238    int res = -1;
00239    DEBUG(ast_log(LOG_DEBUG, "ast_sched_add()\n"));
00240    if (!when) {
00241       ast_log(LOG_NOTICE, "Scheduled event in 0 ms?\n");
00242       return -1;
00243    }
00244    ast_mutex_lock(&con->lock);
00245    if ((tmp = sched_alloc(con))) {
00246       tmp->id = con->eventcnt++;
00247       tmp->callback = callback;
00248       tmp->data = data;
00249       tmp->resched = when;
00250       tmp->when.tv_sec = 0;
00251       tmp->when.tv_usec = 0;
00252       if (sched_settime(&tmp->when, when)) {
00253          sched_release(con, tmp);
00254       } else {
00255          schedule(con, tmp);
00256          res = tmp->id;
00257       }
00258    }
00259    ast_mutex_unlock(&con->lock);
00260    return res;
00261 }

int ast_sched_del ( struct sched_context con,
int  id 
)

Deletes a scheduled event.

Parameters:
con scheduling context to delete item from
id ID of the scheduled item to delete Remove this event from being run. A procedure should not remove its own event, but return 0 instead. Returns 0 on success, -1 on failure

Definition at line 263 of file sched.c.

00264 {
00265    /*
00266     * Delete the schedule entry with number
00267     * "id".  It's nearly impossible that there
00268     * would be two or more in the list with that
00269     * id.
00270     */
00271    struct sched *last=NULL, *s;
00272    DEBUG(ast_log(LOG_DEBUG, "ast_sched_del()\n"));
00273    ast_mutex_lock(&con->lock);
00274    s = con->schedq;
00275    while(s) {
00276       if (s->id == id) {
00277          if (last)
00278             last->next = s->next;
00279          else
00280             con->schedq = s->next;
00281          con->schedcnt--;
00282          sched_release(con, s);
00283          break;
00284       }
00285       last = s;
00286       s = s->next;
00287    }
00288    ast_mutex_unlock(&con->lock);
00289    if (!s) {
00290       ast_log(LOG_NOTICE, "Attempted to delete nonexistent schedule entry %d!\n", id);
00291 #ifdef DO_CRASH
00292       CRASH;
00293 #endif
00294       return -1;
00295    } else
00296       return 0;
00297 }

void ast_sched_dump ( struct sched_context con  ) 

Dumps the scheduler contents.

Parameters:
con Context to dump Debugging: Dump the contents of the scheduler to stderr

Definition at line 299 of file sched.c.

00300 {
00301    /*
00302     * Dump the contents of the scheduler to
00303     * stderr
00304     */
00305    struct sched *q;
00306    struct timeval tv;
00307    time_t s, ms;
00308    gettimeofday(&tv, NULL);
00309 #ifdef SCHED_MAX_CACHE
00310    ast_log(LOG_DEBUG, "Asterisk Schedule Dump (%d in Q, %d Total, %d Cache)\n", 
00311                      con-> schedcnt, con->eventcnt - 1, con->schedccnt);
00312 #else
00313    ast_log(LOG_DEBUG, "Asterisk Schedule Dump (%d in Q, %d Total)\n",
00314                      con-> schedcnt, con->eventcnt - 1);
00315 #endif
00316 
00317    ast_log(LOG_DEBUG, "=================================================\n");
00318    ast_log(LOG_DEBUG, "|ID    Callback    Data        Time  (sec:ms)   |\n");
00319    ast_log(LOG_DEBUG, "+-----+-----------+-----------+-----------------+\n");
00320    q = con->schedq;
00321    while(q) {
00322       s =  q->when.tv_sec - tv.tv_sec;
00323       ms = q->when.tv_usec - tv.tv_usec;
00324       if (ms < 0) {
00325          ms += 1000000;
00326          s--;
00327       }
00328       ast_log(LOG_DEBUG, "|%.4d | %p | %p | %.6ld : %.6ld |\n", 
00329             q->id,
00330             q->callback,
00331             q->data,
00332             (long)s,
00333             (long)ms);
00334       q=q->next;
00335    }
00336    ast_log(LOG_DEBUG, "=================================================\n");
00337    
00338 }

int ast_sched_runq ( struct sched_context con  ) 

Runs the queue.

Parameters:
con Scheduling context to run Run the queue, executing all callbacks which need to be performed at this time. Returns the number of events processed.

Definition at line 340 of file sched.c.

00341 {
00342    /*
00343     * Launch all events which need to be run at this time.
00344     */
00345    struct sched *current;
00346    struct timeval tv;
00347    int x=0;
00348    int res;
00349    DEBUG(ast_log(LOG_DEBUG, "ast_sched_runq()\n"));
00350       
00351    ast_mutex_lock(&con->lock);
00352    for(;;) {
00353       if (!con->schedq)
00354          break;
00355       if (gettimeofday(&tv, NULL)) {
00356          /* This should never happen */
00357          ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
00358          break;
00359       }
00360       /* We only care about millisecond accuracy anyway, so this will
00361          help us get more than one event at one time if they are very
00362          close together. */
00363       tv.tv_usec += 1000;
00364       if (SOONER(con->schedq->when, tv)) {
00365          current = con->schedq;
00366          con->schedq = con->schedq->next;
00367          con->schedcnt--;
00368 
00369          /*
00370           * At this point, the schedule queue is still intact.  We
00371           * have removed the first event and the rest is still there,
00372           * so it's permissible for the callback to add new events, but
00373           * trying to delete itself won't work because it isn't in
00374           * the schedule queue.  If that's what it wants to do, it 
00375           * should return 0.
00376           */
00377          
00378          ast_mutex_unlock(&con->lock);
00379          res = current->callback(current->data);
00380          ast_mutex_lock(&con->lock);
00381          
00382          if (res) {
00383             /*
00384              * If they return non-zero, we should schedule them to be
00385              * run again.
00386              */
00387             if (sched_settime(&current->when, current->resched)) {
00388                sched_release(con, current);
00389             } else
00390                schedule(con, current);
00391          } else {
00392             /* No longer needed, so release it */
00393             sched_release(con, current);
00394          }
00395          x++;
00396       } else
00397          break;
00398    }
00399    ast_mutex_unlock(&con->lock);
00400    return x;
00401 }

int ast_sched_wait ( struct sched_context con  ) 

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

Parameters:
con context to act upon Determine the number of seconds until the next outstanding event should take place, and return the number of milliseconds until it needs to be run. This value is perfect for passing to the poll call. Returns "-1" if there is nothing there are no scheduled events (and thus the poll should not timeout)

Definition at line 141 of file sched.c.

00142 {
00143    /*
00144     * Return the number of milliseconds 
00145     * until the next scheduled event
00146     */
00147    struct timeval tv;
00148    int ms;
00149    DEBUG(ast_log(LOG_DEBUG, "ast_sched_wait()\n"));
00150    ast_mutex_lock(&con->lock);
00151    if (!con->schedq) {
00152       ms = -1;
00153    } else if (gettimeofday(&tv, NULL) < 0) {
00154       /* This should never happen */
00155       ms = 0;
00156    } else {
00157       ms = (con->schedq->when.tv_sec - tv.tv_sec) * 1000;
00158       ms += (con->schedq->when.tv_usec - tv.tv_usec) / 1000;
00159       if (ms < 0)
00160          ms = 0;
00161    }
00162    ast_mutex_unlock(&con->lock);
00163    return ms;
00164    
00165 }

long ast_sched_when ( struct sched_context con,
int  id 
)

Returns the number of seconds before an event takes place

Parameters:
con Context to use
id Id to dump

Definition at line 403 of file sched.c.

00404 {
00405    struct sched *s;
00406    long secs;
00407    struct timeval now;
00408    DEBUG(ast_log(LOG_DEBUG, "ast_sched_when()\n"));
00409 
00410    ast_mutex_lock(&con->lock);
00411    s=con->schedq;
00412    while (s!=NULL) {
00413       if (s->id==id) break;
00414       s=s->next;
00415    }
00416    secs=-1;
00417    if (s!=NULL) {
00418       if (gettimeofday(&now, NULL)) {
00419          ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
00420       } else {
00421          secs=s->when.tv_sec-now.tv_sec;
00422       }
00423    }
00424    ast_mutex_unlock(&con->lock);
00425    return secs;
00426 }

struct sched_context* sched_context_create ( void   )  [read]

New schedule context.

Definition at line 62 of file sched.c.

00063 {
00064    struct sched_context *tmp;
00065    tmp = malloc(sizeof(struct sched_context));
00066    if (tmp) {
00067             memset(tmp, 0, sizeof(struct sched_context));
00068       ast_mutex_init(&tmp->lock);
00069       tmp->eventcnt = 1;
00070       tmp->schedcnt = 0;
00071       tmp->schedq = NULL;
00072 #ifdef SCHED_MAX_CACHE
00073       tmp->schedc = NULL;
00074       tmp->schedccnt = 0;
00075 #endif
00076    }
00077    return tmp;
00078 }

void sched_context_destroy ( struct sched_context c  ) 

destroys a schedule context

Parameters:
c Context to free Destroys (free's) the given sched_context structure Returns 0 on success, -1 on failure

Definition at line 80 of file sched.c.

00081 {
00082    struct sched *s, *sl;
00083    ast_mutex_lock(&con->lock);
00084 #ifdef SCHED_MAX_CACHE
00085    /* Eliminate the cache */
00086    s = con->schedc;
00087    while(s) {
00088       sl = s;
00089       s = s->next;
00090       free(sl);
00091    }
00092 #endif
00093    /* And the queue */
00094    s = con->schedq;
00095    while(s) {
00096       sl = s;
00097       s = s->next;
00098       free(sl);
00099    }
00100    /* And the context */
00101    ast_mutex_unlock(&con->lock);
00102    ast_mutex_destroy(&con->lock);
00103    free(con);
00104 }


Generated on Wed Oct 28 17:01:02 2009 for Asterisk by  doxygen 1.5.6