sim: To avoid system calls being interrupted when use host api
Signed-off-by: yintao <yintao@xiaomi.com>
This commit is contained in:
parent
6367f2469c
commit
9e43a4d31c
@ -33,6 +33,7 @@
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
#include "sim_internal.h"
|
||||
#include "sim_offload.h"
|
||||
|
||||
/****************************************************************************
|
||||
@ -161,40 +162,41 @@ static int sim_audio_config_format(struct sim_audio_s *priv, snd_pcm_t *pcm)
|
||||
break;
|
||||
}
|
||||
|
||||
ret = snd_pcm_hw_params_malloc(&hw_params);
|
||||
ret = host_uninterruptible(snd_pcm_hw_params_malloc, &hw_params);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_pcm_hw_params_any(pcm, hw_params);
|
||||
ret = host_uninterruptible(snd_pcm_hw_params_any, pcm, hw_params);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = snd_pcm_hw_params_set_access(pcm, hw_params,
|
||||
SND_PCM_ACCESS_RW_INTERLEAVED);
|
||||
ret = host_uninterruptible(snd_pcm_hw_params_set_access, pcm,
|
||||
hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = snd_pcm_hw_params_set_format(pcm, hw_params, format);
|
||||
ret = host_uninterruptible(snd_pcm_hw_params_set_format, pcm,
|
||||
hw_params, format);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = snd_pcm_hw_params_set_rate(pcm, hw_params,
|
||||
priv->sample_rate, 0);
|
||||
ret = host_uninterruptible(snd_pcm_hw_params_set_rate, pcm,
|
||||
hw_params, priv->sample_rate, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = snd_pcm_hw_params_set_channels(pcm, hw_params,
|
||||
priv->channels);
|
||||
ret = host_uninterruptible(snd_pcm_hw_params_set_channels, pcm,
|
||||
hw_params, priv->channels);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
@ -203,8 +205,8 @@ static int sim_audio_config_format(struct sim_audio_s *priv, snd_pcm_t *pcm)
|
||||
total_size = priv->nbuffers * priv->buffer_size;
|
||||
|
||||
pframes = priv->buffer_size / priv->frame_size;
|
||||
ret = snd_pcm_hw_params_set_period_size_near(pcm, hw_params,
|
||||
&pframes, NULL);
|
||||
ret = host_uninterruptible(snd_pcm_hw_params_set_period_size_near,
|
||||
pcm, hw_params, &pframes, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
@ -212,17 +214,17 @@ static int sim_audio_config_format(struct sim_audio_s *priv, snd_pcm_t *pcm)
|
||||
|
||||
priv->buffer_size = pframes * priv->frame_size;
|
||||
priv->nbuffers = total_size / priv->buffer_size;
|
||||
ret = snd_pcm_hw_params_set_periods_near(pcm, hw_params,
|
||||
&priv->nbuffers, NULL);
|
||||
ret = host_uninterruptible(snd_pcm_hw_params_set_periods_near, pcm,
|
||||
hw_params, &priv->nbuffers, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = snd_pcm_hw_params(pcm, hw_params);
|
||||
ret = host_uninterruptible(snd_pcm_hw_params, pcm, hw_params);
|
||||
|
||||
fail:
|
||||
snd_pcm_hw_params_free(hw_params);
|
||||
host_uninterruptible_no_return(snd_pcm_hw_params_free, hw_params);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -249,7 +251,6 @@ static void sim_audio_config_ops(struct sim_audio_s *priv, uint8_t fmt)
|
||||
|
||||
static int sim_audio_open(struct sim_audio_s *priv)
|
||||
{
|
||||
irqstate_t flags;
|
||||
snd_pcm_t *pcm = NULL;
|
||||
int direction;
|
||||
int ret;
|
||||
@ -259,15 +260,13 @@ static int sim_audio_open(struct sim_audio_s *priv)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
flags = up_irq_save();
|
||||
|
||||
direction = priv->playback ? SND_PCM_STREAM_PLAYBACK
|
||||
: SND_PCM_STREAM_CAPTURE;
|
||||
|
||||
ret = snd_pcm_open(&pcm, "default", direction, 0);
|
||||
ret = host_uninterruptible(snd_pcm_open, &pcm, "default", direction, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sim_audio_config_format(priv, pcm);
|
||||
@ -276,7 +275,7 @@ static int sim_audio_open(struct sim_audio_s *priv)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = snd_pcm_start(pcm);
|
||||
ret = host_uninterruptible(snd_pcm_start, pcm);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
@ -284,12 +283,12 @@ static int sim_audio_open(struct sim_audio_s *priv)
|
||||
|
||||
priv->pcm = pcm;
|
||||
|
||||
up_irq_restore(flags);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
snd_pcm_close(pcm);
|
||||
up_irq_restore(flags);
|
||||
host_uninterruptible(snd_pcm_close, pcm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -300,7 +299,7 @@ static int sim_audio_close(struct sim_audio_s *priv)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
snd_pcm_close(priv->pcm);
|
||||
host_uninterruptible(snd_pcm_close, priv->pcm);
|
||||
|
||||
priv->pcm = NULL;
|
||||
|
||||
@ -380,15 +379,17 @@ static int sim_audio_getcaps(struct audio_lowerhalf_s *dev, int type,
|
||||
switch (caps->ac_format.hw)
|
||||
{
|
||||
case AUDIO_FU_VOLUME:
|
||||
snd_mixer_selem_get_playback_volume(priv->volume,
|
||||
SND_MIXER_SCHN_UNKNOWN,
|
||||
&val);
|
||||
host_uninterruptible(snd_mixer_selem_get_playback_volume,
|
||||
priv->volume,
|
||||
SND_MIXER_SCHN_UNKNOWN,
|
||||
&val);
|
||||
caps->ac_controls.w = val;
|
||||
break;
|
||||
case AUDIO_FU_INP_GAIN:
|
||||
snd_mixer_selem_get_capture_volume(priv->volume,
|
||||
SND_MIXER_SCHN_MONO,
|
||||
&val);
|
||||
host_uninterruptible(snd_mixer_selem_get_capture_volume,
|
||||
priv->volume,
|
||||
SND_MIXER_SCHN_MONO,
|
||||
&val);
|
||||
caps->ac_controls.w = val;
|
||||
break;
|
||||
default:
|
||||
@ -430,12 +431,14 @@ static int sim_audio_configure(struct audio_lowerhalf_s *dev,
|
||||
switch (caps->ac_format.hw)
|
||||
{
|
||||
case AUDIO_FU_VOLUME:
|
||||
ret = snd_mixer_selem_set_playback_volume_all(priv->volume,
|
||||
caps->ac_controls.hw[0]);
|
||||
ret = host_uninterruptible(
|
||||
snd_mixer_selem_set_playback_volume_all,
|
||||
priv->volume, caps->ac_controls.hw[0]);
|
||||
break;
|
||||
case AUDIO_FU_INP_GAIN:
|
||||
ret = snd_mixer_selem_set_capture_volume_all(priv->volume,
|
||||
caps->ac_controls.hw[0]);
|
||||
ret = host_uninterruptible(
|
||||
snd_mixer_selem_set_capture_volume_all,
|
||||
priv->volume, caps->ac_controls.hw[0]);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
@ -632,7 +635,7 @@ static int sim_alsa_get_latency(struct audio_lowerhalf_s *dev,
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
ret = snd_pcm_delay(priv->pcm, latency);
|
||||
ret = host_uninterruptible(snd_pcm_delay, priv->pcm, latency);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
@ -817,7 +820,8 @@ static int sim_audio_process_playback(struct sim_audio_s *priv,
|
||||
|
||||
aux->curbyte += ret;
|
||||
|
||||
ret = snd_pcm_writei(priv->pcm, out, outsize / priv->frame_size);
|
||||
ret = host_uninterruptible(snd_pcm_writei, priv->pcm, out,
|
||||
outsize / priv->frame_size);
|
||||
ret *= priv->frame_size;
|
||||
}
|
||||
|
||||
@ -845,7 +849,8 @@ static int sim_audio_process_capture(struct sim_audio_s *priv,
|
||||
int frames = 0;
|
||||
int ret;
|
||||
|
||||
frames = snd_pcm_readi(priv->pcm, apb->samp, expect);
|
||||
frames = host_uninterruptible(snd_pcm_readi, priv->pcm,
|
||||
apb->samp, expect);
|
||||
if (frames < 0)
|
||||
{
|
||||
return frames;
|
||||
@ -927,7 +932,7 @@ static void sim_audio_process(struct sim_audio_s *priv)
|
||||
/ priv->frame_size;
|
||||
}
|
||||
|
||||
avail = snd_pcm_avail(priv->pcm);
|
||||
avail = host_uninterruptible(snd_pcm_avail, priv->pcm);
|
||||
if (avail < expect)
|
||||
{
|
||||
return;
|
||||
@ -973,7 +978,7 @@ static void sim_audio_process(struct sim_audio_s *priv)
|
||||
|
||||
if (final)
|
||||
{
|
||||
snd_pcm_drain(priv->pcm);
|
||||
host_uninterruptible(snd_pcm_drain, priv->pcm);
|
||||
#ifdef CONFIG_AUDIO_MULTI_SESSION
|
||||
sim_audio_stop(&priv->dev, NULL);
|
||||
#else
|
||||
@ -988,46 +993,47 @@ out:
|
||||
if (ret == -EPIPE)
|
||||
{
|
||||
awarn("ALSA buffer xrun.\n");
|
||||
snd_pcm_prepare(priv->pcm);
|
||||
snd_pcm_start(priv->pcm);
|
||||
host_uninterruptible(snd_pcm_prepare, priv->pcm);
|
||||
host_uninterruptible(snd_pcm_start, priv->pcm);
|
||||
}
|
||||
else if (ret != -EAGAIN)
|
||||
{
|
||||
aerr("pcm writei/readi failed %d, %s\n", ret, snd_strerror(ret));
|
||||
aerr("pcm writei/readi failed %d, %s\n", ret,
|
||||
host_uninterruptible(snd_strerror, ret));
|
||||
}
|
||||
}
|
||||
|
||||
static int sim_mixer_open(struct sim_audio_s *priv)
|
||||
{
|
||||
snd_mixer_selem_id_t *sid = NULL;
|
||||
irqstate_t flags = up_irq_save();
|
||||
int ret;
|
||||
|
||||
ret = snd_mixer_open(&priv->mixer, 0);
|
||||
ret = host_uninterruptible(snd_mixer_open, &priv->mixer, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = snd_mixer_attach(priv->mixer, "default");
|
||||
ret = host_uninterruptible(snd_mixer_attach, priv->mixer, "default");
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = snd_mixer_selem_register(priv->mixer, NULL, NULL);
|
||||
ret = host_uninterruptible(snd_mixer_selem_register,
|
||||
priv->mixer, NULL, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = snd_mixer_load(priv->mixer);
|
||||
ret = host_uninterruptible(snd_mixer_load, priv->mixer);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = snd_mixer_selem_id_malloc(&sid);
|
||||
ret = host_uninterruptible(snd_mixer_selem_id_malloc, &sid);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
@ -1035,17 +1041,20 @@ static int sim_mixer_open(struct sim_audio_s *priv)
|
||||
|
||||
if (priv->playback)
|
||||
{
|
||||
snd_mixer_selem_id_set_index(sid, 0);
|
||||
snd_mixer_selem_id_set_name(sid, "Master");
|
||||
host_uninterruptible_no_return(snd_mixer_selem_id_set_index, sid, 0);
|
||||
host_uninterruptible_no_return(snd_mixer_selem_id_set_name,
|
||||
sid, "Master");
|
||||
|
||||
priv->volume = snd_mixer_find_selem(priv->mixer, sid);
|
||||
snd_mixer_selem_id_free(sid);
|
||||
priv->volume = host_uninterruptible(snd_mixer_find_selem,
|
||||
priv->mixer, sid);
|
||||
host_uninterruptible_no_return(snd_mixer_selem_id_free, sid);
|
||||
if (!priv->volume)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = snd_mixer_selem_set_playback_volume_range(priv->volume, 0, 1000);
|
||||
ret = host_uninterruptible(snd_mixer_selem_set_playback_volume_range,
|
||||
priv->volume, 0, 1000);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
@ -1053,28 +1062,29 @@ static int sim_mixer_open(struct sim_audio_s *priv)
|
||||
}
|
||||
else
|
||||
{
|
||||
snd_mixer_selem_id_set_index(sid, 0);
|
||||
snd_mixer_selem_id_set_name(sid, "Capture");
|
||||
host_uninterruptible_no_return(snd_mixer_selem_id_set_index, sid, 0);
|
||||
host_uninterruptible_no_return(snd_mixer_selem_id_set_name,
|
||||
sid, "Capture");
|
||||
|
||||
priv->volume = snd_mixer_find_selem(priv->mixer, sid);
|
||||
snd_mixer_selem_id_free(sid);
|
||||
priv->volume = host_uninterruptible(snd_mixer_find_selem,
|
||||
priv->mixer, sid);
|
||||
host_uninterruptible_no_return(snd_mixer_selem_id_free, sid);
|
||||
if (!priv->volume)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = snd_mixer_selem_set_capture_volume_range(priv->volume, 0, 1000);
|
||||
ret = host_uninterruptible(snd_mixer_selem_set_capture_volume_range,
|
||||
priv->volume, 0, 1000);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
up_irq_restore(flags);
|
||||
return 0;
|
||||
fail:
|
||||
snd_mixer_close(priv->mixer);
|
||||
up_irq_restore(flags);
|
||||
host_uninterruptible(snd_mixer_close, priv->mixer);
|
||||
priv->mixer = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
@ -52,9 +52,6 @@ static atomic_int g_uordblks;
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
extern uint64_t up_irq_save(void);
|
||||
extern void up_irq_restore(uint64_t flags);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_allocheap
|
||||
*
|
||||
@ -65,21 +62,19 @@ extern void up_irq_restore(uint64_t flags);
|
||||
|
||||
void *host_allocheap(size_t sz)
|
||||
{
|
||||
uint64_t flags = up_irq_save();
|
||||
void *p;
|
||||
|
||||
#if defined(CONFIG_HOST_MACOS) && defined(CONFIG_HOST_ARM64)
|
||||
/* see: https://developer.apple.com/forums/thread/672804 */
|
||||
|
||||
p = mmap(NULL, sz, PROT_READ | PROT_WRITE,
|
||||
MAP_ANON | MAP_SHARED, -1, 0);
|
||||
p = host_uninterruptible(mmap, NULL, sz, PROT_READ | PROT_WRITE,
|
||||
MAP_ANON | MAP_SHARED, -1, 0);
|
||||
#else
|
||||
p = mmap(NULL, sz, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
p = host_uninterruptible(mmap, NULL, sz,
|
||||
PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
#endif
|
||||
|
||||
up_irq_restore(flags);
|
||||
|
||||
if (p == MAP_FAILED)
|
||||
{
|
||||
return NULL;
|
||||
@ -98,14 +93,11 @@ void *host_allocheap(size_t sz)
|
||||
|
||||
void host_freeheap(void *mem)
|
||||
{
|
||||
uint64_t flags = up_irq_save();
|
||||
munmap(mem, 0);
|
||||
up_irq_restore(flags);
|
||||
host_uninterruptible(munmap, mem, 0);
|
||||
}
|
||||
|
||||
void *host_allocshmem(const char *name, size_t size, int master)
|
||||
{
|
||||
uint64_t flags = up_irq_save();
|
||||
void *mem;
|
||||
int oflag;
|
||||
int ret;
|
||||
@ -117,10 +109,9 @@ void *host_allocshmem(const char *name, size_t size, int master)
|
||||
oflag |= O_CREAT | O_TRUNC;
|
||||
}
|
||||
|
||||
fd = shm_open(name, oflag, S_IRUSR | S_IWUSR);
|
||||
fd = host_uninterruptible(shm_open, name, oflag, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0)
|
||||
{
|
||||
up_irq_restore(flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -128,20 +119,19 @@ void *host_allocshmem(const char *name, size_t size, int master)
|
||||
{
|
||||
/* Avoid the second slave instance open successfully */
|
||||
|
||||
shm_unlink(name);
|
||||
host_uninterruptible(shm_unlink, name);
|
||||
}
|
||||
|
||||
ret = ftruncate(fd, size);
|
||||
ret = host_uninterruptible(ftruncate, fd, size);
|
||||
if (ret < 0)
|
||||
{
|
||||
up_irq_restore(flags);
|
||||
close(fd);
|
||||
host_uninterruptible(close, fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
close(fd); /* Don't need keep fd any more once the memory get mapped */
|
||||
up_irq_restore(flags);
|
||||
mem = host_uninterruptible(mmap, NULL, size,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
host_uninterruptible(close, fd); /* Don't need keep fd any more once the memory get mapped */
|
||||
if (mem == MAP_FAILED)
|
||||
{
|
||||
return NULL;
|
||||
@ -152,23 +142,20 @@ void *host_allocshmem(const char *name, size_t size, int master)
|
||||
|
||||
void host_freeshmem(void *mem)
|
||||
{
|
||||
uint64_t flags = up_irq_save();
|
||||
munmap(mem, 0);
|
||||
up_irq_restore(flags);
|
||||
host_uninterruptible(munmap, mem, 0);
|
||||
}
|
||||
|
||||
size_t host_mallocsize(void *mem)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
return malloc_size(mem);
|
||||
return host_uninterruptible(malloc_size, mem);
|
||||
#else
|
||||
return malloc_usable_size(mem);
|
||||
return host_uninterruptible(malloc_usable_size, mem);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *host_memalign(size_t alignment, size_t size)
|
||||
{
|
||||
uint64_t flags = up_irq_save();
|
||||
void *p;
|
||||
int error;
|
||||
|
||||
@ -177,18 +164,15 @@ void *host_memalign(size_t alignment, size_t size)
|
||||
alignment = sizeof(void *);
|
||||
}
|
||||
|
||||
error = posix_memalign(&p, alignment, size);
|
||||
error = host_uninterruptible(posix_memalign, &p, alignment, size);
|
||||
if (error != 0)
|
||||
{
|
||||
up_irq_restore(flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = host_mallocsize(p);
|
||||
g_aordblks += 1;
|
||||
g_uordblks += size;
|
||||
|
||||
up_irq_restore(flags);
|
||||
atomic_fetch_add(&g_aordblks, 1);
|
||||
atomic_fetch_add(&g_uordblks, size);
|
||||
|
||||
return p;
|
||||
}
|
||||
@ -196,24 +180,20 @@ void *host_memalign(size_t alignment, size_t size)
|
||||
void host_free(void *mem)
|
||||
{
|
||||
size_t size;
|
||||
uint64_t flags;
|
||||
|
||||
if (mem == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
flags = up_irq_save();
|
||||
size = host_mallocsize(mem);
|
||||
g_aordblks -= 1;
|
||||
g_uordblks -= size;
|
||||
free(mem);
|
||||
up_irq_restore(flags);
|
||||
atomic_fetch_sub(&g_aordblks, 1);
|
||||
atomic_fetch_sub(&g_uordblks, size);
|
||||
host_uninterruptible_no_return(free, mem);
|
||||
}
|
||||
|
||||
void *host_realloc(void *oldmem, size_t size)
|
||||
{
|
||||
uint64_t flags;
|
||||
size_t oldsize;
|
||||
void *mem;
|
||||
|
||||
@ -222,27 +202,21 @@ void *host_realloc(void *oldmem, size_t size)
|
||||
return host_memalign(sizeof(void *), size);
|
||||
}
|
||||
|
||||
flags = up_irq_save();
|
||||
|
||||
oldsize = host_mallocsize(oldmem);
|
||||
mem = realloc(oldmem, size);
|
||||
mem = host_uninterruptible(realloc, oldmem, size);
|
||||
if (mem == NULL)
|
||||
{
|
||||
up_irq_restore(flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = host_mallocsize(mem);
|
||||
g_uordblks -= oldsize;
|
||||
g_uordblks += size;
|
||||
|
||||
up_irq_restore(flags);
|
||||
atomic_fetch_add(&g_uordblks, size - oldsize);
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
void host_mallinfo(int *aordblks, int *uordblks)
|
||||
{
|
||||
*aordblks = g_aordblks;
|
||||
*uordblks = g_uordblks;
|
||||
*aordblks = atomic_load(&g_aordblks);
|
||||
*uordblks = atomic_load(&g_uordblks);
|
||||
}
|
||||
|
@ -52,8 +52,6 @@ void __gcov_dump(void);
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
extern uint64_t up_irq_save(void);
|
||||
extern void up_irq_restore(uint64_t flags);
|
||||
extern int backtrace(void **array, int size);
|
||||
|
||||
/****************************************************************************
|
||||
@ -68,19 +66,15 @@ extern int backtrace(void **array, int size);
|
||||
|
||||
void host_abort(int status)
|
||||
{
|
||||
uint64_t flags = up_irq_save();
|
||||
|
||||
#ifdef CONFIG_ARCH_COVERAGE
|
||||
/* Dump gcov data. */
|
||||
|
||||
__gcov_dump();
|
||||
host_uninterruptible_no_return(__gcov_dump);
|
||||
#endif
|
||||
|
||||
/* exit the simulation */
|
||||
|
||||
exit(status);
|
||||
|
||||
up_irq_restore(flags);
|
||||
host_uninterruptible_no_return(exit, status);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -99,13 +93,7 @@ int host_backtrace(void** array, int size)
|
||||
#ifdef CONFIG_WINDOWS_CYGWIN
|
||||
return 0;
|
||||
#else
|
||||
uint64_t flags = up_irq_save();
|
||||
int ret;
|
||||
|
||||
ret = backtrace(array, size);
|
||||
|
||||
up_irq_restore(flags);
|
||||
return ret;
|
||||
return host_uninterruptible(backtrace, array, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -130,7 +118,6 @@ int host_system(char *buf, size_t len, const char *fmt, ...)
|
||||
{
|
||||
FILE *fp;
|
||||
int ret;
|
||||
uint64_t flags;
|
||||
char cmd[512];
|
||||
va_list vars;
|
||||
|
||||
@ -144,21 +131,18 @@ int host_system(char *buf, size_t len, const char *fmt, ...)
|
||||
|
||||
if (buf == NULL)
|
||||
{
|
||||
ret = system(cmd);
|
||||
ret = host_uninterruptible(system, cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
flags = up_irq_save();
|
||||
fp = popen(cmd, "r");
|
||||
fp = host_uninterruptible(popen, cmd, "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
up_irq_restore(flags);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
ret = fread(buf, sizeof(char), len, fp);
|
||||
pclose(fp);
|
||||
up_irq_restore(flags);
|
||||
ret = host_uninterruptible(fread, buf, 1, len, fp);
|
||||
host_uninterruptible(pclose, fp);
|
||||
}
|
||||
|
||||
return ret < 0 ? -errno : ret;
|
||||
@ -178,10 +162,10 @@ void host_init_cwd(void)
|
||||
/* Get the absolute path of the executable file */
|
||||
|
||||
# ifdef CONFIG_HOST_LINUX
|
||||
len = readlink("/proc/self/exe", path, len);
|
||||
len = host_uninterruptible(readlink, "/proc/self/exe", path, len);
|
||||
if (len < 0)
|
||||
{
|
||||
perror("readlink failed");
|
||||
host_uninterruptible_no_return(perror, "readlink failed");
|
||||
return;
|
||||
}
|
||||
# else
|
||||
@ -195,7 +179,7 @@ void host_init_cwd(void)
|
||||
path[len] = '\0';
|
||||
name = strrchr(path, '/');
|
||||
*++name = '\0';
|
||||
chdir(path);
|
||||
host_uninterruptible(chdir, path);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -218,7 +202,8 @@ pid_t host_posix_spawn(const char *path,
|
||||
argv = default_argv;
|
||||
}
|
||||
|
||||
ret = posix_spawn(&pid, path, NULL, NULL, argv, envp);
|
||||
ret = host_uninterruptible(posix_spawn, &pid, path,
|
||||
NULL, NULL, argv, envp);
|
||||
return ret > 0 ? -ret : pid;
|
||||
}
|
||||
|
||||
@ -230,6 +215,6 @@ int host_waitpid(pid_t pid)
|
||||
{
|
||||
int status;
|
||||
|
||||
pid = waitpid(pid, &status, 0);
|
||||
pid = host_uninterruptible(waitpid, pid, &status, 0);
|
||||
return pid < 0 ? -errno : status;
|
||||
}
|
||||
|
@ -120,6 +120,27 @@
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define host_uninterruptible(func, ...) \
|
||||
({ \
|
||||
extern uint64_t up_irq_save(void); \
|
||||
extern void up_irq_restore(uint64_t flags); \
|
||||
uint64_t flags_ = up_irq_save(); \
|
||||
typeof(func(__VA_ARGS__)) ret_ = func(__VA_ARGS__); \
|
||||
up_irq_restore(flags_); \
|
||||
ret_; \
|
||||
})
|
||||
|
||||
#define host_uninterruptible_no_return(func, ...) \
|
||||
do \
|
||||
{ \
|
||||
extern uint64_t up_irq_save(void); \
|
||||
extern void up_irq_restore(uint64_t flags); \
|
||||
uint64_t flags_ = up_irq_save(); \
|
||||
func(__VA_ARGS__); \
|
||||
up_irq_restore(flags_); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* File System Definitions **************************************************/
|
||||
|
||||
/* These definitions characterize the compressed filesystem image */
|
||||
|
Loading…
Reference in New Issue
Block a user