summaryrefslogtreecommitdiff
path: root/drivers/media/video/vivi.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2007-12-13 16:15:41 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 19:03:42 -0200
commit6594ad829a98d5a9fe720d8d182a4e50fc81953a (patch)
treed953e76cb71a79268c0c1431f51a6664d911d114 /drivers/media/video/vivi.c
parent55862ac9b2e656c35ab1e25d9b162e5bda81281f (diff)
V4L/DVB (6817): Cleanup kernel thread and provide overrun detection
The previous code were a little bit messy. Cleans it up. Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/vivi.c')
-rw-r--r--drivers/media/video/vivi.c73
1 files changed, 41 insertions, 32 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 004209d54498..c9d23633fe42 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -425,48 +425,57 @@ static void vivi_thread_tick(struct vivi_dmaqueue *dma_q)
spin_unlock(&dev->slock);
}
+#define frames_to_ms(frames) \
+ ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR)
+
static void vivi_sleep(struct vivi_dmaqueue *dma_q)
{
struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq);
- int timeout;
+ int timeout, running_time;
DECLARE_WAITQUEUE(wait, current);
dprintk(dev, 1, "%s dma_q=0x%08lx\n", __FUNCTION__,
(unsigned long)dma_q);
add_wait_queue(&dma_q->wq, &wait);
- if (!kthread_should_stop()) {
- dma_q->frame++;
-
- /* Calculate time to wake up */
- timeout = dma_q->ini_jiffies+
- msecs_to_jiffies((dma_q->frame*WAKE_NUMERATOR * 1000)
- / WAKE_DENOMINATOR) - jiffies;
-
- if (timeout <= 0) {
- int old = dma_q->frame;
- dma_q->frame = (jiffies_to_msecs(jiffies -
- dma_q->ini_jiffies) *
- WAKE_DENOMINATOR) /
- (WAKE_NUMERATOR * 1000) + 1;
-
- timeout = dma_q->ini_jiffies+
- msecs_to_jiffies((dma_q->frame *
- WAKE_NUMERATOR * 1000)
- / WAKE_DENOMINATOR) - jiffies;
-
- dprintk(dev, 1, "underrun, losed %d frames. "
- "Now, frame is %d. Waking on %d jiffies\n",
- dma_q->frame-old, dma_q->frame, timeout);
- } else
- dprintk(dev, 1, "will sleep for %i jiffies\n",
- timeout);
-
- vivi_thread_tick(dma_q);
-
- schedule_timeout_interruptible(timeout);
- }
+ if (kthread_should_stop())
+ goto stop_task;
+
+ running_time = jiffies - dma_q->ini_jiffies;
+ dma_q->frame++;
+
+ /* Calculate time to wake up */
+ timeout = msecs_to_jiffies(frames_to_ms(dma_q->frame)) - running_time;
+
+ if (timeout > msecs_to_jiffies(frames_to_ms(2)) || timeout <= 0) {
+ int old = dma_q->frame;
+ int nframes;
+
+ dma_q->frame = (jiffies_to_msecs(running_time) /
+ frames_to_ms(1)) + 1;
+
+ timeout = msecs_to_jiffies(frames_to_ms(dma_q->frame))
+ - running_time;
+
+ if (unlikely (timeout <= 0))
+ timeout = 1;
+
+ nframes = (dma_q->frame > old)?
+ dma_q->frame - old : old - dma_q->frame;
+
+ dprintk(dev, 1, "%ld: %s %d frames. "
+ "Current frame is %d. Will sleep for %d jiffies\n",
+ jiffies,
+ (dma_q->frame > old)? "Underrun, losed" : "Overrun of",
+ nframes, dma_q->frame, timeout);
+ } else
+ dprintk(dev, 1, "will sleep for %d jiffies\n", timeout);
+
+ vivi_thread_tick(dma_q);
+
+ schedule_timeout_interruptible(timeout);
+stop_task:
remove_wait_queue(&dma_q->wq, &wait);
try_to_freeze();
}