Module: xenomai-jki
Branch: for-upstream
Commit: d569a7029db921d40a3ffc22d292992f2ee645b1
URL:    
http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=d569a7029db921d40a3ffc22d292992f2ee645b1

Author: Jan Kiszka <jan.kis...@siemens.com>
Date:   Fri Jun  4 18:11:34 2010 +0200

Add unit test for task/thread deletion

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

---

 src/testsuite/unit/Makefile.am      |   29 +++++
 src/testsuite/unit/task-terminate.c |  217 +++++++++++++++++++++++++++++++++++
 2 files changed, 246 insertions(+), 0 deletions(-)

diff --git a/src/testsuite/unit/Makefile.am b/src/testsuite/unit/Makefile.am
index f37ec33..d9a7a3e 100644
--- a/src/testsuite/unit/Makefile.am
+++ b/src/testsuite/unit/Makefile.am
@@ -10,6 +10,8 @@ test_PROGRAMS = \
        mutex-torture-native \
        cond-torture-posix \
        cond-torture-native \
+       task-terminate-posix \
+       task-terminate-native \
        check-vdso \
        rtdm
 
@@ -93,6 +95,33 @@ cond_torture_native_LDADD = \
        ../../skins/common/libxenomai.la \
        -lpthread -lm
 
+task_terminate_posix_SOURCES = task-terminate.c
+
+task_terminate_posix_CPPFLAGS = \
+       -I$(top_srcdir)/include/posix @XENO_USER_CFLAGS@ -g -DXENO_POSIX \
+       -I$(top_srcdir)/include
+
+task_terminate_posix_LDFLAGS = $(XENO_POSIX_WRAPPERS) @XENO_USER_LDFLAGS@
+
+task_terminate_posix_LDADD = \
+       ../../skins/posix/libpthread_rt.la \
+       ../../skins/native/libnative.la \
+       ../../skins/common/libxenomai.la \
+       -lpthread -lrt -lm
+
+task_terminate_native_SOURCES = task-terminate.c
+
+task_terminate_native_CPPFLAGS = \
+       @XENO_USER_CFLAGS@ \
+       -I$(top_srcdir)/include
+
+task_terminate_native_LDFLAGS = @XENO_USER_LDFLAGS@
+
+task_terminate_native_LDADD = \
+       ../../skins/native/libnative.la \
+       ../../skins/common/libxenomai.la \
+       -lpthread -lm
+
 check_vdso_SOURCES = check-vdso.c
 
 check_vdso_CPPFLAGS = \
diff --git a/src/testsuite/unit/task-terminate.c 
b/src/testsuite/unit/task-terminate.c
new file mode 100644
index 0000000..d48c6c6
--- /dev/null
+++ b/src/testsuite/unit/task-terminate.c
@@ -0,0 +1,217 @@
+/*
+ * Functional testing of task termination for native & posix skins.
+ *
+ * Copyright (C) Jan Kiszka  <jan.kis...@siemens.com>
+ *
+ * Released under the terms of GPLv2.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <sys/mman.h>
+#include <pthread.h>
+
+#ifndef XENO_POSIX
+#include <native/task.h>
+#endif /* __NATIVE_SKIN */
+
+#include <asm-generic/xenomai/stack.h>
+
+#define NS_PER_MS (1000000)
+
+#ifdef XENO_POSIX
+
+typedef pthread_t task_t;
+
+int task_delete(pthread_t task, int joinable)
+{
+       int err;
+
+       err = -pthread_cancel(task);
+       if (!joinable || err)
+               return err;
+
+       return -pthread_detach(task);
+}
+
+#define task_join(task)                        (-pthread_join(task, NULL))
+
+#define NS_PER_S (1000000000)
+
+void task_msleep(unsigned ms)
+{
+       struct timespec ts = {
+               .tv_sec = (ms * NS_PER_MS) / NS_PER_S,
+               .tv_nsec = (ms * NS_PER_MS) % NS_PER_S,
+       };
+
+       nanosleep(&ts, NULL);
+}
+
+#else /* __NATIVE_SKIN__ */
+
+typedef RT_TASK task_t;
+
+#define task_delete(task, joinable)    rt_task_delete(&task)
+#define task_join(task)                        rt_task_join(&task)
+#define task_msleep(ms)                        rt_task_sleep((RTIME)ms * 
NS_PER_MS)
+
+#endif /* __NATIVE_SKIN__ */
+
+void *task_handler(void *arg)
+{
+       task_msleep((unsigned long)arg);
+       return NULL;
+}
+
+int task_create(task_t *task, long termination_delay, int joinable)
+{
+       int err;
+#ifdef XENO_POSIX
+       pthread_attr_t tattr;
+
+       pthread_attr_init(&tattr);
+       pthread_attr_setdetachstate(&tattr, joinable ? PTHREAD_CREATE_JOINABLE
+                                                    : PTHREAD_CREATE_DETACHED);
+       pthread_attr_setstacksize(&tattr, xeno_stacksize(0));
+
+       err = pthread_create(task, &tattr, task_handler,
+                            (void *)termination_delay);
+
+       pthread_attr_destroy(&tattr);
+
+#else /* __NATIVE_SKIN__ */
+
+       err = rt_task_spawn(task, "task-terminate", 0, 2,
+                           joinable ? T_JOINABLE : 0,
+                           (void (*)(void *))task_handler,
+                           (void *)termination_delay);
+#endif /* __NATIVE_SKIN__ */
+
+       return -err;
+}
+
+void check_inner(const char *file, int line, const char *fn, const char *msg,
+                int status, int expected)
+{
+       if (status == expected)
+               return;
+
+       fprintf(stderr, "FAILED %s %s: returned %d instead of %d - %s\n", 
+               fn, msg, status, expected, strerror(-status));
+       exit(EXIT_FAILURE);
+}
+#define check(msg, status, expected) \
+       check_inner(__FILE__, __LINE__, __FUNCTION__, msg, status, expected)
+
+void normal_delete(void)
+{
+       task_t task;
+
+       fprintf(stderr, "%s\n", __FUNCTION__);
+
+       check("task_create", task_create(&task, 1000, 1), 0);
+       check("delete1", task_delete(task, 1), 0);
+
+       check("task_create detached", task_create(&task, 1000, 1), 0);
+       check("delete2", task_delete(task, 1), 0);
+}
+
+void double_delete(void)
+{
+       task_t task;
+
+       fprintf(stderr, "%s\n", __FUNCTION__);
+
+       check("task_create", task_create(&task, 1000, 1), 0);
+       check("delete", task_delete(task, 1), 0);
+#ifdef XENO_POSIX
+       check("invalid task_delete", task_delete(task, 1), -EINVAL);
+#else /* __NATIVE_SKIN__ */
+       check("invalid task_delete", task_delete(task, 1), -EIDRM);
+#endif /* __NATIVE_SKIN__ */
+}
+
+void normal_join(void)
+{
+       task_t task;
+
+       fprintf(stderr, "%s\n", __FUNCTION__);
+
+       check("task_create 1", task_create(&task, 10, 1), 0);
+       check("task_join 1", task_join(task), 0);
+
+       check("task_create 2", task_create(&task, 0, 1), 0);
+       check("task_join 2", task_join(task), 0);
+}
+
+void join_detached(void)
+{
+       task_t task;
+
+       fprintf(stderr, "%s\n", __FUNCTION__);
+
+       check("task_create", task_create(&task, 10, 0), 0);
+       check("task_join", task_join(task), -EINVAL);
+
+       /* wait for the task to terminate */
+       task_msleep(11);
+}
+
+void join_deleted(void)
+{
+       task_t task;
+
+       fprintf(stderr, "%s\n", __FUNCTION__);
+
+       check("task_create", task_create(&task, 10, 1), 0);
+       check("delete", task_delete(task, 1), 0);
+#ifdef XENO_POSIX
+       check("task_join", task_join(task), -EINVAL);
+#else /* __NATIVE_SKIN__ */
+       check("task_join", task_join(task), -EIDRM);
+#endif /* __NATIVE_SKIN__ */
+}
+
+void delete_joined(void)
+{
+       task_t task;
+
+       fprintf(stderr, "%s\n", __FUNCTION__);
+
+       check("task_create", task_create(&task, 10, 1), 0);
+       check("task_join", task_join(task), 0);
+#ifdef XENO_POSIX
+       check("delete", task_delete(task, 1), -ESRCH);
+#else /* __NATIVE_SKIN__ */
+       check("delete", task_delete(task, 1), -EIDRM);
+#endif /* __NATIVE_SKIN__ */
+}
+
+int main(void)
+{
+#ifndef XENO_POSIX
+       RT_TASK main_task;
+#endif /* __NATIVE_SKIN__ */
+
+       mlockall(MCL_CURRENT | MCL_FUTURE);
+
+#ifndef XENO_POSIX
+       rt_task_shadow(&main_task, "main_task", 1, 0);
+#endif /* __NATIVE_SKIN__ */
+
+       normal_delete();
+       double_delete();
+       normal_join();
+       join_detached();
+       join_deleted();
+       delete_joined();
+
+       fprintf(stderr, "Test OK\n");
+
+       return 0;
+}


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

Reply via email to