diff --git a/arch/sim/src/sim/posix/sim_alsa.c b/arch/sim/src/sim/posix/sim_alsa.c index 366d74bfe8..9fc1e148b4 100644 --- a/arch/sim/src/sim/posix/sim_alsa.c +++ b/arch/sim/src/sim/posix/sim_alsa.c @@ -33,6 +33,7 @@ #include +#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; } diff --git a/arch/sim/src/sim/posix/sim_hostmemory.c b/arch/sim/src/sim/posix/sim_hostmemory.c index 3ba3adb97e..cc651cb46e 100644 --- a/arch/sim/src/sim/posix/sim_hostmemory.c +++ b/arch/sim/src/sim/posix/sim_hostmemory.c @@ -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); } diff --git a/arch/sim/src/sim/posix/sim_hostmisc.c b/arch/sim/src/sim/posix/sim_hostmisc.c index b23403c24c..a1856b8d47 100644 --- a/arch/sim/src/sim/posix/sim_hostmisc.c +++ b/arch/sim/src/sim/posix/sim_hostmisc.c @@ -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; } diff --git a/arch/sim/src/sim/sim_internal.h b/arch/sim/src/sim/sim_internal.h index c62b78d538..0364514614 100644 --- a/arch/sim/src/sim/sim_internal.h +++ b/arch/sim/src/sim/sim_internal.h @@ -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 */