This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new ac5b38c9e5 arch/sim: avoid host-call being interrupted before getting 
errno
ac5b38c9e5 is described below

commit ac5b38c9e545b5c51a199d0f98162b4206795ad2
Author: guanyi <gua...@xiaomi.com>
AuthorDate: Mon Apr 21 15:46:42 2025 +0800

    arch/sim: avoid host-call being interrupted before getting errno
    
    Sim use coroutine base on one thread in host to do switch context. but if 
we allow switch context with in one API (host-API and errno get), maybe the 
switch context from coroutine cause re-enter host-API call. Make the errno get 
behavior not work as expected.
    
    Signed-off-by: guanyi3 <guan...@xiaomi.com>
---
 arch/sim/src/sim/posix/sim_hostfs.c   | 161 +++++++---------------------------
 arch/sim/src/sim/posix/sim_hostmisc.c |  22 +++--
 arch/sim/src/sim/posix/sim_hostuart.c |  49 ++++-------
 arch/sim/src/sim/sim_internal.h       |  25 +++++-
 4 files changed, 83 insertions(+), 174 deletions(-)

diff --git a/arch/sim/src/sim/posix/sim_hostfs.c 
b/arch/sim/src/sim/posix/sim_hostfs.c
index 5ead9cdfb5..a22d7118d3 100644
--- a/arch/sim/src/sim/posix/sim_hostfs.c
+++ b/arch/sim/src/sim/posix/sim_hostfs.c
@@ -37,24 +37,12 @@
 #include <errno.h>
 
 #include "hostfs.h"
+#include "sim_internal.h"
 
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
 
-/****************************************************************************
- * Name: host_errno_convert
- ****************************************************************************/
-
-static int host_errno_convert(int errcode)
-{
-  /* Provide a common interface, which should have different conversions
-   * on different platforms.
-   */
-
-  return errcode;
-}
-
 /****************************************************************************
  * Name: host_stat_convert
  ****************************************************************************/
@@ -206,13 +194,7 @@ int host_open(const char *pathname, int flags, int mode)
       mapflags |= O_DIRECTORY;
     }
 
-  int ret = open(pathname, mapflags, mode);
-  if (ret == -1)
-    {
-      ret = host_errno_convert(-errno);
-    }
-
-  return ret;
+  return host_uninterruptible_errno(open, pathname, mapflags, mode);
 }
 
 /****************************************************************************
@@ -223,13 +205,7 @@ int host_close(int fd)
 {
   /* Just call the close routine */
 
-  int ret = close(fd);
-  if (ret == -1)
-    {
-      ret = host_errno_convert(-errno);
-    }
-
-  return ret;
+  return host_uninterruptible_errno(close, fd);
 }
 
 /****************************************************************************
@@ -240,13 +216,7 @@ nuttx_ssize_t host_read(int fd, void *buf, nuttx_size_t 
count)
 {
   /* Just call the read routine */
 
-  nuttx_ssize_t ret = read(fd, buf, count);
-  if (ret == -1)
-    {
-      ret = host_errno_convert(-errno);
-    }
-
-  return ret;
+  return host_uninterruptible_errno(read, fd, buf, count);
 }
 
 /****************************************************************************
@@ -257,13 +227,7 @@ nuttx_ssize_t host_write(int fd, const void *buf, 
nuttx_size_t count)
 {
   /* Just call the write routine */
 
-  nuttx_ssize_t ret = write(fd, buf, count);
-  if (ret == -1)
-    {
-      ret = host_errno_convert(-errno);
-    }
-
-  return ret;
+  return host_uninterruptible_errno(write, fd, buf, count);
 }
 
 /****************************************************************************
@@ -275,13 +239,7 @@ nuttx_off_t host_lseek(int fd, nuttx_off_t pos, 
nuttx_off_t offset,
 {
   /* Just call the lseek routine */
 
-  nuttx_off_t ret = lseek(fd, offset, whence);
-  if (ret == (nuttx_off_t)-1)
-    {
-      ret =  host_errno_convert(-errno);
-    }
-
-  return ret;
+  return host_uninterruptible_errno(lseek, fd, offset, whence);
 }
 
 /****************************************************************************
@@ -292,13 +250,7 @@ int host_ioctl(int fd, int request, unsigned long arg)
 {
   /* Just call the ioctl routine */
 
-  int ret = ioctl(fd, request, arg);
-  if (ret < 0)
-    {
-      ret = host_errno_convert(-errno);
-    }
-
-  return ret;
+  return host_uninterruptible_errno(ioctl, fd, request, arg);
 }
 
 /****************************************************************************
@@ -318,13 +270,7 @@ void host_sync(int fd)
 
 int host_dup(int fd)
 {
-  int ret = dup(fd);
-  if (ret < 0)
-    {
-      ret = host_errno_convert(-errno);
-    }
-
-  return ret;
+  return host_uninterruptible_errno(dup, fd);
 }
 
 /****************************************************************************
@@ -338,11 +284,7 @@ int host_fstat(int fd, struct nuttx_stat_s *buf)
 
   /* Call the host's stat routine */
 
-  ret = fstat(fd, &hostbuf);
-  if (ret < 0)
-    {
-      ret = host_errno_convert(-errno);
-    }
+  ret = host_uninterruptible_errno(fstat, fd, &hostbuf);
 
   /* Map the return values */
 
@@ -361,19 +303,19 @@ int host_fchstat(int fd, const struct nuttx_stat_s *buf, 
int flags)
 
   if (flags & NUTTX_CH_STAT_MODE)
     {
-      ret = fchmod(fd, buf->st_mode);
+      ret = host_uninterruptible_errno(fchmod, fd, buf->st_mode);
       if (ret < 0)
         {
-          return host_errno_convert(-errno);
+          return ret;
         }
     }
 
   if (flags & (NUTTX_CH_STAT_UID | NUTTX_CH_STAT_GID))
     {
-      ret = fchown(fd, buf->st_uid, buf->st_gid);
+      ret = host_uninterruptible_errno(fchown, fd, buf->st_uid, buf->st_gid);
       if (ret < 0)
         {
-          return host_errno_convert(-errno);
+          return ret;
         }
     }
 
@@ -401,10 +343,10 @@ int host_fchstat(int fd, const struct nuttx_stat_s *buf, 
int flags)
           times[1].tv_nsec = UTIME_OMIT;
         }
 
-      ret = futimens(fd, times);
+      ret = host_uninterruptible_errno(futimens, fd, times);
       if (ret < 0)
         {
-          return host_errno_convert(-errno);
+          return ret;
         }
     }
 
@@ -417,13 +359,7 @@ int host_fchstat(int fd, const struct nuttx_stat_s *buf, 
int flags)
 
 int host_ftruncate(int fd, nuttx_off_t length)
 {
-  int ret = ftruncate(fd, length);
-  if (ret < 0)
-    {
-      ret = host_errno_convert(-errno);
-    }
-
-  return ret;
+  return host_uninterruptible_errno(ftruncate, fd, length);
 }
 
 /****************************************************************************
@@ -513,13 +449,7 @@ void host_rewinddir(void *dirp)
 
 int host_closedir(void *dirp)
 {
-  int ret = closedir(dirp);
-  if (ret < 0)
-    {
-      ret = host_errno_convert(-errno);
-    }
-
-  return ret;
+  return host_uninterruptible_errno(closedir, dirp);
 }
 
 /****************************************************************************
@@ -533,11 +463,7 @@ int host_statfs(const char *path, struct nuttx_statfs_s 
*buf)
 
   /* Call the host's statfs routine */
 
-  ret = statvfs(path, &hostbuf);
-  if (ret < 0)
-    {
-      ret = host_errno_convert(-errno);
-    }
+  ret = host_uninterruptible_errno(statvfs, path, &hostbuf);
 
   /* Map the struct statfs value */
 
@@ -559,13 +485,7 @@ int host_statfs(const char *path, struct nuttx_statfs_s 
*buf)
 
 int host_unlink(const char *pathname)
 {
-  int ret = unlink(pathname);
-  if (ret < 0)
-    {
-      ret = host_errno_convert(-errno);
-    }
-
-  return ret;
+  return host_uninterruptible_errno(unlink, pathname);
 }
 
 /****************************************************************************
@@ -576,13 +496,7 @@ int host_mkdir(const char *pathname, int mode)
 {
   /* Just call the host's mkdir routine */
 
-  int ret = mkdir(pathname, mode);
-  if (ret < 0)
-    {
-      ret = host_errno_convert(-errno);
-    }
-
-  return ret;
+  return host_uninterruptible_errno(mkdir, pathname, mode);
 }
 
 /****************************************************************************
@@ -591,13 +505,7 @@ int host_mkdir(const char *pathname, int mode)
 
 int host_rmdir(const char *pathname)
 {
-  int ret = rmdir(pathname);
-  if (ret < 0)
-    {
-      ret = host_errno_convert(-errno);
-    }
-
-  return ret;
+  return host_uninterruptible_errno(rmdir, pathname);
 }
 
 /****************************************************************************
@@ -606,13 +514,7 @@ int host_rmdir(const char *pathname)
 
 int host_rename(const char *oldpath, const char *newpath)
 {
-  int ret = rename(oldpath, newpath);
-  if (ret < 0)
-    {
-      ret = host_errno_convert(-errno);
-    }
-
-  return ret;
+  return host_uninterruptible_errno(rename, oldpath, newpath);
 }
 
 /****************************************************************************
@@ -626,11 +528,7 @@ int host_stat(const char *path, struct nuttx_stat_s *buf)
 
   /* Call the host's stat routine */
 
-  ret = stat(path, &hostbuf);
-  if (ret < 0)
-    {
-      ret = host_errno_convert(-errno);
-    }
+  ret = host_uninterruptible_errno(stat, path, &hostbuf);
 
   /* Map the return values */
 
@@ -649,19 +547,20 @@ int host_chstat(const char *path, const struct 
nuttx_stat_s *buf, int flags)
 
   if (flags & NUTTX_CH_STAT_MODE)
     {
-      ret = chmod(path, buf->st_mode);
+      ret = host_uninterruptible_errno(chmod, path, buf->st_mode);
       if (ret < 0)
         {
-          return host_errno_convert(-errno);
+          return ret;
         }
     }
 
   if (flags & (NUTTX_CH_STAT_UID | NUTTX_CH_STAT_GID))
     {
-      ret = chown(path, buf->st_uid, buf->st_gid);
+      ret = host_uninterruptible_errno(chown, path,
+                                       buf->st_uid, buf->st_gid);
       if (ret < 0)
         {
-          return host_errno_convert(-errno);
+          return ret;
         }
     }
 
@@ -689,10 +588,10 @@ int host_chstat(const char *path, const struct 
nuttx_stat_s *buf, int flags)
           times[1].tv_nsec = UTIME_OMIT;
         }
 
-      ret = utimensat(AT_FDCWD, path, times, 0);
+      ret = host_uninterruptible_errno(utimensat, AT_FDCWD, path, times, 0);
       if (ret < 0)
         {
-          return host_errno_convert(-errno);
+          return ret;
         }
     }
 
diff --git a/arch/sim/src/sim/posix/sim_hostmisc.c 
b/arch/sim/src/sim/posix/sim_hostmisc.c
index d759f1f57c..6015af0701 100644
--- a/arch/sim/src/sim/posix/sim_hostmisc.c
+++ b/arch/sim/src/sim/posix/sim_hostmisc.c
@@ -128,32 +128,38 @@ int host_system(char *buf, size_t len, const char *fmt, 
...)
   int ret;
   char cmd[512];
   va_list vars;
+  uint64_t flags;
 
   va_start(vars, fmt);
-  ret = vsnprintf(cmd, sizeof(cmd), fmt, vars);
+  ret = host_uninterruptible_errno(vsnprintf, cmd, sizeof(cmd), fmt, vars);
   va_end(vars);
   if (ret <= 0 || ret > sizeof(cmd))
     {
-      return ret < 0 ? -errno : -EINVAL;
+      return ret < 0 ? ret : -EINVAL;
     }
 
   if (buf == NULL)
     {
-      ret = host_uninterruptible(system, cmd);
+      ret = host_uninterruptible_errno(system, cmd);
     }
   else
     {
+      flags = up_irq_save();
       fp = host_uninterruptible(popen, cmd, "r");
       if (fp == NULL)
         {
-          return -errno;
+          ret = -errno;
+          up_irq_restore(flags);
+          return ret;
         }
 
-      ret = host_uninterruptible(fread, buf, 1, len, fp);
+      up_irq_restore(flags);
+
+      ret = host_uninterruptible_errno(fread, buf, 1, len, fp);
       host_uninterruptible(pclose, fp);
     }
 
-  return ret < 0 ? -errno : ret;
+  return ret;
 }
 
 /****************************************************************************
@@ -223,6 +229,6 @@ int host_waitpid(pid_t pid)
 {
   int status;
 
-  pid = host_uninterruptible(waitpid, pid, &status, 0);
-  return pid < 0 ? -errno : status;
+  pid = host_uninterruptible_errno(waitpid, pid, &status, 0);
+  return pid < 0 ? pid : status;
 }
diff --git a/arch/sim/src/sim/posix/sim_hostuart.c 
b/arch/sim/src/sim/posix/sim_hostuart.c
index facc21e467..12f1965895 100644
--- a/arch/sim/src/sim/posix/sim_hostuart.c
+++ b/arch/sim/src/sim/posix/sim_hostuart.c
@@ -96,15 +96,15 @@ void host_uart_start(void)
 {
   /* Get the current stdin terminal mode */
 
-  tcgetattr(0, &g_cooked);
+  host_uninterruptible_no_return(tcgetattr, 0, &g_cooked);
 
   /* Put stdin into raw mode */
 
-  setrawmode(0);
+  host_uninterruptible_no_return(setrawmode, 0);
 
   /* Restore the original terminal mode before exit */
 
-  atexit(restoremode);
+  host_uninterruptible_no_return(atexit, restoremode);
 }
 
 /****************************************************************************
@@ -115,16 +115,12 @@ int host_uart_open(const char *pathname)
 {
   int fd;
 
-  fd = open(pathname, O_RDWR | O_NONBLOCK);
+  fd = host_uninterruptible_errno(open, pathname, O_RDWR | O_NONBLOCK);
   if (fd >= 0)
     {
       /* keep raw mode */
 
-      setrawmode(fd);
-    }
-  else
-    {
-      fd = -errno;
+      host_uninterruptible_no_return(setrawmode, fd);
     }
 
   return fd;
@@ -136,7 +132,7 @@ int host_uart_open(const char *pathname)
 
 void host_uart_close(int fd)
 {
-  close(fd);
+  host_uninterruptible(close, fd);
 }
 
 /****************************************************************************
@@ -149,11 +145,11 @@ int host_uart_puts(int fd, const char *buf, size_t size)
 
   do
     {
-      ret = write(fd, buf, size);
+      ret = host_uninterruptible_errno(write, fd, buf, size);
     }
-  while (ret < 0 && errno == EINTR);
+  while (ret < 0 && ret == -EINTR);
 
-  return ret < 0 ? -errno : ret;
+  return ret;
 }
 
 /****************************************************************************
@@ -166,11 +162,11 @@ int host_uart_gets(int fd, char *buf, size_t size)
 
   do
     {
-      ret = read(fd, buf, size);
+      ret = host_uninterruptible_errno(read, fd, buf, size);
     }
-  while (ret < 0 && errno == EINTR);
+  while (ret < 0 && ret == -EINTR);
 
-  return ret < 0 ? -errno : ret;
+  return ret;
 }
 
 /****************************************************************************
@@ -182,12 +178,8 @@ int host_uart_getcflag(int fd, unsigned int *cflag)
   struct termios t;
   int ret;
 
-  ret = tcgetattr(fd, &t);
-  if (ret < 0)
-    {
-      ret = -errno;
-    }
-  else
+  ret = host_uninterruptible_errno(tcgetattr, fd, &t);
+  if (ret >= 0)
     {
       *cflag = t.c_cflag;
     }
@@ -204,16 +196,11 @@ int host_uart_setcflag(int fd, unsigned int cflag)
   struct termios t;
   int ret;
 
-  ret = tcgetattr(fd, &t);
+  ret = host_uninterruptible_errno(tcgetattr, fd, &t);
   if (!ret)
     {
       t.c_cflag = cflag;
-      ret = tcsetattr(fd, TCSANOW, &t);
-    }
-
-  if (ret < 0)
-    {
-      ret = -errno;
+      ret = host_uninterruptible_errno(tcsetattr, fd, TCSANOW, &t);
     }
 
   return ret;
@@ -229,7 +216,7 @@ bool host_uart_checkin(int fd)
 
   pfd.fd     = fd;
   pfd.events = POLLIN;
-  return poll(&pfd, 1, 0) == 1;
+  return host_uninterruptible(poll, &pfd, 1, 0) == 1;
 }
 
 /****************************************************************************
@@ -242,7 +229,7 @@ bool host_uart_checkout(int fd)
 
   pfd.fd     = fd;
   pfd.events = POLLOUT;
-  return poll(&pfd, 1, 0) == 1;
+  return host_uninterruptible(poll, &pfd, 1, 0) == 1;
 }
 
 /****************************************************************************
diff --git a/arch/sim/src/sim/sim_internal.h b/arch/sim/src/sim/sim_internal.h
index aead67c564..f902098bd4 100644
--- a/arch/sim/src/sim/sim_internal.h
+++ b/arch/sim/src/sim/sim_internal.h
@@ -107,6 +107,12 @@
 #define sim_savestate(regs) sim_copyfullstate(regs, up_current_regs())
 #define sim_restorestate(regs) up_set_current_regs(regs)
 
+/* Provide a common interface, which should have different conversions
+ * on different platforms.
+ */
+
+#define host_errno_convert(errcode) (errcode)
+
 #define sim_saveusercontext(saveregs, ret)                      \
     do                                                          \
       {                                                         \
@@ -134,8 +140,6 @@
 
 #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_);                                 \
@@ -145,14 +149,24 @@
 #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)
 
+#define host_uninterruptible_errno(func, ...)                   \
+    ({                                                          \
+        uint64_t flags_ = up_irq_save();                        \
+        typeof(func(__VA_ARGS__)) ret_ = func(__VA_ARGS__);     \
+        if (ret_ < 0)                                           \
+          {                                                     \
+            ret_ = host_errno_convert(-errno);                  \
+          }                                                     \
+        up_irq_restore(flags_);                                 \
+        ret_;                                                   \
+    })
+
 /* File System Definitions **************************************************/
 
 /* These definitions characterize the compressed filesystem image */
@@ -204,6 +218,9 @@ extern char **g_argv;
  * Public Function Prototypes
  ****************************************************************************/
 
+uint64_t up_irq_save(void);
+void up_irq_restore(uint64_t flags);
+
 /* Context switching */
 
 void sim_copyfullstate(xcpt_reg_t *dest, xcpt_reg_t *src);

Reply via email to