Module: xenomai-head Branch: master Commit: 3abdf95ed016b3b70bb08d5bd106917cdf057834 URL: http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=3abdf95ed016b3b70bb08d5bd106917cdf057834
Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org> Date: Sun Aug 1 19:02:08 2010 +0200 native: add cancellation points --- src/skins/native/cond.c | 81 +++++++++++++++++++++++++++++++++++++++------- src/skins/native/intr.c | 11 ++++++- src/skins/native/queue.c | 60 ++++++++++++++++++++++++++++++--- src/skins/native/sem.c | 22 +++++++++++- src/skins/native/task.c | 46 ++++++++++++++++++++++---- 5 files changed, 192 insertions(+), 28 deletions(-) diff --git a/src/skins/native/cond.c b/src/skins/native/cond.c index f874678..cf7a639 100644 --- a/src/skins/native/cond.c +++ b/src/skins/native/cond.c @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <pthread.h> + #include <native/syscall.h> #include <native/mutex.h> #include <native/cond.h> @@ -39,12 +41,40 @@ int rt_cond_delete(RT_COND *cond) return XENOMAI_SKINCALL1(__native_muxid, __native_cond_delete, cond); } +struct rt_cond_cleanup_t { + RT_MUTEX *mutex; + unsigned saved_lockcnt; +}; + +static void __rt_cond_cleanup(void *data) +{ + struct rt_cond_cleanup_t *c = (struct rt_cond_cleanup_t *)data; + int err; + + do { + err = XENOMAI_SKINCALL2(__native_muxid, + __native_cond_wait_epilogue, c->mutex, + c->saved_lockcnt); + } while (err == EINTR); + +#ifdef CONFIG_XENO_FASTSYNCH + c->mutex->lockcnt = c->saved_lockcnt; +#endif /* CONFIG_XENO_FASTSYNCH */ +} + int rt_cond_wait(RT_COND *cond, RT_MUTEX *mutex, RTIME timeout) { - int saved_lockcnt, err; + struct rt_cond_cleanup_t c = { + .mutex = mutex, + }; + int err, oldtype; + + pthread_cleanup_push(&__rt_cond_cleanup, &c); + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); #ifdef CONFIG_XENO_FASTSYNCH - saved_lockcnt = mutex->lockcnt; + c.saved_lockcnt = mutex->lockcnt; err = XENOMAI_SKINCALL5(__native_muxid, __native_cond_wait_prologue, cond, mutex, @@ -53,54 +83,81 @@ int rt_cond_wait(RT_COND *cond, RT_MUTEX *mutex, RTIME timeout) while (err == -EINTR) err = XENOMAI_SKINCALL2(__native_muxid, __native_cond_wait_epilogue, mutex, - saved_lockcnt); + c.saved_lockcnt); + + pthread_setcanceltype(oldtype, NULL); - mutex->lockcnt = saved_lockcnt; + pthread_cleanup_pop(0); + + mutex->lockcnt = c.saved_lockcnt; #else /* !CONFIG_XENO_FASTSYNCH */ err = XENOMAI_SKINCALL5(__native_muxid, __native_cond_wait_prologue, cond, mutex, - &saved_lockcnt, XN_RELATIVE, &timeout); + &c.saved_lockcnt, XN_RELATIVE, &timeout); + + pthread_setcanceltype(oldtype, NULL); + + pthread_cleanup_pop(0); while (err == -EINTR) err = XENOMAI_SKINCALL2(__native_muxid, __native_cond_wait_epilogue, mutex, - saved_lockcnt); + c.saved_lockcnt); #endif /* !CONFIG_XENO_FASTSYNCH */ + pthread_testcancel(); + return err; } int rt_cond_wait_until(RT_COND *cond, RT_MUTEX *mutex, RTIME timeout) { - int saved_lockcnt, err; + struct rt_cond_cleanup_t c = { + .mutex = mutex, + }; + int err, oldtype; + + pthread_cleanup_push(&__rt_cond_cleanup, &c); + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); #ifdef CONFIG_XENO_FASTSYNCH - saved_lockcnt = mutex->lockcnt; + c.saved_lockcnt = mutex->lockcnt; err = XENOMAI_SKINCALL5(__native_muxid, __native_cond_wait_prologue, cond, mutex, NULL, XN_REALTIME, &timeout); + pthread_setcanceltype(oldtype, NULL); + + pthread_cleanup_pop(0); + while (err == -EINTR) err = XENOMAI_SKINCALL2(__native_muxid, __native_cond_wait_epilogue, mutex, - saved_lockcnt); + c.saved_lockcnt); - mutex->lockcnt = saved_lockcnt; + mutex->lockcnt = c.saved_lockcnt; #else /* !CONFIG_XENO_FASTSYNCH */ err = XENOMAI_SKINCALL5(__native_muxid, __native_cond_wait_prologue, cond, mutex, - &saved_lockcnt, XN_REALTIME, &timeout); + &c.saved_lockcnt, XN_REALTIME, &timeout); + + pthread_setcanceltype(oldtype, NULL); + + pthread_cleanup_pop(0); while (err == -EINTR) err = XENOMAI_SKINCALL2(__native_muxid, __native_cond_wait_epilogue, mutex, - saved_lockcnt); + c.saved_lockcnt); #endif /* !CONFIG_XENO_FASTSYNCH */ + pthread_testcancel(); + return err; } diff --git a/src/skins/native/intr.c b/src/skins/native/intr.c index 8dd6db8..e425706 100644 --- a/src/skins/native/intr.c +++ b/src/skins/native/intr.c @@ -18,6 +18,7 @@ #include <sys/types.h> #include <stdio.h> +#include <pthread.h> #include <native/syscall.h> #include <native/intr.h> @@ -42,8 +43,16 @@ int rt_intr_delete(RT_INTR *intr) int rt_intr_wait(RT_INTR *intr, RTIME timeout) { - return XENOMAI_SKINCALL2(__native_muxid, + int err, oldtype; + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); + + err = XENOMAI_SKINCALL2(__native_muxid, __native_intr_wait, intr, &timeout); + + pthread_setcanceltype(oldtype, NULL); + + return err; } int rt_intr_enable(RT_INTR *intr) diff --git a/src/skins/native/queue.c b/src/skins/native/queue.c index e645822..4684251 100644 --- a/src/skins/native/queue.c +++ b/src/skins/native/queue.c @@ -124,42 +124,90 @@ int rt_queue_free(RT_QUEUE *q, void *buf) int rt_queue_send(RT_QUEUE *q, void *buf, size_t size, int mode) { - return XENOMAI_SKINCALL4(__native_muxid, + int err, oldtype; + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); + + err = XENOMAI_SKINCALL4(__native_muxid, __native_queue_send, q, buf, size, mode); + + pthread_setcanceltype(oldtype, NULL); + + return err; } int rt_queue_write(RT_QUEUE *q, const void *buf, size_t size, int mode) { - return XENOMAI_SKINCALL4(__native_muxid, + int err, oldtype; + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); + + err = XENOMAI_SKINCALL4(__native_muxid, __native_queue_write, q, buf, size, mode); + + pthread_setcanceltype(oldtype, NULL); + + return err; } ssize_t rt_queue_receive(RT_QUEUE *q, void **bufp, RTIME timeout) { - return XENOMAI_SKINCALL4(__native_muxid, + int err, oldtype; + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); + + err = XENOMAI_SKINCALL4(__native_muxid, __native_queue_receive, q, bufp, XN_RELATIVE, &timeout); + + pthread_setcanceltype(oldtype, NULL); + + return err; } ssize_t rt_queue_receive_until(RT_QUEUE *q, void **bufp, RTIME timeout) { - return XENOMAI_SKINCALL4(__native_muxid, + int err, oldtype; + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); + + err = XENOMAI_SKINCALL4(__native_muxid, __native_queue_receive, q, bufp, XN_REALTIME, &timeout); + + pthread_setcanceltype(oldtype, NULL); + + return err; } ssize_t rt_queue_read(RT_QUEUE *q, void *buf, size_t size, RTIME timeout) { - return XENOMAI_SKINCALL5(__native_muxid, + int err, oldtype; + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); + + err = XENOMAI_SKINCALL5(__native_muxid, __native_queue_read, q, buf, size, XN_RELATIVE, &timeout); + + pthread_setcanceltype(oldtype, NULL); + + return err; } ssize_t rt_queue_read_until(RT_QUEUE *q, void *buf, size_t size, RTIME timeout) { - return XENOMAI_SKINCALL5(__native_muxid, + int err, oldtype; + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); + + err = XENOMAI_SKINCALL5(__native_muxid, __native_queue_read, q, buf, size, XN_REALTIME, &timeout); + + pthread_setcanceltype(oldtype, NULL); + + return err; } int rt_queue_inquire(RT_QUEUE *q, RT_QUEUE_INFO *info) diff --git a/src/skins/native/sem.c b/src/skins/native/sem.c index 3b6ca70..8863e2c 100644 --- a/src/skins/native/sem.c +++ b/src/skins/native/sem.c @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <pthread.h> + #include <native/syscall.h> #include <native/sem.h> @@ -40,14 +42,30 @@ int rt_sem_delete(RT_SEM *sem) int rt_sem_p(RT_SEM *sem, RTIME timeout) { - return XENOMAI_SKINCALL3(__native_muxid, + int err, oldtype; + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); + + err = XENOMAI_SKINCALL3(__native_muxid, __native_sem_p, sem, XN_RELATIVE, &timeout); + + pthread_setcanceltype(oldtype, NULL); + + return err; } int rt_sem_p_until(RT_SEM *sem, RTIME timeout) { - return XENOMAI_SKINCALL3(__native_muxid, + int err, oldtype; + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); + + err = XENOMAI_SKINCALL3(__native_muxid, __native_sem_p, sem, XN_REALTIME, &timeout); + + pthread_setcanceltype(oldtype, NULL); + + return err; } int rt_sem_v(RT_SEM *sem) diff --git a/src/skins/native/task.c b/src/skins/native/task.c index d975508..be4ea2c 100644 --- a/src/skins/native/task.c +++ b/src/skins/native/task.c @@ -24,6 +24,7 @@ #include <pthread.h> #include <signal.h> #include <limits.h> +#include <pthread.h> #include <native/syscall.h> #include <native/task.h> #include <asm-generic/bits/sigshadow.h> @@ -191,7 +192,7 @@ int rt_task_shadow(RT_TASK *task, const char *name, int prio, int mode) if (pthread_getspecific(__native_tskey)) /* Current task is already a native taks. */ return -EBUSY; - + self = malloc(sizeof(*self)); if (!self) return -ENOMEM; @@ -292,8 +293,16 @@ int rt_task_set_periodic(RT_TASK *task, RTIME idate, RTIME period) int rt_task_wait_period(unsigned long *overruns_r) { - return XENOMAI_SKINCALL1(__native_muxid, + int err, oldtype; + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); + + err = XENOMAI_SKINCALL1(__native_muxid, __native_task_wait_period, overruns_r); + + pthread_setcanceltype(oldtype, NULL); + + return err; } int rt_task_set_priority(RT_TASK *task, int prio) @@ -304,15 +313,29 @@ int rt_task_set_priority(RT_TASK *task, int prio) int rt_task_sleep(RTIME delay) { - return XENOMAI_SKINCALL1(__native_muxid, __native_task_sleep, &delay); + int err, oldtype; + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); + + err = XENOMAI_SKINCALL1(__native_muxid, __native_task_sleep, &delay); + + pthread_setcanceltype(oldtype, NULL); + return err; } int rt_task_sleep_until(RTIME date) { - return XENOMAI_SKINCALL1(__native_muxid, __native_task_sleep_until, + int err, oldtype; + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); + + err = XENOMAI_SKINCALL1(__native_muxid, __native_task_sleep_until, &date); + pthread_setcanceltype(oldtype, NULL); + + return err; } int rt_task_unblock(RT_TASK *task) @@ -376,9 +399,18 @@ int rt_task_join(RT_TASK *task) ssize_t rt_task_send(RT_TASK *task, RT_TASK_MCB *mcb_s, RT_TASK_MCB *mcb_r, RTIME timeout) { - return (ssize_t) XENOMAI_SKINCALL4(__native_muxid, - __native_task_send, - task, mcb_s, mcb_r, &timeout); + int oldtype; + ssize_t ret; + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); + + ret = (ssize_t)XENOMAI_SKINCALL4(__native_muxid, + __native_task_send, + task, mcb_s, mcb_r, &timeout); + + pthread_setcanceltype(oldtype, NULL); + + return ret; } int rt_task_receive(RT_TASK_MCB *mcb_r, RTIME timeout) _______________________________________________ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git