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