Module: xenomai-2.5
Branch: master
Commit: c592930c80b25d537dd27b4388d1a3a502a21672
URL:    
http://git.xenomai.org/?p=xenomai-2.5.git;a=commit;h=c592930c80b25d537dd27b4388d1a3a502a21672

Author: Jan Kiszka <jan.kis...@siemens.com>
Date:   Tue Mar  2 22:35:13 2010 +0100

testsuite: Add timed mutex test

Add test for timeouts while waiting on a mutexe. At this chance, also
tag the output on errors more clearly.

Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>

---

 src/testsuite/unit/mutex-torture.c |  133 ++++++++++++++++++++++++++++--------
 1 files changed, 104 insertions(+), 29 deletions(-)

diff --git a/src/testsuite/unit/mutex-torture.c 
b/src/testsuite/unit/mutex-torture.c
index ebdd4f2..ebcb882 100644
--- a/src/testsuite/unit/mutex-torture.c
+++ b/src/testsuite/unit/mutex-torture.c
@@ -27,17 +27,18 @@
 #include <asm-generic/bits/current.h> /* For internal use, do not use
                                         in your code. */
 
-#define MUTEX_CREATE   1
-#define MUTEX_LOCK     2
-#define MUTEX_TRYLOCK  3
-#define MUTEX_UNLOCK   4
-#define MUTEX_DESTROY  5
-#define COND_CREATE    6
-#define COND_SIGNAL    7
-#define COND_WAIT      8
-#define COND_DESTROY   9
-#define THREAD_DETACH  10
-#define THREAD_CREATE  11
+#define MUTEX_CREATE           1
+#define MUTEX_LOCK             2
+#define MUTEX_TRYLOCK          3
+#define MUTEX_TIMED_LOCK       4
+#define MUTEX_UNLOCK           5
+#define MUTEX_DESTROY          6
+#define COND_CREATE            7
+#define COND_SIGNAL            8
+#define COND_WAIT              9
+#define COND_DESTROY           10
+#define THREAD_DETACH          11
+#define THREAD_CREATE          12
 
 #define NS_PER_MS      1000000
 
@@ -51,6 +52,16 @@ typedef RT_TASK thread_t;
 typedef RT_COND cond_t;
 #endif /* __NATIVE_SKIN__ */
 
+void timespec_add(struct timespec *ts, unsigned long long value)
+{
+       ts->tv_sec += value / 1000000000;
+       ts->tv_nsec += value % 1000000000;
+       if (ts->tv_nsec > 1000000000) {
+               ts->tv_sec++;
+               ts->tv_nsec -= 1000000000;
+       }
+}
+
 void ms_sleep(int time)
 {
 #ifdef XENO_POSIX
@@ -82,14 +93,16 @@ void check_current_prio(int expected_prio)
        RT_TASK_INFO task_info;
 
        if ((ret = rt_task_inquire(NULL, &task_info)) < 0) {
-               fprintf(stderr, "Task inquire: %i (%s)\n", -ret, 
strerror(-ret));
+               fprintf(stderr,
+                       "FAILURE: Task inquire: %i (%s)\n", -ret, 
strerror(-ret));
                exit(EXIT_FAILURE);
        }
        current_prio = task_info.cprio;
 #endif /* __NATIVE_SKIN__ */
 
        if (current_prio != expected_prio) {
-               fprintf(stderr, "current prio (%d) != expected prio (%d)\n",
+               fprintf(stderr,
+                       "FAILURE: current prio (%d) != expected prio (%d)\n",
                        current_prio, expected_prio);
                exit(EXIT_FAILURE);
        }
@@ -105,7 +118,8 @@ void check_current_mode(int expected_primary_mode)
        current_in_primary = !(xeno_get_current_mode() & XNRELAX);
        
        if (current_in_primary != expected_primary_mode) {
-               fprintf(stderr, "current mode (%d) != expected mode (%d)\n",
+               fprintf(stderr,
+                       "FAILURE: current mode (%d) != expected mode (%d)\n",
                        current_in_primary, expected_primary_mode);
                exit(EXIT_FAILURE);
        }
@@ -122,16 +136,18 @@ void yield(void)
 
 int dispatch(const char *service_name, int service_type, int check, ...)
 {
+       unsigned long long timeout;
        thread_t *thread;
        cond_t *cond;
        void *handler;
        va_list ap;
        int status;
+       mutex_t *mutex;
 #ifdef XENO_POSIX
        struct sched_param param;
        pthread_attr_t threadattr;
        pthread_mutexattr_t mutexattr;
-       pthread_mutex_t *mutex;
+       struct timespec ts;
 #else /* __NATIVE_SKIN__ */
        int prio;
 #endif /* __NATIVE_SKIN__ */
@@ -174,6 +190,18 @@ int dispatch(const char *service_name, int service_type, 
int check, ...)
 #endif /* __NATIVE_SKIN__ */
                break;
 
+       case MUTEX_TIMED_LOCK:
+               mutex = va_arg(ap, mutex_t *);
+               timeout = va_arg(ap, unsigned long long);
+#ifdef XENO_POSIX
+               clock_gettime(CLOCK_REALTIME, &ts);
+               timespec_add(&ts, timeout);
+               status = pthread_mutex_timedlock(mutex, &ts);
+#else /* __NATIVE_SKIN__ */
+               status = -rt_mutex_acquire(mutex, timeout);
+#endif /* __NATIVE_SKIN__ */
+               break;
+
        case MUTEX_UNLOCK:
 #ifdef XENO_POSIX
                status = pthread_mutex_unlock(va_arg(ap, pthread_mutex_t *));
@@ -264,7 +292,7 @@ int dispatch(const char *service_name, int service_type, 
int check, ...)
        va_end(ap);
 
        if (status > 0 && check) {
-               fprintf(stderr, "%s: %i (%s)\n", 
+               fprintf(stderr, "FAILURE: %s: %i (%s)\n", 
                        service_name, status, strerror(status));
                exit(EXIT_FAILURE);
        }
@@ -281,7 +309,7 @@ void *waiter(void *cookie)
        dispatch("waiter mutex_lock", MUTEX_LOCK, 1, mutex);
        diff = rt_timer_tsc2ns(rt_timer_tsc() - start);
        if (diff < 10000000) {
-               fprintf(stderr, "waiter, waited %Ld.%03u us\n",
+               fprintf(stderr, "FAILURE: waiter, waited %Ld.%03u us\n",
                        diff / 1000, (unsigned) (diff % 1000));
                exit(EXIT_FAILURE);
        }
@@ -311,7 +339,7 @@ void simple_wait(void)
        dispatch("simple mutex_lock 2", MUTEX_LOCK, 1, &mutex);
        diff = rt_timer_tsc2ns(rt_timer_tsc() - start);
        if (diff < 10000000) {
-               fprintf(stderr, "main, waited %Ld.%03u us\n",
+               fprintf(stderr, "FAILURE: main, waited %Ld.%03u us\n",
                        diff / 1000, (unsigned) (diff % 1000));
                exit(EXIT_FAILURE);
        }
@@ -346,7 +374,7 @@ void recursive_wait(void)
        diff = rt_timer_tsc2ns(rt_timer_tsc() - start);
 
        if (diff < 10000000) {
-               fprintf(stderr, "main, waited %Ld.%03u us\n",
+               fprintf(stderr, "FAILURE: main, waited %Ld.%03u us\n",
                        diff / 1000, (unsigned) (diff % 1000));
                exit(EXIT_FAILURE);
        }
@@ -371,7 +399,7 @@ void errorcheck_wait(void)
 
        err = pthread_mutex_lock(&mutex);
        if (err != EDEADLK) {
-               fprintf(stderr, "errorcheck mutex_lock 2: %s\n",
+               fprintf(stderr, "FAILURE: errorcheck mutex_lock 2: %s\n",
                        strerror(err));
                exit(EXIT_FAILURE);
        }
@@ -383,7 +411,7 @@ void errorcheck_wait(void)
        yield();
        err = pthread_mutex_unlock(&mutex);
        if (err != EPERM) {
-               fprintf(stderr, "errorcheck mutex_unlock 2: %s\n",
+               fprintf(stderr, "FAILURE: errorcheck mutex_unlock 2: %s\n",
                        strerror(err));
                exit(EXIT_FAILURE);
        }
@@ -392,7 +420,7 @@ void errorcheck_wait(void)
        dispatch("errorcheck mutex_lock 3", MUTEX_LOCK, 1, &mutex);
        diff = rt_timer_tsc2ns(rt_timer_tsc() - start);
        if (diff < 10000000) {
-               fprintf(stderr, "main, waited %Ld.%03u us\n",
+               fprintf(stderr, "FAILURE: main, waited %Ld.%03u us\n",
                        diff / 1000, (unsigned) (diff % 1000));
                exit(EXIT_FAILURE);
        }
@@ -401,6 +429,51 @@ void errorcheck_wait(void)
 #endif /* XENO_POSIX */
 }
 
+void *timed_waiter(void *cookie)
+{
+       mutex_t *mutex = (mutex_t *) cookie;
+       unsigned long long start, diff;
+       int result;
+
+       dispatch("timed_waiter pthread_detach", THREAD_DETACH, 1);
+
+       start = rt_timer_tsc();
+       result = dispatch("timed_waiter mutex_timed_lock", MUTEX_TIMED_LOCK,
+                         0, mutex, 10000000);
+       diff = rt_timer_tsc2ns(rt_timer_tsc() - start);
+
+       if (result != ETIMEDOUT) {
+               fprintf(stderr,
+                       "FAILURE: timed_waiter mutex_timed_lock: %i (%s)\n",
+                       result, strerror(result));
+               exit(EXIT_FAILURE);
+       }
+       if (diff < 10000000) {
+               fprintf(stderr, "FAILURE: timed_waiter, waited %Ld.%03u us\n",
+                       diff / 1000, (unsigned) (diff % 1000));
+               exit(EXIT_FAILURE);
+       }
+
+       return cookie;
+}
+
+void timed_mutex(void)
+{
+       mutex_t mutex;
+       thread_t waiter_tid;
+
+       fprintf(stderr, "timed_mutex\n");
+
+       dispatch("timed_mutex mutex_init", MUTEX_CREATE, 1, &mutex, 1, 0);
+       dispatch("timed_mutex mutex_lock 1", MUTEX_LOCK, 1, &mutex);
+       dispatch("timed_mutex thread_create", THREAD_CREATE, 1, &waiter_tid,
+                2, timed_waiter, &mutex);
+       ms_sleep(20);
+       dispatch("timed_mutex mutex_unlock 1", MUTEX_UNLOCK, 1, &mutex);
+       dispatch("timed_mutex mutex_destroy", MUTEX_DESTROY, 1, &mutex);
+
+}
+
 void mode_switch(void)
 {
        mutex_t mutex;
@@ -448,7 +521,7 @@ void pi_wait(void)
        dispatch("pi mutex_lock 2", MUTEX_LOCK, 1, &mutex);
        diff = rt_timer_tsc2ns(rt_timer_tsc() - start);
        if (diff < 10000000) {
-               fprintf(stderr, "main, waited %Ld.%03u us\n",
+               fprintf(stderr, "FAILURE: main, waited %Ld.%03u us\n",
                        diff / 1000, (unsigned) (diff % 1000));
                exit(EXIT_FAILURE);
        }
@@ -506,7 +579,8 @@ void lock_stealing(void)
 #else /* __NATIVE_SKIN__ */
        } else if (trylock_result != EWOULDBLOCK) {
 #endif /* __NATIVE_SKIN__ */
-               fprintf(stderr, "lock_stealing mutex_trylock: %i (%s)\n",
+               fprintf(stderr,
+                       "FAILURE: lock_stealing mutex_trylock: %i (%s)\n",
                        trylock_result, strerror(trylock_result));
                exit(EXIT_FAILURE);
        }
@@ -525,7 +599,7 @@ void lock_stealing(void)
 
        if (trylock_result != 0)
                fprintf(stderr,
-                       "lock_stealing mutex_trylock: not supported\n");
+                       "NOTE: lock_stealing mutex_trylock: not supported\n");
 }
 
 struct cond_mutex {
@@ -546,7 +620,7 @@ void *cond_signaler(void *cookie)
 
        if (diff < 10000000) {
                fprintf(stderr,
-                       "cond_signaler, mutex_lock waited %Ld.%03u us\n",
+                       "FAILURE: cond_signaler, mutex_lock waited %Ld.%03u 
us\n",
                        diff / 1000, (unsigned) (diff % 1000));
                exit(EXIT_FAILURE);
        }
@@ -560,7 +634,7 @@ void *cond_signaler(void *cookie)
        diff = rt_timer_tsc2ns(rt_timer_tsc() - start);
        if (diff < 10000000) {
                fprintf(stderr,
-                       "cond_signaler, mutex_lock 2 waited %Ld.%03u us\n",
+                       "FAILURE: cond_signaler, mutex_lock 2 waited %Ld.%03u 
us\n",
                        diff / 1000, (unsigned) (diff % 1000));
                exit(EXIT_FAILURE);
        }
@@ -593,7 +667,7 @@ void simple_condwait(void)
        dispatch("simple_condwait cond_wait", COND_WAIT, 1, &cond, &mutex);
        diff = rt_timer_tsc2ns(rt_timer_tsc() - start);
        if (diff < 10000000) {
-               fprintf(stderr, "main, waited %Ld.%03u us\n",
+               fprintf(stderr, "FAILURE: main, waited %Ld.%03u us\n",
                        diff / 1000, (unsigned) (diff % 1000));
                exit(EXIT_FAILURE);
        }
@@ -631,7 +705,7 @@ void recursive_condwait(void)
        dispatch("rec_condwait cond_wait", COND_WAIT, 1, &cond, &mutex);
        diff = rt_timer_tsc2ns(rt_timer_tsc() - start);
        if (diff < 10000000) {
-               fprintf(stderr, "main, waited %Ld.%03u us\n",
+               fprintf(stderr, "FAILURE: main, waited %Ld.%03u us\n",
                        diff / 1000, (unsigned) (diff % 1000));
                exit(EXIT_FAILURE);
        }
@@ -666,6 +740,7 @@ int main(void)
        simple_wait();
        recursive_wait();
        errorcheck_wait();
+       timed_mutex();
        mode_switch();
        pi_wait();
        lock_stealing();


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to