Hello community, here is the log from the commit of package alsa checked in at Fri Nov 23 17:15:45 CET 2007. -------- --- alsa/alsa.changes 2007-11-16 12:09:32.000000000 +0100 +++ /mounts/work_src_done/STABLE/alsa/alsa.changes 2007-11-23 16:47:45.000000000 +0100 @@ -1,0 +2,7 @@ +Fri Nov 23 16:48:19 CET 2007 - tiwai@suse.de + +- fix possible CPU hog problem with too small avail_min +- fix time-stamp with dmix/dsnoop plugins +- fix mmap of multi plugins + +------------------------------------------------------------------- New: ---- alsa-lib-avail_min-fix.diff alsa-lib-dmix-tstamp-fix.diff alsa-lib-multi-mmap-fix.diff ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ alsa.spec ++++++ --- /var/tmp/diff_new_pack.Z22555/_old 2007-11-23 17:15:03.000000000 +0100 +++ /var/tmp/diff_new_pack.Z22555/_new 2007-11-23 17:15:03.000000000 +0100 @@ -21,7 +21,7 @@ AutoReqProv: on Summary: Advanced Linux Sound Architecture Version: 1.0.15 -Release: 11 +Release: 13 Source: ftp://ftp.alsa-project.org/pub/lib/alsa-lib-%{package_version}.tar.bz2 Source8: 40-alsa.rules Source11: alsasound @@ -40,6 +40,9 @@ Patch2: alsa-lib-smixer-range-fix.diff Patch3: alsa-lib-rate-plugin-fix.diff Patch4: alsa-lib-dmix-error-code-fix.diff +Patch5: alsa-lib-avail_min-fix.diff +Patch6: alsa-lib-dmix-tstamp-fix.diff +Patch7: alsa-lib-multi-mmap-fix.diff Url: http://www.alsa-project.org/ BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -116,6 +119,9 @@ %patch2 -p1 %patch3 -p1 %patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 %{?suse_update_config:%{suse_update_config -f .}} %build @@ -255,7 +261,12 @@ %{_libdir}/libasound.so.* %{_libdir}/alsa-lib %{_datadir}/alsa + %changelog +* Fri Nov 23 2007 - tiwai@suse.de +- fix possible CPU hog problem with too small avail_min +- fix time-stamp with dmix/dsnoop plugins +- fix mmap of multi plugins * Fri Nov 16 2007 - tiwai@suse.de - fix the wrong error codes in dmix (#339507) * Mon Nov 12 2007 - tiwai@suse.de ++++++ alsa-lib-avail_min-fix.diff ++++++ # HG changeset patch # User tiwai # Date 1195568950 -3600 # Node ID 39d34d6a4587ffa6462e42308fb3519f55a2781c # Parent b1d1733e52f8baf293ffa2af1c2b9cf5212006ec pcm - Limit the avail_min minimum size Fix avail_min if it's less than period_size. The too small avail_min is simply useless and the cause of CPU hog with rate plugin. diff -r b1d1733e52f8 -r 39d34d6a4587 src/pcm/pcm.c --- a/src/pcm/pcm.c Mon Nov 19 08:07:19 2007 +0100 +++ b/src/pcm/pcm.c Tue Nov 20 15:29:10 2007 +0100 @@ -5577,6 +5577,12 @@ int snd_pcm_sw_params_set_avail_min(snd_ #endif { assert(pcm && params); + /* Fix avail_min if it's below period size. The period_size + * defines the minimal wake-up timing accuracy, so it doesn't + * make sense to set below that. + */ + if (val < pcm->period_size) + val = pcm->period_size; params->avail_min = val; return 0; } ++++++ alsa-lib-dmix-tstamp-fix.diff ++++++ diff -r 39d34d6a4587 -r 3539f279ec38 src/pcm/pcm_direct.c --- a/src/pcm/pcm_direct.c Tue Nov 20 15:29:10 2007 +0100 +++ b/src/pcm/pcm_direct.c Wed Nov 21 12:19:43 2007 +0100 @@ -1001,6 +1001,17 @@ int snd_pcm_direct_initialize_slave(snd_ return ret; } + /* set timestamp mode to MMAP + * the slave timestamp is copied appropriately in dsnoop/dmix/dshare + * based on the tstamp_mode of each client + */ + ret = snd_pcm_sw_params_set_tstamp_mode(spcm, sw_params, + SND_PCM_TSTAMP_MMAP); + if (ret < 0) { + SNDERR("unable to tstamp mode MMAP"); + return ret; + } + if (dmix->type != SND_PCM_TYPE_DMIX) goto __skip_silencing; diff -r 39d34d6a4587 -r 3539f279ec38 src/pcm/pcm_dmix.c --- a/src/pcm/pcm_dmix.c Tue Nov 20 15:29:10 2007 +0100 +++ b/src/pcm/pcm_dmix.c Wed Nov 21 12:19:43 2007 +0100 @@ -367,11 +367,8 @@ static int snd_pcm_dmix_sync_ptr(snd_pcm if (avail > dmix->avail_max) dmix->avail_max = avail; if (avail >= pcm->stop_threshold) { - struct timeval tv; snd_timer_stop(dmix->timer); - gettimeofday(&tv, 0); - dmix->trigger_tstamp.tv_sec = tv.tv_sec; - dmix->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L; + gettimestamp(&dmix->trigger_tstamp); if (dmix->state == SND_PCM_STATE_RUNNING) { dmix->state = SND_PCM_STATE_XRUN; return -EPIPE; @@ -420,7 +417,10 @@ static int snd_pcm_dmix_status(snd_pcm_t memset(status, 0, sizeof(*status)); status->state = snd_pcm_dmix_state(pcm); status->trigger_tstamp = dmix->trigger_tstamp; - status->tstamp = snd_pcm_hw_fast_tstamp(dmix->spcm); + if (pcm->tstamp_mode == SND_PCM_TSTAMP_MMAP) + status->tstamp = snd_pcm_hw_fast_tstamp(dmix->spcm); + else + gettimestamp(&status->tstamp); status->avail = snd_pcm_mmap_playback_avail(pcm); status->avail_max = status->avail > dmix->avail_max ? status->avail : dmix->avail_max; dmix->avail_max = 0; @@ -525,7 +525,6 @@ static int snd_pcm_dmix_start(snd_pcm_t { snd_pcm_direct_t *dmix = pcm->private_data; snd_pcm_sframes_t avail; - struct timeval tv; int err; if (dmix->state != SND_PCM_STATE_PREPARED) @@ -540,9 +539,7 @@ static int snd_pcm_dmix_start(snd_pcm_t return err; snd_pcm_dmix_sync_area(pcm); } - gettimeofday(&tv, 0); - dmix->trigger_tstamp.tv_sec = tv.tv_sec; - dmix->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L; + gettimestamp(&dmix->trigger_tstamp); return 0; } diff -r 39d34d6a4587 -r 3539f279ec38 src/pcm/pcm_dshare.c --- a/src/pcm/pcm_dshare.c Tue Nov 20 15:29:10 2007 +0100 +++ b/src/pcm/pcm_dshare.c Wed Nov 21 12:19:43 2007 +0100 @@ -194,11 +194,8 @@ static int snd_pcm_dshare_sync_ptr(snd_p if (avail > dshare->avail_max) dshare->avail_max = avail; if (avail >= pcm->stop_threshold) { - struct timeval tv; snd_timer_stop(dshare->timer); - gettimeofday(&tv, 0); - dshare->trigger_tstamp.tv_sec = tv.tv_sec; - dshare->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L; + gettimestamp(&dshare->trigger_tstamp); if (dshare->state == SND_PCM_STATE_RUNNING) { dshare->state = SND_PCM_STATE_XRUN; return -EPIPE; @@ -229,7 +226,10 @@ static int snd_pcm_dshare_status(snd_pcm memset(status, 0, sizeof(*status)); status->state = snd_pcm_state(dshare->spcm); status->trigger_tstamp = dshare->trigger_tstamp; - status->tstamp = snd_pcm_hw_fast_tstamp(dshare->spcm); + if (pcm->tstamp_mode == SND_PCM_TSTAMP_MMAP) + status->tstamp = snd_pcm_hw_fast_tstamp(dshare->spcm); + else + gettimestamp(&status->tstamp); status->avail = snd_pcm_mmap_playback_avail(pcm); status->avail_max = status->avail > dshare->avail_max ? status->avail : dshare->avail_max; dshare->avail_max = 0; @@ -335,7 +335,6 @@ static int snd_pcm_dshare_start(snd_pcm_ { snd_pcm_direct_t *dshare = pcm->private_data; snd_pcm_sframes_t avail; - struct timeval tv; int err; if (dshare->state != SND_PCM_STATE_PREPARED) @@ -350,9 +349,7 @@ static int snd_pcm_dshare_start(snd_pcm_ return err; snd_pcm_dshare_sync_area(pcm); } - gettimeofday(&tv, 0); - dshare->trigger_tstamp.tv_sec = tv.tv_sec; - dshare->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L; + gettimestamp(&dshare->trigger_tstamp); return 0; } diff -r 39d34d6a4587 -r 3539f279ec38 src/pcm/pcm_dsnoop.c --- a/src/pcm/pcm_dsnoop.c Tue Nov 20 15:29:10 2007 +0100 +++ b/src/pcm/pcm_dsnoop.c Wed Nov 21 12:19:43 2007 +0100 @@ -141,10 +141,7 @@ static int snd_pcm_dsnoop_sync_ptr(snd_p if (pcm->stop_threshold >= pcm->boundary) /* don't care */ return 0; if ((avail = snd_pcm_mmap_capture_hw_avail(pcm)) >= pcm->stop_threshold) { - struct timeval tv; - gettimeofday(&tv, 0); - dsnoop->trigger_tstamp.tv_sec = tv.tv_sec; - dsnoop->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L; + gettimestamp(&dsnoop->trigger_tstamp); dsnoop->state = SND_PCM_STATE_XRUN; dsnoop->avail_max = avail; return -EPIPE; @@ -175,7 +172,10 @@ static int snd_pcm_dsnoop_status(snd_pcm state = snd_pcm_state(dsnoop->spcm); status->state = state == SND_PCM_STATE_RUNNING ? dsnoop->state : state; status->trigger_tstamp = dsnoop->trigger_tstamp; - status->tstamp = snd_pcm_hw_fast_tstamp(dsnoop->spcm); + if (pcm->tstamp_mode == SND_PCM_TSTAMP_MMAP) + status->tstamp = snd_pcm_hw_fast_tstamp(dsnoop->spcm); + else + gettimestamp(&status->tstamp); status->avail = snd_pcm_mmap_capture_avail(pcm); status->avail_max = status->avail > dsnoop->avail_max ? status->avail : dsnoop->avail_max; dsnoop->avail_max = 0; @@ -264,7 +264,6 @@ static int snd_pcm_dsnoop_start(snd_pcm_ static int snd_pcm_dsnoop_start(snd_pcm_t *pcm) { snd_pcm_direct_t *dsnoop = pcm->private_data; - struct timeval tv; int err; if (dsnoop->state != SND_PCM_STATE_PREPARED) @@ -275,9 +274,7 @@ static int snd_pcm_dsnoop_start(snd_pcm_ if (err < 0) return err; dsnoop->state = SND_PCM_STATE_RUNNING; - gettimeofday(&tv, 0); - dsnoop->trigger_tstamp.tv_sec = tv.tv_sec; - dsnoop->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L; + gettimestamp(&dsnoop->trigger_tstamp); return 0; } diff -r 39d34d6a4587 -r 3539f279ec38 src/pcm/pcm_ioplug.c --- a/src/pcm/pcm_ioplug.c Tue Nov 20 15:29:10 2007 +0100 +++ b/src/pcm/pcm_ioplug.c Wed Nov 21 12:19:43 2007 +0100 @@ -438,7 +438,6 @@ static int snd_pcm_ioplug_start(snd_pcm_ static int snd_pcm_ioplug_start(snd_pcm_t *pcm) { ioplug_priv_t *io = pcm->private_data; - struct timeval tv; int err; if (io->data->state != SND_PCM_STATE_PREPARED) @@ -448,9 +447,7 @@ static int snd_pcm_ioplug_start(snd_pcm_ if (err < 0) return err; - gettimeofday(&tv, 0); - io->trigger_tstamp.tv_sec = tv.tv_sec; - io->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L; + gettimestamp(&io->trigger_tstamp); io->data->state = SND_PCM_STATE_RUNNING; return 0; @@ -459,16 +456,13 @@ static int snd_pcm_ioplug_drop(snd_pcm_t static int snd_pcm_ioplug_drop(snd_pcm_t *pcm) { ioplug_priv_t *io = pcm->private_data; - struct timeval tv; if (io->data->state == SND_PCM_STATE_OPEN) return -EBADFD; io->data->callback->stop(io->data); - gettimeofday(&tv, 0); - io->trigger_tstamp.tv_sec = tv.tv_sec; - io->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L; + gettimestamp(&io->trigger_tstamp); io->data->state = SND_PCM_STATE_SETUP; return 0; diff -r 39d34d6a4587 -r 3539f279ec38 src/pcm/pcm_local.h --- a/src/pcm/pcm_local.h Tue Nov 20 15:29:10 2007 +0100 +++ b/src/pcm/pcm_local.h Wed Nov 21 12:19:43 2007 +0100 @@ -838,3 +838,13 @@ typedef union snd_tmp_double { double d; int64_t l; } snd_tmp_double_t; + +/* get the current timestamp */ +static inline void gettimestamp(snd_htimestamp_t *tstamp) +{ + struct timeval tv; + + gettimeofday(&tv, 0); + tstamp->tv_sec = tv.tv_sec; + tstamp->tv_nsec = tv.tv_usec * 1000L; +} diff -r 39d34d6a4587 -r 3539f279ec38 src/pcm/pcm_null.c --- a/src/pcm/pcm_null.c Tue Nov 20 15:29:10 2007 +0100 +++ b/src/pcm/pcm_null.c Wed Nov 21 12:19:43 2007 +0100 @@ -82,13 +82,10 @@ static int snd_pcm_null_status(snd_pcm_t static int snd_pcm_null_status(snd_pcm_t *pcm, snd_pcm_status_t * status) { snd_pcm_null_t *null = pcm->private_data; - struct timeval tv; memset(status, 0, sizeof(*status)); status->state = null->state; status->trigger_tstamp = null->trigger_tstamp; - gettimeofday(&tv, 0); - status->tstamp.tv_sec = tv.tv_sec; - status->tstamp.tv_nsec = tv.tv_usec * 1000L; + gettimestamp(&status->tstamp); status->avail = pcm->buffer_size; status->avail_max = status->avail; return 0; diff -r 39d34d6a4587 -r 3539f279ec38 src/pcm/pcm_rate.c --- a/src/pcm/pcm_rate.c Tue Nov 20 15:29:10 2007 +0100 +++ b/src/pcm/pcm_rate.c Wed Nov 21 12:19:43 2007 +0100 @@ -1090,7 +1090,6 @@ static int snd_pcm_rate_start(snd_pcm_t { snd_pcm_rate_t *rate = pcm->private_data; snd_pcm_uframes_t avail; - struct timeval tv; if (pcm->stream == SND_PCM_STREAM_CAPTURE) return snd_pcm_start(rate->gen.slave); @@ -1098,9 +1097,7 @@ static int snd_pcm_rate_start(snd_pcm_t if (snd_pcm_state(rate->gen.slave) != SND_PCM_STATE_PREPARED) return -EBADFD; - gettimeofday(&tv, 0); - rate->trigger_tstamp.tv_sec = tv.tv_sec; - rate->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L; + gettimestamp(&rate->trigger_tstamp); avail = snd_pcm_mmap_playback_hw_avail(rate->gen.slave); if (avail == 0) { diff -r 39d34d6a4587 -r 3539f279ec38 src/pcm/pcm_share.c --- a/src/pcm/pcm_share.c Tue Nov 20 15:29:10 2007 +0100 +++ b/src/pcm/pcm_share.c Wed Nov 21 12:19:43 2007 +0100 @@ -914,7 +914,6 @@ static int snd_pcm_share_start(snd_pcm_t snd_pcm_share_t *share = pcm->private_data; snd_pcm_share_slave_t *slave = share->slave; snd_pcm_t *spcm = slave->pcm; - struct timeval tv; int err = 0; if (share->state != SND_PCM_STATE_PREPARED) return -EBADFD; @@ -970,9 +969,7 @@ static int snd_pcm_share_start(snd_pcm_t } slave->running_count++; _snd_pcm_share_update(pcm); - gettimeofday(&tv, 0); - share->trigger_tstamp.tv_sec = tv.tv_sec; - share->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L; + gettimestamp(&share->trigger_tstamp); _end: Pthread_mutex_unlock(&slave->mutex); return err; @@ -1099,16 +1096,13 @@ static void _snd_pcm_share_stop(snd_pcm_ { snd_pcm_share_t *share = pcm->private_data; snd_pcm_share_slave_t *slave = share->slave; - struct timeval tv; #if 0 if (!pcm->mmap_channels) { /* PCM closing already begun in the main thread */ return; } #endif - gettimeofday(&tv, 0); - share->trigger_tstamp.tv_sec = tv.tv_sec; - share->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L; + gettimestamp(&share->trigger_tstamp); if (pcm->stream == SND_PCM_STREAM_CAPTURE) { snd_pcm_areas_copy(pcm->stopped_areas, 0, pcm->running_areas, 0, ++++++ alsa-lib-multi-mmap-fix.diff ++++++ # HG changeset patch # User tiwai # Date 1195829208 -3600 # Node ID 672c5387645d33ec98157257b5221476064ac810 # Parent 3539f279ec3847636ec20110e9237b88382722a9 Fix mmap with multi plugin The mmap of multi plugin seems broken (for a long time!) due to its creation of local buffer via snd_pcm_mmap(). Since the multi plugin just needs to shadow the mmap buffer of each slave, it now has mmap_shadow=1 and its own mmap/unmap method to do shadowing. diff -r 3539f279ec38 -r 672c5387645d src/pcm/pcm_multi.c --- a/src/pcm/pcm_multi.c Wed Nov 21 12:19:43 2007 +0100 +++ b/src/pcm/pcm_multi.c Fri Nov 23 15:46:48 2007 +0100 @@ -690,13 +690,44 @@ static snd_pcm_sframes_t snd_pcm_multi_m return size; } -static int snd_pcm_multi_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED) +static int snd_pcm_multi_munmap(snd_pcm_t *pcm) { + free(pcm->mmap_channels); + free(pcm->running_areas); + pcm->mmap_channels = NULL; + pcm->running_areas = NULL; return 0; } -static int snd_pcm_multi_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED) +static int snd_pcm_multi_mmap(snd_pcm_t *pcm) { + snd_pcm_multi_t *multi = pcm->private_data; + unsigned int c; + + pcm->mmap_channels = calloc(pcm->channels, + sizeof(pcm->mmap_channels[0])); + pcm->running_areas = calloc(pcm->channels, + sizeof(pcm->running_areas[0])); + if (!pcm->mmap_channels || !pcm->running_areas) { + snd_pcm_multi_munmap(pcm); + return -ENOMEM; + } + + /* Copy the slave mmapped buffer data */ + for (c = 0; c < pcm->channels; c++) { + snd_pcm_multi_channel_t *chan = &multi->channels[c]; + snd_pcm_t *slave; + if (chan->slave_idx < 0) { + snd_pcm_multi_munmap(pcm); + return -ENXIO; + } + slave = multi->slaves[chan->slave_idx].pcm; + pcm->mmap_channels[c] = + slave->mmap_channels[chan->slave_channel]; + pcm->mmap_channels[c].channel = c; + pcm->running_areas[c] = + slave->running_areas[chan->slave_channel]; + } return 0; } @@ -850,6 +881,7 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, return err; } pcm->mmap_rw = 1; + pcm->mmap_shadow = 1; /* has own mmap method */ pcm->ops = &snd_pcm_multi_ops; pcm->fast_ops = &snd_pcm_multi_fast_ops; pcm->private_data = multi; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org