summaryrefslogtreecommitdiff
path: root/drivers/dahdi
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2010-09-24 22:44:37 +0000
committerShaun Ruffell <sruffell@digium.com>2010-09-24 22:44:37 +0000
commit28ff1b763c119bcbd7fe41566f28e8e6b687cf0b (patch)
treede961abc3d03574e4bb96acb3bde92461e9bf51a /drivers/dahdi
parent39e7e3fe91e5090c76576febfb88667c82121fe1 (diff)
dahdi: Allow core DAHDI software timing to work when DAHDI_CHUNKSIZE > 8.
When no hardware spans are configured DAHDI will use a kernel timer in order provide timing for conferences. This is what dahdi_dummy historically was used for. When kernel timers are used to provide timing DAHDI can both potentially slow the rate at which time timer runs and also needs to account for how many milliseconds of audio are processed for each 'tick' of process_masterspan. The result is that if you are only using DAHDI for app_meetme, you can change DAHDI_CHUNKSIZE to 40 (5ms) or 80 (10ms) bytes to reduce overhead since user space is dealing with chunks of 20ms by default anyway. NOTE: If you set this, you may still need to comment out the board drivers in drivers/dahdi/Kbuild since they all do not support operating with a DAHDI_CHUNKSIZE != 8 currently. Signed-off-by: Shaun Ruffell <sruffell@digium.com> Acked-by: Kinsey Moore <kmoore@digium.com> Acked-by: Russ Meyerriecks <rmeyerriecks@digium.com> Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com> Review: https://reviewboard.asterisk.org/r/940/ git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9407 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi')
-rw-r--r--drivers/dahdi/dahdi-base.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c
index 6e94782..8db1705 100644
--- a/drivers/dahdi/dahdi-base.c
+++ b/drivers/dahdi/dahdi-base.c
@@ -245,6 +245,7 @@ static struct {
static struct core_timer {
struct timer_list timer;
struct timespec start_interval;
+ unsigned long interval;
atomic_t count;
atomic_t shutdown;
atomic_t last_count;
@@ -8493,7 +8494,7 @@ static void process_masterspan(void)
/* We increment the calls since start here, so that if we switch over
* to the core timer, we know how many times we need to call
* process_masterspan in order to catch up since this function needs
- * to be called 1000 times per second. */
+ * to be called (1000 / (DAHDI_CHUNKSIZE / 8)) times per second. */
atomic_inc(&core_timer.count);
#endif
/* Hold the big zap lock for the duration of major
@@ -8619,14 +8620,19 @@ static unsigned long core_diff_ms(struct timespec *t0, struct timespec *t1)
return ms;
}
+static inline unsigned long msecs_processed(const struct core_timer *const ct)
+{
+ return atomic_read(&ct->count) * DAHDI_MSECS_PER_CHUNK;
+}
+
static void coretimer_func(unsigned long param)
{
unsigned long ms_since_start;
struct timespec now;
const unsigned long MAX_INTERVAL = 100000L;
- const unsigned long FOURMS_INTERVAL = max(HZ/250, 1);
const unsigned long ONESEC_INTERVAL = HZ;
- const unsigned long MS_LIMIT = 3000;
+ const long MS_LIMIT = 3000;
+ long difference;
now = current_kernel_time();
@@ -8637,8 +8643,10 @@ static void coretimer_func(unsigned long param)
* dahdi_receive, and therefore the core of dahdi needs to
* perform the master span processing itself. */
- if (!atomic_read(&core_timer.shutdown))
- mod_timer(&core_timer.timer, jiffies + FOURMS_INTERVAL);
+ if (!atomic_read(&core_timer.shutdown)) {
+ mod_timer(&core_timer.timer, jiffies +
+ core_timer.interval);
+ }
ms_since_start = core_diff_ms(&core_timer.start_interval, &now);
@@ -8649,16 +8657,19 @@ static void coretimer_func(unsigned long param)
* not hang the system here.
*
*/
- if (unlikely((ms_since_start - atomic_read(&core_timer.count)) > MS_LIMIT)) {
- if (printk_ratelimit())
- module_printk(KERN_INFO, "Detected time shift.\n");
+ difference = ms_since_start - msecs_processed(&core_timer);
+ if (unlikely(difference > MS_LIMIT)) {
+ if (printk_ratelimit()) {
+ module_printk(KERN_INFO,
+ "Detected time shift.");
+ }
atomic_set(&core_timer.count, 0);
atomic_set(&core_timer.last_count, 0);
core_timer.start_interval = now;
return;
}
- while (ms_since_start > atomic_read(&core_timer.count))
+ while (ms_since_start > msecs_processed(&core_timer))
process_masterspan();
if (ms_since_start > MAX_INTERVAL) {
@@ -8690,6 +8701,9 @@ static void coretimer_init(void)
core_timer.timer.expires = jiffies + HZ;
atomic_set(&core_timer.count, 0);
atomic_set(&core_timer.shutdown, 0);
+ core_timer.interval = max(msecs_to_jiffies(DAHDI_MSECS_PER_CHUNK), 1UL);
+ if (core_timer.interval < (HZ/250))
+ core_timer.interval = (HZ/250);
add_timer(&core_timer.timer);
}