[Asterisk-Dev] sched.c::schedule function can be a bottleneck and is optimised backwards

Steve Kann stevek at stevek.com
Fri Oct 28 14:55:04 MST 2005


Chris Wade wrote:

> Steve Kann wrote:
>
>> If you end up with thousands of schedulings in the first 100ms or so, 
>> and then a thousand or so things spread over the next 30ms, then it 
>> might make sense to split it up into two queues: a "short" queue, and 
>> a "long" queue, or something like that.
>
>
> Why not simply choose the schedule search algorithm at time of 
> insertion?  I'm sure both algorithm's have their place -- let the 
> developer needed to schedule something choose the better algorithm for 
> what they are scheduling.  I may be talking out of my @$$ here but 
> it's just a stupid suggestion.
>
Because, even with a doubly-linked list, you still would have only two 
choices:  start looking for the right place at the beginning, or start 
looking at the end.

My suspicion is that the scheduler queue actually has two different 
types of scheduling events:  short-term events, and long-term events.

The short term events might be 50% of the total, and might all be 
scheduled for the next 500ms or so (not sure what that number would be), 
and relatively evenly-distributed over that time.   These short-term 
events would include:

a) New Jitterbuffer pulls (these are actually all generally scheduled to 
happen every 20-30ms or so).
  (OR, old jitterbuffer delivery scheduled packets, probably evenly 
distributed over <jitter>-ms).
b) IAX2 retransmits (2xRTT or so, probably around 30-60ms or so).
c) other things like this (?)

The long term events might also be 50% of the total, but evenly 
distributed over 30s or 60s or so.
a) pings (once every 10s?)
b) lagrq (once every 30s? -- these probably should just go away, IMHO).
c) Real-time auto-clear (?)
d) call timeouts (auto-congest?)
e) registration-refresh
f) registry-expiration
g) auth-reject?
h) auto-hangup
i) poke stuff

So, if you want to schedule something long-term, you need to search 
through _all_ the events to find the right spot to put it in the list.  
That's definately bad, and you can pretty much solve that by starting 
your search from the end of the queue.

But, it doesn't help for the short-term events.  For these, it would be 
ideal to start from the "middle", and work back, or something, which 
isn't really an option.  That's why it might make sense to have two 
queues, and have the scheduler just maintain them separately:

When you schedule something, if you're scheduling it to happen within X 
ms (where X might be 200, 500, or 2000, for example), it would go into 
the short-term queue, and you'd start looking for the right place at the 
end.  If it's long-term, you'd look at the end of the long-term queue, 
to find the right place.

You can probably implement this as follows:

1) Modify ast_sched_XXX to follow the same API, except use a 
double-linked list, and search from the end of the list when adding.

2) Modify chan_iax2, so that "short-term" scheduled things use 
"sched_short", and long term things use "sched_long", instead of both 
using the same scheduler.

3) Modify the 5 line area at the bottom of network_thread in chan_iax2 
to check both scheduler queues and use the earlier value when it calls 
ast_io_wait.

-SteveK





More information about the asterisk-dev mailing list