aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/vivi.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2007-12-13 14:15:41 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 16:03:42 -0500
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)
425 spin_unlock(&dev->slock); 425 spin_unlock(&dev->slock);
426} 426}
427 427
428#define frames_to_ms(frames) \
429 ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR)
430
428static void vivi_sleep(struct vivi_dmaqueue *dma_q) 431static void vivi_sleep(struct vivi_dmaqueue *dma_q)
429{ 432{
430 struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); 433 struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq);
431 int timeout; 434 int timeout, running_time;
432 DECLARE_WAITQUEUE(wait, current); 435 DECLARE_WAITQUEUE(wait, current);
433 436
434 dprintk(dev, 1, "%s dma_q=0x%08lx\n", __FUNCTION__, 437 dprintk(dev, 1, "%s dma_q=0x%08lx\n", __FUNCTION__,
435 (unsigned long)dma_q); 438 (unsigned long)dma_q);
436 439
437 add_wait_queue(&dma_q->wq, &wait); 440 add_wait_queue(&dma_q->wq, &wait);
438 if (!kthread_should_stop()) { 441 if (kthread_should_stop())
439 dma_q->frame++; 442 goto stop_task;
440 443
441 /* Calculate time to wake up */ 444 running_time = jiffies - dma_q->ini_jiffies;
442 timeout = dma_q->ini_jiffies+ 445 dma_q->frame++;
443 msecs_to_jiffies((dma_q->frame*WAKE_NUMERATOR * 1000) 446
444 / WAKE_DENOMINATOR) - jiffies; 447 /* Calculate time to wake up */
445 448 timeout = msecs_to_jiffies(frames_to_ms(dma_q->frame)) - running_time;
446 if (timeout <= 0) { 449
447 int old = dma_q->frame; 450 if (timeout > msecs_to_jiffies(frames_to_ms(2)) || timeout <= 0) {
448 dma_q->frame = (jiffies_to_msecs(jiffies - 451 int old = dma_q->frame;
449 dma_q->ini_jiffies) * 452 int nframes;
450 WAKE_DENOMINATOR) / 453
451 (WAKE_NUMERATOR * 1000) + 1; 454 dma_q->frame = (jiffies_to_msecs(running_time) /
452 455 frames_to_ms(1)) + 1;
453 timeout = dma_q->ini_jiffies+ 456
454 msecs_to_jiffies((dma_q->frame * 457 timeout = msecs_to_jiffies(frames_to_ms(dma_q->frame))
455 WAKE_NUMERATOR * 1000) 458 - running_time;
456 / WAKE_DENOMINATOR) - jiffies; 459
457 460 if (unlikely (timeout <= 0))
458 dprintk(dev, 1, "underrun, losed %d frames. " 461 timeout = 1;
459 "Now, frame is %d. Waking on %d jiffies\n", 462
460 dma_q->frame-old, dma_q->frame, timeout); 463 nframes = (dma_q->frame > old)?
461 } else 464 dma_q->frame - old : old - dma_q->frame;
462 dprintk(dev, 1, "will sleep for %i jiffies\n", 465
463 timeout); 466 dprintk(dev, 1, "%ld: %s %d frames. "
464 467 "Current frame is %d. Will sleep for %d jiffies\n",
465 vivi_thread_tick(dma_q); 468 jiffies,
466 469 (dma_q->frame > old)? "Underrun, losed" : "Overrun of",
467 schedule_timeout_interruptible(timeout); 470 nframes, dma_q->frame, timeout);
468 } 471 } else
472 dprintk(dev, 1, "will sleep for %d jiffies\n", timeout);
473
474 vivi_thread_tick(dma_q);
475
476 schedule_timeout_interruptible(timeout);
469 477
478stop_task:
470 remove_wait_queue(&dma_q->wq, &wait); 479 remove_wait_queue(&dma_q->wq, &wait);
471 try_to_freeze(); 480 try_to_freeze();
472} 481}