Module: xenomai-jki Branch: for-upstream Commit: 7fc3764307e620fae623e0dba706cf4baf1aa0ec URL: http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=7fc3764307e620fae623e0dba706cf4baf1aa0ec
Author: Jan Kiszka <jan.kis...@siemens.com> Date: Tue Mar 2 22:35:13 2010 +0100 testsuite: Add timed mutex and cond tests Add test for timeouts while waiting on mutexes of condition variables. 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 | 183 ++++++++++++++++++++++++++++++------ 1 files changed, 154 insertions(+), 29 deletions(-) diff --git a/src/testsuite/unit/mutex-torture.c b/src/testsuite/unit/mutex-torture.c index ebdd4f2..5f84652 100644 --- a/src/testsuite/unit/mutex-torture.c +++ b/src/testsuite/unit/mutex-torture.c @@ -27,17 +27,19 @@ #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_TIMED_WAIT 10 +#define COND_DESTROY 11 +#define THREAD_DETACH 12 +#define THREAD_CREATE 13 #define NS_PER_MS 1000000 @@ -51,6 +53,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 +94,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 +119,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 +137,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 +191,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 *)); @@ -218,6 +247,19 @@ int dispatch(const char *service_name, int service_type, int check, ...) #endif /* __NATIVE_SKIN__ */ break; + case COND_TIMED_WAIT: + cond = va_arg(ap, cond_t *); + 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_cond_timedwait(cond, mutex, &ts); +#else /* __NATIVE_SKIN__ */ + status = -rt_cond_wait(cond, mutex, timeout); +#endif /* __NATIVE_SKIN__ */ + break; + case COND_DESTROY: #ifdef XENO_POSIX status = pthread_cond_destroy(va_arg(ap, pthread_cond_t *)); @@ -264,7 +306,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 +323,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 +353,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 +388,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 +413,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 +425,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 +434,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 +443,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 +535,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 +593,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 +613,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 +634,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 +648,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 +681,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 +719,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); } @@ -644,6 +732,41 @@ void recursive_condwait(void) dispatch("rec_condwait cond_destroy", COND_DESTROY, 1, &cond); } +void timed_condwait(void) +{ + unsigned long long start, diff; + mutex_t mutex; + cond_t cond; + int result; + + fprintf(stderr, "timed_condwait\n"); + + dispatch("timed_condwait mutex_init", MUTEX_CREATE, 1, &mutex); + dispatch("timed_condwait cond_init", COND_CREATE, 1, &cond); + dispatch("timed_condwait mutex_lock", MUTEX_LOCK, 1, &mutex); + + start = rt_timer_tsc(); + result = dispatch("timed_condwait cond_timed_wait", COND_TIMED_WAIT, + 0, &cond, &mutex, 10000000); + diff = rt_timer_tsc2ns(rt_timer_tsc() - start); + + if (result != ETIMEDOUT) { + fprintf(stderr, + "FAILURE: main cond_timed_wait: %i (%s)\n", + result, strerror(result)); + exit(EXIT_FAILURE); + } + if (diff < 10000000) { + fprintf(stderr, "FAILURE: main, waited %Ld.%03u us\n", + diff / 1000, (unsigned) (diff % 1000)); + exit(EXIT_FAILURE); + } + dispatch("simple_condwait mutex_unlock", MUTEX_UNLOCK, 1, &mutex); + + dispatch("simple_condwait mutex_destroy", MUTEX_DESTROY, 1, &mutex); + dispatch("simple_condwait cond_destroy", COND_DESTROY, 1, &cond); +} + int main(void) { #ifdef XENO_POSIX @@ -666,11 +789,13 @@ int main(void) simple_wait(); recursive_wait(); errorcheck_wait(); + timed_mutex(); mode_switch(); pi_wait(); lock_stealing(); simple_condwait(); recursive_condwait(); + timed_condwait(); fprintf(stderr, "Test OK\n"); return 0; } _______________________________________________ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git