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

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Tue Dec  1 23:21:24 2009 +0100

testsuite: add user-space real-time signals unit test

---

 configure.in                          |    1 +
 include/Makefile.am                   |    2 +-
 include/testing/sigtest_syscall.h     |   16 ++
 ksrc/drivers/testing/Config.in        |    2 +
 ksrc/drivers/testing/Kconfig          |   10 +-
 ksrc/drivers/testing/Makefile         |    8 +-
 ksrc/drivers/testing/sigtest_module.c |  137 ++++++++++++++
 src/testsuite/Makefile.am             |    2 +-
 src/testsuite/sigtest/Makefile.am     |   29 +++
 src/testsuite/sigtest/runinfo.in      |    1 +
 src/testsuite/sigtest/sigtest.c       |  315 +++++++++++++++++++++++++++++++++
 11 files changed, 518 insertions(+), 5 deletions(-)

diff --git a/configure.in b/configure.in
index d0d9a1c..37d1ad2 100644
--- a/configure.in
+++ b/configure.in
@@ -912,6 +912,7 @@ AC_CONFIG_FILES([ \
        src/testsuite/clocktest/Makefile \
                src/testsuite/klatency/Makefile \
                src/testsuite/unit/Makefile \
+               src/testsuite/sigtest/Makefile \
        src/utils/Makefile \
        src/utils/can/Makefile \
        src/utils/analogy/Makefile \
diff --git a/include/Makefile.am b/include/Makefile.am
index 04811a2..e882713 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -41,4 +41,4 @@ uninstall-local:
 dist-hook:
        find $(distdir)/compat -name .svn -depth -exec rm -fr \{\} \;
 
-EXTRA_DIST = compat
+EXTRA_DIST = compat testing
diff --git a/include/testing/sigtest_syscall.h 
b/include/testing/sigtest_syscall.h
new file mode 100644
index 0000000..b260cc5
--- /dev/null
+++ b/include/testing/sigtest_syscall.h
@@ -0,0 +1,16 @@
+#ifndef SIGTEST_SYSCALL_H
+#define SIGTEST_SYSCALL_H
+
+#include <asm/xenomai/syscall.h>
+
+#define SIGTEST_SKIN_MAGIC 0x53494754
+
+#define __NR_sigtest_queue 0   /* sigtest_queue(int *, size_t) */
+#define __NR_sigtest_wait_pri 1        /* sigtest_wait_pri(void) */
+#define __NR_sigtest_wait_sec 2 /* sigtest_wait_sec(void) */
+
+struct sigtest_siginfo {
+       int sig_nr;
+};
+
+#endif /* SIGTEST_SYSCALL_H */
diff --git a/ksrc/drivers/testing/Config.in b/ksrc/drivers/testing/Config.in
index 41c2efa..01fe460 100644
--- a/ksrc/drivers/testing/Config.in
+++ b/ksrc/drivers/testing/Config.in
@@ -13,4 +13,6 @@ dep_tristate 'Context switches test driver' 
CONFIG_XENO_DRIVERS_SWITCHTEST $CONF
 
 dep_tristate 'Kernel-only latency measurement module' 
CONFIG_XENO_DRIVERS_KLATENCY $XENO_DRIVERS_TIMERBENCH
 
+dep_tristate 'User-space real-time signals testing module' 
CONFIG_XENO_SKIN_SIGTEST
+
 endmenu
diff --git a/ksrc/drivers/testing/Kconfig b/ksrc/drivers/testing/Kconfig
index 17c6ad6..c219fb9 100644
--- a/ksrc/drivers/testing/Kconfig
+++ b/ksrc/drivers/testing/Kconfig
@@ -1,6 +1,6 @@
 menu "Testing drivers"
 
-config XENO_KLATENCY_MODULE
+config XENO_TESTING_MODULE
         depends on MODULES
        def_tristate m
 
@@ -13,7 +13,7 @@ config XENO_DRIVERS_TIMERBENCH
        See testsuite/latency for a possible front-end.
 
 config XENO_DRIVERS_KLATENCY
-       depends on XENO_DRIVERS_TIMERBENCH && XENO_KLATENCY_MODULE
+       depends on XENO_DRIVERS_TIMERBENCH && XENO_TESTING_MODULE
        tristate "Kernel-only latency measurement module"
        help
        Kernel module for kernel-only latency measurement.
@@ -34,4 +34,10 @@ config XENO_DRIVERS_SWITCHTEST
        Kernel-based driver for unit testing context switches and
        FPU switches.
 
+config XENO_SKIN_SIGTEST
+       depends on XENO_TESTING_MODULE
+       tristate "User-space real-time signals testing module"
+       help
+       Elementary skin for unit testing user-space real-time signals.
+
 endmenu
diff --git a/ksrc/drivers/testing/Makefile b/ksrc/drivers/testing/Makefile
index e8ce95a..db9150e 100644
--- a/ksrc/drivers/testing/Makefile
+++ b/ksrc/drivers/testing/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_XENO_DRIVERS_TIMERBENCH) += xeno_timerbench.o
 obj-$(CONFIG_XENO_DRIVERS_IRQBENCH)   += xeno_irqbench.o
 obj-$(CONFIG_XENO_DRIVERS_SWITCHTEST) += xeno_switchtest.o
 obj-$(CONFIG_XENO_DRIVERS_KLATENCY)   += xeno_klat.o
+obj-$(CONFIG_XENO_SKIN_SIGTEST)    += xeno_sigtest.o
 
 xeno_timerbench-y := timerbench.o
 
@@ -17,6 +18,8 @@ xeno_switchtest-y := switchtest.o
 
 xeno_klat-y := klat.o
 
+xeno_sigtest-y := sigtest_module.o
+
 EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai
 
 else
@@ -29,6 +32,7 @@ obj-$(CONFIG_XENO_DRIVERS_TIMERBENCH) += xeno_timerbench.o
 obj-$(CONFIG_XENO_DRIVERS_IRQBENCH)   += xeno_irqbench.o
 obj-$(CONFIG_XENO_DRIVERS_SWITCHTEST) += xeno_switchtest.o
 obj-$(CONFIG_XENO_DRIVERS_KLATENCY)   += xeno_klat.o
+obj-$(CONFIG_XENO_SKIN_SIGTEST)              += xeno_sigtest.o
 xeno_timerbench-objs := timerbench.o
 
 xeno_irqbench-objs := irqbench.o
@@ -37,8 +41,10 @@ xeno_switchtest-objs := switchtest.o
 
 xeno_klat-objs := klat.o
 
+xeno_sigtest-objs := sigtest_module.o
+
 export-objs := $(xeno_timerbench-objs) $(xeno_irqbench-objs) \
-       $(xeno_switchtest-objs) $(xeno_klat-objs)
+       $(xeno_switchtest-objs) $(xeno_klat-objs) $(xeno_sigtest-objs)
 
 EXTRA_CFLAGS += -D__IN_XENOMAI__ -I$(TOPDIR)/include/xenomai 
-I$(TOPDIR)/include/xenomai/compat
 
diff --git a/ksrc/drivers/testing/sigtest_module.c 
b/ksrc/drivers/testing/sigtest_module.c
new file mode 100644
index 0000000..e4235f1
--- /dev/null
+++ b/ksrc/drivers/testing/sigtest_module.c
@@ -0,0 +1,137 @@
+#include <nucleus/timebase.h>
+#include <nucleus/timer.h>
+#include <nucleus/shadow.h>
+#include <nucleus/thread.h>
+#include <nucleus/heap.h>
+#include <nucleus/pod.h>
+#include <nucleus/types.h>
+#include <testing/sigtest_syscall.h>
+
+static int muxid;
+static xntbase_t *tbase;
+
+static int *sigs, next_sig;
+static size_t nr_sigs;
+static xnthread_t *target;
+static xntimer_t sigtest_timer;
+
+MODULE_DESCRIPTION("signals testing interface");
+MODULE_AUTHOR("gilles.chanteperd...@xenomai.org");
+MODULE_LICENSE("GPL");
+
+static void sigtest_timer_handler(xntimer_t *timer)
+{
+       xnshadow_mark_sig(target, muxid);
+       /* xnpod_schedule called later. */
+}
+
+static int __sigtest_queue(struct pt_regs *regs)
+{
+       target = xnshadow_thread(current);
+       nr_sigs = (size_t)__xn_reg_arg2(regs);
+       sigs = xnmalloc(sizeof(*sigs) * nr_sigs);
+       next_sig = 0;
+
+       if (__xn_copy_from_user(sigs, (void __user *)__xn_reg_arg1(regs), 
+                               sizeof(*sigs) * nr_sigs)) {
+               xnfree(sigs);
+               return -EFAULT;
+       }
+
+       xntimer_set_sched(&sigtest_timer, xnpod_current_sched());
+       xntimer_start(&sigtest_timer, 10000000, 0, 0);
+
+       return 0;
+}
+
+static int __sigtest_wait_pri(struct pt_regs *regs)
+{
+       xnthread_t *thread = xnshadow_thread(current);
+       xnticks_t ticks = xntbase_ns2ticks(tbase, 20000000);
+       xnpod_suspend_thread(thread, XNDELAY, ticks, XN_RELATIVE, NULL);
+       if (xnthread_test_info(thread, XNBREAK))
+               return -EINTR;
+
+       return 0;
+}
+
+static int __sigtest_wait_sec(struct pt_regs *regs)
+{
+       schedule_timeout_interruptible(20 * HZ / 1000 + 1);
+       if (signal_pending(current))
+               return -EINTR;
+       return 0;
+}
+
+static xnsysent_t __systab[] = {
+       [__NR_sigtest_queue] = {&__sigtest_queue, __xn_exec_any},
+       [__NR_sigtest_wait_pri] = {&__sigtest_wait_pri, __xn_exec_primary},
+       [__NR_sigtest_wait_sec] = {&__sigtest_wait_sec, __xn_exec_secondary},
+};
+
+static int sigtest_unqueue(xnthread_t *thread, union xnsiginfo __user *si)
+{
+       struct sigtest_siginfo __user *mysi = (struct sigtest_siginfo __user 
*)si;
+       int status = sigs[next_sig];
+
+       __xn_put_user(next_sig, &mysi->sig_nr);
+       if (++next_sig == nr_sigs) {
+               spl_t s;
+
+               xnfree(sigs);
+               xnlock_get_irqsave(&nklock, s);
+               xnshadow_clear_sig(thread, muxid);
+               xnlock_put_irqrestore(&nklock, s);
+       }
+       return status;
+}
+
+static struct xnskin_props __props = {
+       .name = "sigtest",
+       .magic = SIGTEST_SKIN_MAGIC,
+       .nrcalls = ARRAY_SIZE(__systab),
+       .systab = __systab,
+       .eventcb = NULL,
+       .sig_unqueue = sigtest_unqueue,
+       .timebasep = &tbase,
+       .module = THIS_MODULE
+};
+
+int SKIN_INIT(sigtest)
+{
+       int err;
+
+       xnprintf("starting sigtest services\n");
+
+       err = xnpod_init();
+       if (err)
+               goto fail;
+
+       err = xntbase_alloc("sigtest", 0, 0, &tbase);
+       if (err)
+               goto fail_shutdown_pod;
+
+       muxid = xnshadow_register_interface(&__props);
+       if (muxid < 0) {
+               err = muxid;
+         fail_shutdown_pod:
+               xnpod_shutdown(err);
+         fail:
+               return err;
+       }
+
+       xntimer_init(&sigtest_timer, tbase, sigtest_timer_handler);
+
+       return 0;
+}
+
+void SKIN_EXIT(sigtest)
+{
+       xnprintf("stopping sigtest services\n");
+       xntimer_destroy(&sigtest_timer);
+       xnshadow_unregister_interface(muxid);
+       xntbase_free(tbase);
+       xnpod_shutdown(XNPOD_NORMAL_EXIT);
+}
+module_init(__sigtest_skin_init);
+module_exit(__sigtest_skin_exit);
diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am
index 0f533c2..70ab3ce 100644
--- a/src/testsuite/Makefile.am
+++ b/src/testsuite/Makefile.am
@@ -1 +1 @@
-SUBDIRS = latency cyclic switchtest irqbench clocktest klatency unit
+SUBDIRS = latency cyclic switchtest irqbench clocktest klatency unit sigtest
diff --git a/src/testsuite/sigtest/Makefile.am 
b/src/testsuite/sigtest/Makefile.am
new file mode 100644
index 0000000..9d7a342
--- /dev/null
+++ b/src/testsuite/sigtest/Makefile.am
@@ -0,0 +1,29 @@
+testdir = $(exec_prefix)/share/xenomai/testsuite/sigtest
+
+CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC)
+
+bin_PROGRAMS = sigtest
+
+sigtest_SOURCES = sigtest.c
+
+sigtest_CPPFLAGS = -I$(top_srcdir)/include/posix $(XENO_USER_CFLAGS) -g 
-I$(top_srcdir)/include
+
+sigtest_LDFLAGS =  $(XENO_POSIX_WRAPPERS) $(XENO_USER_LDFLAGS) -rdynamic
+
+sigtest_LDADD = \
+       ../../skins/posix/libpthread_rt.la -lpthread -lrt
+
+install-data-local:
+       $(mkinstalldirs) $(DESTDIR)$(testdir)
+       @sed -e's,@exec_prefix\@,$(exec_prefix),g' $(srcdir)/runinfo.in > 
$(DESTDIR)$(testdir)/.runinfo
+       @echo "#!/bin/sh" > $(DESTDIR)$(testdir)/run
+       @echo "\$${DESTDIR}$(exec_prefix)/bin/xeno-load \`dirname \$$0\` \$$*" 
>> $(DESTDIR)$(testdir)/run
+       @chmod +x $(DESTDIR)$(testdir)/run
+
+uninstall-local:
+       $(RM) $(DESTDIR)$(testdir)/.runinfo $(DESTDIR)$(testdir)/run
+
+run: all
+       @$(top_srcdir)/scripts/xeno-load --verbose
+
+EXTRA_DIST = runinfo.in
diff --git a/src/testsuite/sigtest/runinfo.in b/src/testsuite/sigtest/runinfo.in
new file mode 100644
index 0000000..1d89013
--- /dev/null
+++ b/src/testsuite/sigtest/runinfo.in
@@ -0,0 +1 @@
+sigtest:posix+rtdm+sigtest:!...@exec_prefix@/bin/sigtest;popall:control_c
diff --git a/src/testsuite/sigtest/sigtest.c b/src/testsuite/sigtest/sigtest.c
new file mode 100644
index 0000000..77de76b
--- /dev/null
+++ b/src/testsuite/sigtest/sigtest.c
@@ -0,0 +1,315 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <sys/mman.h>
+#ifdef __GLIBC__
+#include <execinfo.h>
+#endif /* __GLIBC__ */
+
+#include <asm-generic/xenomai/bits/bind.h>
+#include <asm-generic/bits/mlock_alert.h>
+#include <asm-generic/bits/sigshadow.h>
+#include <testing/sigtest_syscall.h>
+
+#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
+
+static int shifted_muxid;
+
+int sigtest_queue(int *retvals, size_t nr)
+{
+       return XENOMAI_SKINCALL2(shifted_muxid, 
+                                __NR_sigtest_queue, retvals, nr);
+}
+
+int sigtest_wait_pri(void)
+{
+       return XENOMAI_SKINCALL0(shifted_muxid, __NR_sigtest_wait_pri);
+}
+
+int sigtest_wait_sec(void)
+{
+       return XENOMAI_SKINCALL0(shifted_muxid, __NR_sigtest_wait_sec);
+}
+
+static xnsighandler *mysh;
+
+void sigtest_handler(union xnsiginfo *gen_si)
+{
+       mysh(gen_si);
+}
+
+__attribute__((constructor)) void __init_sigtest_interface(void)
+{
+       int muxid;
+
+       muxid = xeno_bind_skin(SIGTEST_SKIN_MAGIC, "SIGTEST", "xeno_sigtest", 
sigtest_handler);
+
+       shifted_muxid = __xn_mux_shifted_id(muxid);
+}
+
+static volatile unsigned seen;
+static int cascade_res;
+
+void mark_seen(union xnsiginfo *gen_si)
+{
+       struct sigtest_siginfo *si = (struct sigtest_siginfo *)gen_si;
+       seen |= (1 << si->sig_nr);
+}
+
+void mark_seen_2(int sig)
+{
+       seen |= 2;
+}
+
+void mark_seen_2_bt(int sig)
+{
+#ifdef __GLIBC__
+       void *buf[200];
+       int nelems = backtrace(buf, sizeof(buf)/sizeof(buf[0]));
+       fputs("\n>>>>>>>>>>>>>>>>>>>>> Please "
+             "check that the following backtrace looks correct:\n", stderr);
+       backtrace_symbols_fd(buf, nelems, 2);
+       fputs("<<<<<<<<<<<<<<<<<<<<< End of backtrace\n\n", stderr);
+#endif /* __GLIBC__ */
+       seen |= 2;
+}
+
+void cascade_pri(union xnsiginfo *gen_si __attribute__((unused)))
+{
+       cascade_res = sigtest_wait_pri() == -EINTR ? -EINTR : cascade_res;
+}
+
+void cascade_sec(union xnsiginfo *gen_si __attribute__((unused)))
+{
+       cascade_res = sigtest_wait_sec() == -EINTR ? -EINTR : cascade_res;
+}
+
+static unsigned failed, success;
+
+#define test_assert(expr)                                      \
+       ({                                                      \
+               if (expr) {                                     \
+                       ++success;                              \
+                       fprintf(stderr, #expr ": success.\n");  \
+               } else {                                        \
+                       ++failed;                               \
+                       fprintf(stderr, #expr " failed\n");     \
+               }                                               \
+       })
+
+#define check(expr, expected)                                          \
+       ({                                                              \
+               int rc = (expr);                                        \
+               if (rc == (expected)) {                                 \
+                       ++success;                                      \
+                       fprintf(stderr, #expr ": success.\n");          \
+               } else {                                                \
+                       ++failed;                                       \
+                       fprintf(stderr, #expr " failed: %d\n", -rc);    \
+               }                                                       \
+       })
+
+void *cancel_with_signals(void *cookie)
+{
+       int *run = (int *)cookie;
+       int one_restart[] = { -ERESTART, };
+       struct timespec ts;
+
+       pthread_set_name_np(pthread_self(), "cancel_with_signals");
+
+       check(sigtest_queue(one_restart, ARRAY_SIZE(one_restart)), 0);
+       ts.tv_sec = 0;
+       ts.tv_nsec = 20000000;
+       __real_nanosleep(&ts, NULL);    /* Wait for the signals to be
+                                        * delivered. */
+       *run = 1;
+       pthread_exit(NULL);
+}
+
+struct cond {
+       pthread_mutex_t mx;
+       pthread_cond_t cnd;
+       int val;
+};
+
+void *dual_signals(void *cookie)
+{
+       struct cond *c = (struct cond *)cookie;
+       int one_restart[] = { -ERESTART, };
+
+       pthread_set_name_np(pthread_self(), "dual_signals");
+
+       check(sigtest_queue(one_restart, ARRAY_SIZE(one_restart)), 0);
+       pthread_mutex_lock(&c->mx);
+       c->val = 1;
+       pthread_cond_signal(&c->cnd);
+       while (c->val != 2)
+               check(pthread_cond_wait(&c->cnd, &c->mx), 0);
+       c->val = 3;
+       pthread_cond_signal(&c->cnd);
+       pthread_mutex_unlock(&c->mx);
+       pthread_exit(NULL);
+}
+
+void *dual_signals2(void *cookie)
+{
+       int one_restart[] = { -ERESTART, };
+
+       pthread_set_name_np(pthread_self(), "dual_signals");
+       check(sigtest_queue(one_restart, ARRAY_SIZE(one_restart)), 0);
+       check(sigtest_wait_sec(), 0);
+       test_assert(seen == 3);
+       pthread_exit(NULL);
+}
+
+int main(void)
+{
+       mlockall(MCL_CURRENT | MCL_FUTURE);
+
+       int one_restart[] = { -ERESTART, };
+       mysh = mark_seen;
+       seen = 0;
+       check(sigtest_queue(one_restart, ARRAY_SIZE(one_restart)), 0);
+       check(sigtest_wait_pri(), 0);
+       test_assert(seen == 1);
+
+       seen = 0;
+       check(sigtest_queue(one_restart, ARRAY_SIZE(one_restart)), 0);
+       check(sigtest_wait_sec(), 0);
+       test_assert(seen == 1);
+       
+       int one_intr[] = { -EINTR, };
+       seen = 0;
+       check(sigtest_queue(one_intr, ARRAY_SIZE(one_intr)), 0);
+       check(sigtest_wait_pri(), -EINTR);
+       test_assert(seen == 1);
+
+       seen = 0;
+       check(sigtest_queue(one_intr, ARRAY_SIZE(one_intr)), 0);
+       check(sigtest_wait_sec(), 0); /* Signal does not interrupt
+                                      * secondary-mode syscall */
+       test_assert(seen == 1);
+
+       int sixteen_restart[] = { [0 ... 15] = -ERESTART, };
+       seen = 0;
+       check(sigtest_queue(sixteen_restart, ARRAY_SIZE(sixteen_restart)), 0);
+       check(sigtest_wait_pri(), 0);
+       test_assert(seen == ((1 << 16) - 1));
+
+       seen = 0;
+       check(sigtest_queue(sixteen_restart, ARRAY_SIZE(sixteen_restart)), 0);
+       check(sigtest_wait_sec(), 0);
+       test_assert(seen == ((1 << 16) - 1));
+
+       int middle_intr[] = { [0 ... 7] = -ERESTART, [8] = -EINTR, [9 ... 15] = 
-ERESTART, 
+       };
+       seen = 0;
+       check(sigtest_queue(middle_intr, ARRAY_SIZE(middle_intr)), 0);
+       check(sigtest_wait_pri(), -EINTR);
+       test_assert(seen == ((1 << 16) - 1));
+       
+       seen = 0;
+       check(sigtest_queue(middle_intr, ARRAY_SIZE(middle_intr)), 0);
+       check(sigtest_wait_sec(), 0); /* Signal does not interrupt
+                                      * secondary-mode syscall */
+       test_assert(seen == ((1 << 16) - 1));
+
+       int seventeen_restart[] = { [0 ... 16] = -ERESTART };
+       mysh = cascade_pri;
+       cascade_res = ~0;
+       check(sigtest_queue(seventeen_restart, ARRAY_SIZE(seventeen_restart)), 
0);
+       check(sigtest_wait_pri(), 0);
+       test_assert(cascade_res == ~0);
+       
+       cascade_res = ~0;
+       check(sigtest_queue(seventeen_restart, ARRAY_SIZE(seventeen_restart)), 
0);
+       check(sigtest_wait_sec(), 0);
+       test_assert(cascade_res == ~0);
+
+       int seventeen_intr[] = { [0 ... 15] = -ERESTART, [16] = -EINTR };
+       cascade_res = ~0;
+       check(sigtest_queue(seventeen_intr, ARRAY_SIZE(seventeen_intr)), 0);
+       check(sigtest_wait_pri(), 0);
+       test_assert(cascade_res == -EINTR);
+
+       cascade_res = ~0;
+       check(sigtest_queue(seventeen_intr, ARRAY_SIZE(seventeen_intr)), 0);
+       check(sigtest_wait_sec(), 0);
+       test_assert(cascade_res == -EINTR);
+
+       /* Cascade secondary mode call. */
+       mysh = cascade_sec;
+       cascade_res = ~0;
+       check(sigtest_queue(seventeen_restart, ARRAY_SIZE(seventeen_restart)), 
0);
+       check(sigtest_wait_pri(), 0);
+       test_assert(cascade_res == ~0);
+       
+       cascade_res = ~0;
+       check(sigtest_queue(seventeen_restart, ARRAY_SIZE(seventeen_restart)), 
0);
+       check(sigtest_wait_sec(), 0);
+       test_assert(cascade_res == ~0);
+
+       cascade_res = ~0;
+       check(sigtest_queue(seventeen_intr, ARRAY_SIZE(seventeen_intr)), 0);
+       check(sigtest_wait_pri(), 0);
+       test_assert(cascade_res == ~0);
+
+       cascade_res = ~0;
+       check(sigtest_queue(seventeen_intr, ARRAY_SIZE(seventeen_intr)), 0);
+       check(sigtest_wait_sec(), 0);
+       test_assert(cascade_res == ~0);
+
+       /* Try and destroy a thread with pending signals. They should
+          be discarded. */
+       pthread_t tid;
+       int run = 0;
+       mysh = mark_seen;
+       seen = 0;
+       pthread_create(&tid, NULL, cancel_with_signals, &run);
+       pthread_join(tid, NULL);
+       test_assert(run == 1 && seen == 0);
+
+       /* Try and mix linux signals and xeno signals (this test does
+          not work as expected, but turns out to be a good test for
+          pthread_cond_wait and signals, so, keep it). */
+       struct timespec ts;
+       struct cond c;
+       mysh = mark_seen;
+       seen = 0;
+       pthread_mutex_init(&c.mx, NULL);
+       pthread_cond_init(&c.cnd, NULL);
+       c.val = 0;
+       signal(SIGUSR1, mark_seen_2);
+       pthread_create(&tid, NULL, dual_signals, &c);
+       check(pthread_mutex_lock(&c.mx), 0);
+       while (c.val != 1)
+               check(pthread_cond_wait(&c.cnd, &c.mx), 0);
+       ts.tv_sec = 0;
+       ts.tv_nsec = 20000000;
+       nanosleep(&ts, NULL);
+       c.val = 2;
+       /* thread received the xeno signals, now send the linux signal */
+       pthread_kill(tid, SIGUSR1);
+       pthread_cond_signal(&c.cnd); /* Now, wake-up. */
+       while (c.val != 3)
+               check(pthread_cond_wait(&c.cnd, &c.mx), 0);
+       pthread_mutex_unlock(&c.mx);
+       test_assert(seen == 3);
+       pthread_join(tid, NULL);
+
+       /* Try and mix linux signals and xeno signals. Take 2. */
+       signal(SIGUSR1, mark_seen_2_bt);
+       seen = 0;
+       pthread_create(&tid, NULL, dual_signals2, NULL);
+       ts.tv_sec = 0;
+       ts.tv_nsec = 15000000;
+       nanosleep(&ts, NULL);
+       pthread_kill(tid, SIGUSR1);
+       pthread_join(tid, NULL);
+
+       fprintf(stderr, "Failed %u/%u\n", failed, success + failed);
+       sleep(1);
+       exit(failed ? EXIT_FAILURE : EXIT_SUCCESS);
+}


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

Reply via email to