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

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


The following commit(s) were added to refs/heads/master by this push:
     new ba075747b ostest: Add initial support for CONFIG_BUILD_KERNEL
ba075747b is described below

commit ba075747be4bbd8b9a2a2f86a02593d4a5a40413
Author: fangxinyong <fangxiny...@xiaomi.com>
AuthorDate: Tue Nov 14 18:46:17 2023 +0800

    ostest: Add initial support for CONFIG_BUILD_KERNEL
    
    task_* APIs are unavailable in kernel build mode, replacing with
    posix_spawn or pthread_* API to pass the case. But posix_spawn requires
    some dependency, for example CONFIG_BUILTIN and CONFIG_LIBC_EXECFUNCS,
    so pthread_* APIs are used in most scenarios. Some tests should be
    re-visited because the intent is to user another task (in this case
    another process) to e.g. receive signals.
    That will require quite a bit of extra work.
    
    Tests that had to be disabled:
    - restart: task_restart() does not work at all with kernel mode so it is
      disabled entirely
    - fpu: make sure the FPU test is not even attempted, because it will cause
      ASSERT() and stop the test
    - vfork: vfork() does not work for some reason in CONFIG_BUILD_KERNEL,
      there is something missing on the kernel side, so just disable the test 
for now
    
    Tests that should be re-visited:
    - The signal tests, now they signal the process itself while before the
      signal was sent to another task. This will require building the part
      that receives the signal as a separate process
    - waitpid: Like stated above, waitpid does not work for pthreads
    - suspend: kill to send signal does not work for pthreads
    
    Signed-off-by: fangxinyong <fangxiny...@xiaomi.com>
    Co-authored-by: Ville Juven <ville.ju...@unikie.com>
---
 testing/ostest/ostest.h       |  2 ++
 testing/ostest/ostest_main.c  | 53 +++++++++++++++++++++++++++++++++++++++----
 testing/ostest/pthread_exit.c | 27 ++++++++++++++--------
 testing/ostest/restart.c      |  4 ++++
 testing/ostest/sighand.c      | 13 +++++++----
 testing/ostest/signest.c      | 40 +++++++++++++++++---------------
 testing/ostest/suspend.c      |  7 ++++++
 testing/ostest/waitpid.c      |  8 +++++--
 8 files changed, 116 insertions(+), 38 deletions(-)

diff --git a/testing/ostest/ostest.h b/testing/ostest/ostest.h
index afc62b78a..e169f4b71 100644
--- a/testing/ostest/ostest.h
+++ b/testing/ostest/ostest.h
@@ -115,7 +115,9 @@ void aio_test(void);
 
 /* restart.c ****************************************************************/
 
+#ifndef CONFIG_BUILD_KERNEL
 void restart_test(void);
+#endif
 
 /* waitpid.c ****************************************************************/
 
diff --git a/testing/ostest/ostest_main.c b/testing/ostest/ostest_main.c
index dbd28e4d5..c856aea40 100644
--- a/testing/ostest/ostest_main.c
+++ b/testing/ostest/ostest_main.c
@@ -339,7 +339,8 @@ static int user_main(int argc, char *argv[])
       check_test_memory_usage();
 #endif
 
-#if defined(CONFIG_ARCH_FPU) && !defined(CONFIG_TESTING_OSTEST_FPUTESTDISABLE)
+#if defined(CONFIG_ARCH_FPU) && !defined(CONFIG_TESTING_OSTEST_FPUTESTDISABLE) 
&& \
+    !defined(CONFIG_BUILD_KERNEL)
       /* Check that the FPU is properly supported during context switching */
 
       printf("\nuser_main: FPU test\n");
@@ -347,13 +348,15 @@ static int user_main(int argc, char *argv[])
       check_test_memory_usage();
 #endif
 
+#ifndef CONFIG_BUILD_KERNEL
       /* Checkout task_restart() */
 
       printf("\nuser_main: task_restart test\n");
       restart_test();
       check_test_memory_usage();
+#endif
 
-#ifdef CONFIG_SCHED_WAITPID
+#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_BUILD_KERNEL)
       /* Check waitpid() and friends */
 
       printf("\nuser_main: waitpid test\n");
@@ -508,7 +511,8 @@ static int user_main(int argc, char *argv[])
       signest_test();
       check_test_memory_usage();
 
-#if defined(CONFIG_SIG_SIGSTOP_ACTION) && defined(CONFIG_SIG_SIGKILL_ACTION)
+#if defined(CONFIG_SIG_SIGSTOP_ACTION) && defined(CONFIG_SIG_SIGKILL_ACTION) 
&& \
+    !defined(CONFIG_BUILD_KERNEL)
       printf("\nuser_main: signal action test\n");
       suspend_test();
       check_test_memory_usage();
@@ -581,8 +585,16 @@ static int user_main(int argc, char *argv[])
 #endif
 
 #if defined(CONFIG_ARCH_HAVE_FORK) && defined(CONFIG_SCHED_WAITPID)
+#ifndef CONFIG_BUILD_KERNEL
       printf("\nuser_main: vfork() test\n");
       vfork_test();
+#else
+      /* REVISIT: The issue with vfork() is on the kernel side, fix the issue
+       * and re-enable this test with CONFIG_BUILD_KERNEL
+       */
+
+      printf("\nuser_main: vfork() test DISABLED (CONFIG_BUILD_KERNEL)\n");
+#endif
 #endif
 
 #ifdef CONFIG_SMP_CALL
@@ -635,13 +647,36 @@ static void stdio_test(void)
 
 int main(int argc, FAR char **argv)
 {
-  int result;
 #ifdef CONFIG_TESTING_OSTEST_WAITRESULT
   int ostest_result = ERROR;
 #else
   int ostest_result = OK;
 #endif
 
+#ifndef CONFIG_BUILD_KERNEL
+  int result;
+#else
+  struct sched_param param;
+  posix_spawnattr_t attr;
+  FAR const char * const arg[7] =
+  {
+    argv[0], "user_main", arg1, arg2, arg3, arg4, NULL
+  };
+
+  pid_t result;
+  int status;
+
+  /* Use posix_spawn API to spawn the new task for tests, should re-enter
+   * the main entry in new task, the second arg as to identify the real
+   * entry point of the test tasks.
+   */
+
+  if (argc >= 2 && strcmp(argv[1], "user_main") == 0)
+    {
+      return user_main(argc - 1 , &argv[1]);
+    }
+#endif
+
   /* Verify that stdio works first */
 
   stdio_test();
@@ -680,9 +715,19 @@ int main(int argc, FAR char **argv)
 
   /* Verify that we can spawn a new task */
 
+#ifdef CONFIG_BUILD_KERNEL
+  posix_spawnattr_init(&attr);
+  param.sched_priority = PRIORITY;
+  posix_spawnattr_setschedparam(&attr, &param);
+  posix_spawnattr_setstacksize(&attr, STACKSIZE);
+  status = posix_spawn(&result, arg[0], NULL, &attr,
+                       (char * const *)arg, NULL);
+  if (status != 0)
+#else
   result = task_create("ostest", PRIORITY, STACKSIZE, user_main,
                        (FAR char * const *)g_argv);
   if (result == ERROR)
+#endif
     {
       printf("ostest_main: ERROR Failed to start user_main\n");
       ASSERT(false);
diff --git a/testing/ostest/pthread_exit.c b/testing/ostest/pthread_exit.c
index a16d2a6ca..179a659aa 100644
--- a/testing/ostest/pthread_exit.c
+++ b/testing/ostest/pthread_exit.c
@@ -44,7 +44,7 @@
  * Private Functions
  ****************************************************************************/
 
-static void *pthread_exit_thread(FAR void *parameter)
+static FAR void *pthread_exit_thread(FAR void *parameter)
 {
   unsigned me = (unsigned)pthread_self();
 
@@ -56,7 +56,7 @@ static void *pthread_exit_thread(FAR void *parameter)
   return NULL;
 }
 
-static int pthread_exit_main(int argc, char **argv)
+static FAR void *pthread_exit_main(FAR void *arg)
 {
   pthread_t child;
 #ifdef SDCC
@@ -87,7 +87,7 @@ static int pthread_exit_main(int argc, char **argv)
   printf("pthread_exit_main %u: ERROR:  Still running\n", me);
   exit(0);
 
-  return 0;
+  return NULL;
 }
 
 /****************************************************************************
@@ -96,20 +96,29 @@ static int pthread_exit_main(int argc, char **argv)
 
 void pthread_exit_test(void)
 {
-  int statloc;
+  struct sched_param param;
+  pthread_attr_t attr;
+  pid_t pid;
   int ret;
 
-  ret = task_create("pthread_exit", PRIORITY, STACKSIZE, pthread_exit_main,
-                    NULL);
+  pthread_attr_init(&attr);
+  param.sched_priority = PRIORITY;
+  pthread_attr_setschedparam(&attr, &param);
+  pthread_attr_setstacksize(&attr, STACKSIZE);
+  ret = pthread_create(&pid, &attr, pthread_exit_main, NULL);
   if (ret < 0)
     {
-      printf("pthread_exit_test:  ERROR task_create Failed\n");
+      printf("pthread_exit_test:  ERROR pthread_create Failed\n");
     }
   else
     {
       printf("pthread_exit_test: Started pthread_exit_main at PID=%d\n",
-             ret);
-      waitpid((pid_t)ret, &statloc, 0);
+             pid);
+      if (pthread_join(pid, NULL) != 0)
+        {
+          printf("pthread_exit_test: ERROR Failed to join to terminate\n");
+          ASSERT(false);
+        };
     }
 }
 
diff --git a/testing/ostest/restart.c b/testing/ostest/restart.c
index 76c637464..ecd336dac 100644
--- a/testing/ostest/restart.c
+++ b/testing/ostest/restart.c
@@ -36,6 +36,8 @@
 
 #include "ostest.h"
 
+#ifndef CONFIG_BUILD_KERNEL
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
@@ -225,3 +227,5 @@ void restart_test(void)
 
   printf("restart_main: Exiting\n");
 }
+
+#endif /* !CONFIG_BUILD_KERNEL */
diff --git a/testing/ostest/sighand.c b/testing/ostest/sighand.c
index 82093a11d..72b653890 100644
--- a/testing/ostest/sighand.c
+++ b/testing/ostest/sighand.c
@@ -128,7 +128,7 @@ static void wakeup_action(int signo, siginfo_t *info, void 
*ucontext)
     }
 }
 
-static int waiter_main(int argc, char *argv[])
+static FAR void *waiter_main(FAR void *arg)
 {
   sigset_t set;
   struct sigaction act;
@@ -218,6 +218,7 @@ void sighand_test(void)
   sigset_t set;
 #endif
   struct sched_param param;
+  pthread_attr_t attr;
   union sigval sigvalue;
   pid_t waiterpid;
   int status;
@@ -265,9 +266,11 @@ void sighand_test(void)
       param.sched_priority = PTHREAD_DEFAULT_PRIORITY;
     }
 
-  waiterpid = task_create("waiter", param.sched_priority,
-                           STACKSIZE, waiter_main, NULL);
-  if (waiterpid == ERROR)
+  pthread_attr_init(&attr);
+  pthread_attr_setschedparam(&attr, &param);
+  pthread_attr_setstacksize(&attr, STACKSIZE);
+  status = pthread_create(&waiterpid, &attr, waiter_main, NULL);
+  if (status != 0)
     {
       printf("sighand_test: ERROR failed to start waiter_main\n");
       ASSERT(false);
@@ -293,7 +296,7 @@ void sighand_test(void)
     {
       printf("sighand_test: ERROR sigqueue failed\n");
       ASSERT(false);
-      task_delete(waiterpid);
+      pthread_cancel(waiterpid);
     }
 
   /* Wait a bit */
diff --git a/testing/ostest/signest.c b/testing/ostest/signest.c
index a6ca0c98e..59a801750 100644
--- a/testing/ostest/signest.c
+++ b/testing/ostest/signest.c
@@ -94,7 +94,6 @@ static void waiter_action(int signo)
 
   sched_lock();
   nest_level = g_nest_level++;
-  sched_unlock();
 
   if ((signo & 1) != 0)
     {
@@ -114,11 +113,12 @@ static void waiter_action(int signo)
     }
 
   g_nest_level = nest_level;
+  sched_unlock();
 
   sem_post(&g_sem_signal_finish);
 }
 
-static int waiter_main(int argc, char *argv[])
+static FAR void *waiter_main(FAR void *arg)
 {
   sigset_t set;
   struct sigaction act;
@@ -134,7 +134,7 @@ static int waiter_main(int argc, char *argv[])
     {
       printf("waiter_main: ERROR sigprocmask failed: %d\n", errno);
       ASSERT(false);
-      return EXIT_FAILURE;
+      return NULL;
     }
 
   printf("waiter_main: Registering signal handler\n");
@@ -160,7 +160,7 @@ static int waiter_main(int argc, char *argv[])
             {
               printf("waiter_main: WARNING sigaction failed with %d\n",
                      errno);
-              return EXIT_FAILURE;
+              return NULL;
             }
         }
     }
@@ -180,10 +180,10 @@ static int waiter_main(int argc, char *argv[])
   /* Just exit, the system should clean up the signal handlers */
 
   g_waiter_running = false;
-  return EXIT_SUCCESS;
+  return NULL;
 }
 
-static int interfere_main(int argc, char *argv[])
+static FAR void *interfere_main(FAR void *arg)
 {
   /* Now just loop staying in the way as much as possible */
 
@@ -202,7 +202,7 @@ static int interfere_main(int argc, char *argv[])
   return EXIT_SUCCESS;
 }
 
-void wait_finish(int pid, int sig)
+static void wait_finish(int pid, int sig)
 {
   struct timespec ts;
   int wait_times;
@@ -239,6 +239,7 @@ void wait_finish(int pid, int sig)
 void signest_test(void)
 {
   struct sched_param param;
+  pthread_attr_t attr;
   pid_t waiterpid;
   pid_t interferepid;
   int total_signals;
@@ -246,7 +247,6 @@ void signest_test(void)
   int total_nested;
   int even_signals;
   int odd_signals;
-  int prio;
   int ret;
   int i;
   int j;
@@ -280,11 +280,14 @@ void signest_test(void)
 
   /* Start waiter thread  */
 
-  prio = param.sched_priority + 1;
-  printf("signest_test: Starting signal waiter task at priority %d\n", prio);
-  waiterpid = task_create("waiter", prio, STACKSIZE,
-                          waiter_main, NULL);
-  if (waiterpid == ERROR)
+  param.sched_priority++;
+  printf("signest_test: Starting signal waiter task at priority %d\n",
+         param.sched_priority);
+  pthread_attr_init(&attr);
+  pthread_attr_setschedparam(&attr, &param);
+  pthread_attr_setstacksize(&attr, STACKSIZE);
+  ret = pthread_create(&waiterpid, &attr, waiter_main, NULL);
+  if (ret != 0)
     {
       printf("signest_test: ERROR failed to start waiter_main\n");
       ASSERT(false);
@@ -295,11 +298,12 @@ void signest_test(void)
 
   /* Start interfering thread  */
 
-  prio++;
-  printf("signest_test: Starting interfering task at priority %d\n", prio);
-  interferepid = task_create("interfere", prio, STACKSIZE,
-                             interfere_main, NULL);
-  if (interferepid == ERROR)
+  param.sched_priority++;
+  printf("signest_test: Starting interfering task at priority %d\n",
+         param.sched_priority);
+  pthread_attr_setschedparam(&attr, &param);
+  ret = pthread_create(&interferepid, &attr, interfere_main, NULL);
+  if (ret != 0)
     {
       printf("signest_test: ERROR failed to start interfere_main\n");
       ASSERT(false);
diff --git a/testing/ostest/suspend.c b/testing/ostest/suspend.c
index ea640fbb1..16181fc48 100644
--- a/testing/ostest/suspend.c
+++ b/testing/ostest/suspend.c
@@ -37,6 +37,12 @@
 
 #include "ostest.h"
 
+/* REVISIT: This could be implemented for CONFIG_BUILD_KERNEL as well, by
+ * starting a new process instead of using task_create()
+ */
+
+#ifndef CONFIG_BUILD_KERNEL
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -136,3 +142,4 @@ void suspend_test(void)
   printf("suspend_test: done\n");
   FFLUSH();
 }
+#endif /* !CONFIG_BUILD_KERNEL */
diff --git a/testing/ostest/waitpid.c b/testing/ostest/waitpid.c
index 02709ade9..758ffcf9f 100644
--- a/testing/ostest/waitpid.c
+++ b/testing/ostest/waitpid.c
@@ -35,7 +35,11 @@
 
 #include "ostest.h"
 
-#ifdef CONFIG_SCHED_WAITPID
+/* REVISIT: This could be implemented for CONFIG_BUILD_KERNEL as well, by
+ * starting a new process instead of using task_create()
+ */
+
+#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_BUILD_KERNEL)
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -392,4 +396,4 @@ int waitpid_test(void)
   return 0;
 }
 
-#endif /* CONFIG_SCHED_WAITPID */
+#endif /* defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_BUILD_KERNEL) */

Reply via email to