Skip to content

Commit 671ec85

Browse files
committed
ALSA: seq: Process queue tempo/ppq change in a shot
The SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO ioctl sets the tempo and the ppq in a single call, while the current implementation updates each value one by one. This is a bit racy, and also suboptimal from the performance POV, as each call does re-acquire the lock and invokes the update of ALSA timer resolution. This patch reorganizes the code slightly so that we change both the tempo and the ppq in a shot. The skew value can be put into the same lock, but this is rather a rarely used feature and completely independent from the temp/ppq (it's evaluated only in the interrupt), so it's left as it was. Signed-off-by: Takashi Iwai <[email protected]>
1 parent 4ea5553 commit 671ec85

File tree

3 files changed

+10
-9
lines changed

3 files changed

+10
-9
lines changed

sound/core/seq/seq_queue.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -497,9 +497,7 @@ int snd_seq_queue_timer_set_tempo(int queueid, int client,
497497
return -EPERM;
498498
}
499499

500-
result = snd_seq_timer_set_tempo(q->timer, info->tempo);
501-
if (result >= 0)
502-
result = snd_seq_timer_set_ppq(q->timer, info->ppq);
500+
result = snd_seq_timer_set_tempo_ppq(q->timer, info->tempo, info->ppq);
503501
if (result >= 0 && info->skew_base > 0)
504502
result = snd_seq_timer_set_skew(q->timer, info->skew_value,
505503
info->skew_base);

sound/core/seq/seq_timer.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,14 +191,15 @@ int snd_seq_timer_set_tempo(struct snd_seq_timer * tmr, int tempo)
191191
return 0;
192192
}
193193

194-
/* set current ppq */
195-
int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq)
194+
/* set current tempo and ppq in a shot */
195+
int snd_seq_timer_set_tempo_ppq(struct snd_seq_timer *tmr, int tempo, int ppq)
196196
{
197+
int changed;
197198
unsigned long flags;
198199

199200
if (snd_BUG_ON(!tmr))
200201
return -EINVAL;
201-
if (ppq <= 0)
202+
if (tempo <= 0 || ppq <= 0)
202203
return -EINVAL;
203204
spin_lock_irqsave(&tmr->lock, flags);
204205
if (tmr->running && (ppq != tmr->ppq)) {
@@ -208,9 +209,11 @@ int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq)
208209
pr_debug("ALSA: seq: cannot change ppq of a running timer\n");
209210
return -EBUSY;
210211
}
211-
212+
changed = (tempo != tmr->tempo) || (ppq != tmr->ppq);
213+
tmr->tempo = tempo;
212214
tmr->ppq = ppq;
213-
snd_seq_timer_set_tick_resolution(tmr);
215+
if (changed)
216+
snd_seq_timer_set_tick_resolution(tmr);
214217
spin_unlock_irqrestore(&tmr->lock, flags);
215218
return 0;
216219
}

sound/core/seq/seq_timer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ int snd_seq_timer_stop(struct snd_seq_timer *tmr);
131131
int snd_seq_timer_start(struct snd_seq_timer *tmr);
132132
int snd_seq_timer_continue(struct snd_seq_timer *tmr);
133133
int snd_seq_timer_set_tempo(struct snd_seq_timer *tmr, int tempo);
134-
int snd_seq_timer_set_ppq(struct snd_seq_timer *tmr, int ppq);
134+
int snd_seq_timer_set_tempo_ppq(struct snd_seq_timer *tmr, int tempo, int ppq);
135135
int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr, snd_seq_tick_time_t position);
136136
int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr, snd_seq_real_time_t position);
137137
int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, unsigned int base);

0 commit comments

Comments
 (0)