summaryrefslogtreecommitdiffstats
path: root/sound/core/timer.c
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2007-12-13 10:19:42 +0100
committerJaroslav Kysela <perex@perex.cz>2008-01-31 17:29:31 +0100
commitb751eef1fdffca5532344285f2fad0c60d2f0158 (patch)
treed504104c6315a8abc4b3f657f8f4828fb55a8795 /sound/core/timer.c
parent[ALSA] cmipci: document 'Modem' control version check (diff)
downloadlinux-b751eef1fdffca5532344285f2fad0c60d2f0158.tar.xz
linux-b751eef1fdffca5532344285f2fad0c60d2f0158.zip
[ALSA] Use posix clock monotonic for PCM and timer timestamps
We need an accurate and continuous (monotonic) time sources to do accurate synchronization among more timing sources. This patch allows to enable monotonic timestamps for ALSA PCM devices and enables monotonic timestamps for ALSA timer devices. Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/core/timer.c')
-rw-r--r--sound/core/timer.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/sound/core/timer.c b/sound/core/timer.c
index e7dc56ca4b97..7e5fe2d91662 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -44,11 +44,14 @@
#endif
static int timer_limit = DEFAULT_TIMER_LIMIT;
+static int timer_tstamp_monotonic = 1;
MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>");
MODULE_DESCRIPTION("ALSA timer interface");
MODULE_LICENSE("GPL");
module_param(timer_limit, int, 0444);
MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
+module_param(timer_tstamp_monotonic, int, 0444);
+MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default).");
struct snd_timer_user {
struct snd_timer_instance *timeri;
@@ -381,7 +384,10 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
struct snd_timer_instance *ts;
struct timespec tstamp;
- getnstimeofday(&tstamp);
+ if (timer_tstamp_monotonic)
+ do_posix_clock_monotonic_gettime(&tstamp);
+ else
+ getnstimeofday(&tstamp);
snd_assert(event >= SNDRV_TIMER_EVENT_START &&
event <= SNDRV_TIMER_EVENT_PAUSE, return);
if (event == SNDRV_TIMER_EVENT_START ||
@@ -1182,8 +1188,12 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
spin_unlock(&tu->qlock);
return;
}
- if (tu->last_resolution != resolution || ticks > 0)
- getnstimeofday(&tstamp);
+ if (tu->last_resolution != resolution || ticks > 0) {
+ if (timer_tstamp_monotonic)
+ do_posix_clock_monotonic_gettime(&tstamp);
+ else
+ getnstimeofday(&tstamp);
+ }
if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
tu->last_resolution != resolution) {
r1.event = SNDRV_TIMER_EVENT_RESOLUTION;