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

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

commit f0f98c3d73f0f4deb707fc47d9d7a244d3247c6e
Author: hujun5 <huj...@xiaomi.com>
AuthorDate: Sun Apr 16 20:54:07 2023 +0800

    ostest:  fix smp ostest fail
    
    In SMP we need improve thread waiting strategy
    
    Signed-off-by: hujun5 <huj...@xiaomi.com>
---
 testing/ostest/cancel.c         | 30 +++++++++++++++++++++++++++---
 testing/ostest/cond.c           | 13 ++++++++++++-
 testing/ostest/pthread_rwlock.c |  9 +++++++++
 testing/ostest/sem.c            |  9 +++++++++
 testing/ostest/wqueue.c         |  7 ++++++-
 5 files changed, 63 insertions(+), 5 deletions(-)

diff --git a/testing/ostest/cancel.c b/testing/ostest/cancel.c
index 1db31c073..8f85d0e2d 100644
--- a/testing/ostest/cancel.c
+++ b/testing/ostest/cancel.c
@@ -33,6 +33,7 @@
 #include <stdio.h>
 #include <time.h>
 #include <unistd.h>
+#include <semaphore.h>
 
 #include "ostest.h"
 
@@ -42,6 +43,7 @@
 
 static pthread_mutex_t mutex;
 static pthread_cond_t  cond;
+static sem_t sem_thread_started;
 
 /****************************************************************************
  * Private Functions
@@ -80,6 +82,7 @@ static FAR void *sem_waiter(FAR void *parameter)
        ASSERT(false);
     }
 
+  sem_post(&sem_thread_started);
   printf("sem_waiter: Starting wait for condition\n");
 
   /* Are we a non-cancelable thread?   Yes, set the non-cancelable state */
@@ -428,6 +431,8 @@ void cancel_test(void)
   void *result;
   int status;
 
+  sem_init(&sem_thread_started, 0, 0);
+
   /* Test 1: Normal Cancel **************************************************/
 
   /* Start the waiter thread  */
@@ -440,7 +445,13 @@ void cancel_test(void)
    * make sure.
    */
 
-  usleep(75 * 1000);
+  sem_wait(&sem_thread_started);
+
+  /* Make sure sem_waiter run into pthread_cond_wait */
+
+  pthread_mutex_lock(&mutex);
+
+  pthread_mutex_unlock(&mutex);
 
   printf("cancel_test: Canceling thread\n");
   status = pthread_cancel(waiter);
@@ -561,7 +572,13 @@ void cancel_test(void)
    * bit to be certain.
    */
 
-  usleep(100 * 1000);
+  sem_wait(&sem_thread_started);
+
+  /* Make sure sem_waiter run into pthread_cond_wait */
+
+  pthread_mutex_lock(&mutex);
+
+  pthread_mutex_unlock(&mutex);
 
   printf("cancel_test: Canceling thread\n");
   status = pthread_cancel(waiter);
@@ -625,7 +642,13 @@ void cancel_test(void)
    * The cancellation should succeed, because the cancellation is pending.
    */
 
-  usleep(100 * 1000);
+  sem_wait(&sem_thread_started);
+
+  /* Make sure sem_waiter run into pthread_cond_wait */
+
+  pthread_mutex_lock(&mutex);
+
+  pthread_mutex_unlock(&mutex);
 
   printf("cancel_test: Canceling thread\n");
   status = pthread_cancel(waiter);
@@ -693,6 +716,7 @@ void cancel_test(void)
 
   printf("cancel_test: Test 6: Cancel message queue wait\n");
   printf("cancel_test: Starting thread (cancelable)\n");
+  sem_destroy(&sem_thread_started);
 
 #if !defined(CONFIG_DISABLE_MQUEUE) && defined(CONFIG_CANCELLATION_POINTS)
   /* Create the message queue */
diff --git a/testing/ostest/cond.c b/testing/ostest/cond.c
index a80a77c28..e6a805ce8 100644
--- a/testing/ostest/cond.c
+++ b/testing/ostest/cond.c
@@ -27,6 +27,7 @@
 #include <sched.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <semaphore.h>
 
 #include "ostest.h"
 
@@ -59,6 +60,7 @@ static int signaler_nloops = 0;
 static int signaler_already = 0;
 static int signaler_state = 0;
 static int signaler_nerrors = 0;
+static sem_t sem_thread_started;
 
 /****************************************************************************
  * Private Functions
@@ -78,6 +80,7 @@ static void *thread_waiter(void *parameter)
       status       = pthread_mutex_lock(&mutex);
       waiter_state = RUNNING;
 
+      sem_post(&sem_thread_started);
       if (status != 0)
         {
           printf("waiter_thread: "
@@ -219,7 +222,10 @@ static void *thread_signaler(void *parameter)
        * To avoid this situaltion, we add the following usleep()
        */
 
-      usleep(10 * 1000);
+      while (data_available == 1)
+        {
+          usleep(10 * 1000);
+        }
 #endif
 
       signaler_nloops++;
@@ -248,6 +254,8 @@ void cond_test(void)
   int prio_mid;
   int status;
 
+  sem_init(&sem_thread_started, 0, 0);
+
   /* Initialize the mutex */
 
   printf("cond_test: Initializing mutex\n");
@@ -302,6 +310,8 @@ void cond_test(void)
       printf("cond_test: pthread_create failed, status=%d\n", status);
     }
 
+  sem_wait(&sem_thread_started);
+
   printf("cond_test: Starting signaler\n");
   status = pthread_attr_init(&attr);
   if (status != 0)
@@ -338,6 +348,7 @@ void cond_test(void)
   printf("cond_test: signaler terminated, now cancel the waiter\n");
   pthread_detach(waiter);
   pthread_cancel(waiter);
+  sem_destroy(&sem_thread_started);
 
   printf("cond_test: \tWaiter\tSignaler\n");
   printf("cond_test: Loops\t%d\t%d\n", waiter_nloops, signaler_nloops);
diff --git a/testing/ostest/pthread_rwlock.c b/testing/ostest/pthread_rwlock.c
index 3c1bc7c3e..860d94c84 100644
--- a/testing/ostest/pthread_rwlock.c
+++ b/testing/ostest/pthread_rwlock.c
@@ -43,6 +43,7 @@ struct race_cond_s
  ****************************************************************************/
 
 static int g_race_cond_thread_pos;
+static sem_t g_sem_thread_started;
 
 /****************************************************************************
  * Private Functions
@@ -308,6 +309,7 @@ static FAR void *timeout_thread1(FAR void *data)
       ASSERT(false);
     }
 
+  sem_post(&g_sem_thread_started);
   sem_wait(rc->sem1);
 
   status = pthread_rwlock_unlock(rc->rw_lock);
@@ -408,6 +410,9 @@ static void test_timeout(void)
   rc.rw_lock = &rw_lock;
 
   status = pthread_create(&thread1, NULL, timeout_thread1, &rc);
+
+  status = sem_wait(&g_sem_thread_started);
+
   status = pthread_create(&thread2, NULL, timeout_thread2, &rc);
 
   pthread_join(thread1, NULL);
@@ -425,6 +430,8 @@ void pthread_rwlock_test(void)
 
   printf("pthread_rwlock: Initializing rwlock\n");
 
+  sem_init(&g_sem_thread_started, 0, 0);
+
   status = pthread_rwlock_init(&rw_lock, NULL);
   if (status != 0)
     {
@@ -489,4 +496,6 @@ void pthread_rwlock_test(void)
   test_two_threads();
 
   test_timeout();
+
+  sem_destroy(&g_sem_thread_started);
 }
diff --git a/testing/ostest/sem.c b/testing/ostest/sem.c
index cacb2fba3..a1107b20b 100644
--- a/testing/ostest/sem.c
+++ b/testing/ostest/sem.c
@@ -240,6 +240,15 @@ void sem_test(void)
       ASSERT(false);
     }
 
+  /* Make sure waiter_thread1 and waiter_thread2 in sem_wait */
+
+  do
+    {
+      sem_getvalue(&sem, &status);
+      usleep(10 * 1000L);
+    }
+  while (status != -2);
+
   printf("sem_test: Starting poster thread 3\n");
   status = pthread_attr_init(&attr);
   if (status != 0)
diff --git a/testing/ostest/wqueue.c b/testing/ostest/wqueue.c
index 2a313c4f2..f49cb5234 100644
--- a/testing/ostest/wqueue.c
+++ b/testing/ostest/wqueue.c
@@ -119,7 +119,12 @@ static FAR void *verifier(FAR void *arg)
 
   /* Wait for count workers to run. */
 
-  usleep(SLEEP_TIME);
+  do
+    {
+      usleep(SLEEP_TIME);
+      sem_getvalue(&call_sem, &call_count);
+    }
+  while (call_count != VERIFY_COUNT);
 
   sem_getvalue(&call_sem, &call_count);
   printf("wqueue_test: call = %d, expect = %d\n", call_count, VERIFY_COUNT);

Reply via email to