mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
pcm: hw: allocate fallback buffer in advance of trials of mapping
When allowing failure of map operation for both of status/control data for runtime of PCM substream, applications need to use fallback buffer for an alternative ioctl. However, in current implementation, status mapping is dominant to the allocation. This commit moves code for the allocation outside of the mapping operation for status data. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
cb7503eba1
commit
afadf61e44
1 changed files with 21 additions and 9 deletions
|
|
@ -867,21 +867,18 @@ static snd_pcm_sframes_t snd_pcm_hw_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_u
|
|||
return xfern.result;
|
||||
}
|
||||
|
||||
static int map_status_data(snd_pcm_hw_t *hw)
|
||||
static int map_status_data(snd_pcm_hw_t *hw, struct snd_pcm_sync_ptr *sync_ptr)
|
||||
{
|
||||
void *ptr;
|
||||
int err;
|
||||
|
||||
ptr = MAP_FAILED;
|
||||
if (hw->sync_ptr_ioctl == 0)
|
||||
ptr = mmap(NULL, page_align(sizeof(struct snd_pcm_mmap_status)),
|
||||
PROT_READ, MAP_FILE|MAP_SHARED,
|
||||
hw->fd, SNDRV_PCM_MMAP_OFFSET_STATUS);
|
||||
if (ptr == MAP_FAILED || ptr == NULL) {
|
||||
hw->sync_ptr = calloc(1, sizeof(struct snd_pcm_sync_ptr));
|
||||
if (hw->sync_ptr == NULL)
|
||||
return -ENOMEM;
|
||||
hw->mmap_status = &hw->sync_ptr->s.status;
|
||||
hw->mmap_control = &hw->sync_ptr->c.control;
|
||||
hw->mmap_status = &sync_ptr->s.status;
|
||||
hw->mmap_control = &sync_ptr->c.control;
|
||||
hw->sync_ptr_ioctl = 1;
|
||||
} else {
|
||||
hw->mmap_status = ptr;
|
||||
|
|
@ -894,7 +891,7 @@ static int map_control_data(snd_pcm_hw_t *hw)
|
|||
{
|
||||
void *ptr;
|
||||
int err;
|
||||
if (hw->sync_ptr == NULL) {
|
||||
if (hw->sync_ptr_ioctl == 0) {
|
||||
ptr = mmap(NULL, page_align(sizeof(struct snd_pcm_mmap_control)),
|
||||
PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
|
||||
hw->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL);
|
||||
|
|
@ -912,11 +909,18 @@ static int map_control_data(snd_pcm_hw_t *hw)
|
|||
static int map_status_and_control_data(snd_pcm_t *pcm, bool force_fallback)
|
||||
{
|
||||
snd_pcm_hw_t *hw = pcm->private_data;
|
||||
struct snd_pcm_sync_ptr *sync_ptr;
|
||||
int err;
|
||||
|
||||
/* Preparation for fallback to failure of mmap(2). */
|
||||
sync_ptr = malloc(sizeof(*sync_ptr));
|
||||
if (sync_ptr == NULL)
|
||||
return -ENOMEM;
|
||||
memset(sync_ptr, 0, sizeof(*sync_ptr));
|
||||
|
||||
hw->sync_ptr_ioctl = (int)force_fallback;
|
||||
|
||||
err = map_status_data(hw);
|
||||
err = map_status_data(hw, sync_ptr);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
@ -924,6 +928,14 @@ static int map_status_and_control_data(snd_pcm_t *pcm, bool force_fallback)
|
|||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Any fallback mode needs to keep the buffer. */
|
||||
if (hw->sync_ptr_ioctl == 0) {
|
||||
hw->sync_ptr = sync_ptr;
|
||||
} else {
|
||||
free(sync_ptr);
|
||||
hw->sync_ptr = NULL;
|
||||
}
|
||||
|
||||
/* Initialize the data. */
|
||||
hw->mmap_control->appl_ptr = 0;
|
||||
hw->mmap_control->avail_min = 1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue