Module: xenomai-gch Branch: for-forge Commit: 7532802bcc9310a94af20ae8547970a9650e6384 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=7532802bcc9310a94af20ae8547970a9650e6384
Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org> Date: Fri Dec 6 21:27:51 2013 +0100 cobalt: use registry for condvars --- include/cobalt/uapi/cond.h | 2 +- kernel/cobalt/posix/cond.c | 64 +++++++++++++++++++++++++++++--------------- kernel/cobalt/posix/cond.h | 1 + 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/include/cobalt/uapi/cond.h b/include/cobalt/uapi/cond.h index de37315..0c6157a 100644 --- a/include/cobalt/uapi/cond.h +++ b/include/cobalt/uapi/cond.h @@ -27,7 +27,7 @@ union cobalt_cond_union { struct __shadow_cond { unsigned int magic; struct cobalt_condattr attr; - struct cobalt_cond *cond; + xnhandle_t handle; union { unsigned int pending_signals_offset; unsigned long *pending_signals; diff --git a/kernel/cobalt/posix/cond.c b/kernel/cobalt/posix/cond.c index 5572431..87dd09d 100644 --- a/kernel/cobalt/posix/cond.c +++ b/kernel/cobalt/posix/cond.c @@ -54,16 +54,24 @@ #include "clock.h" static inline void -cond_destroy_internal(struct cobalt_cond *cond, struct cobalt_kqueues *q) +cond_destroy_internal(xnhandle_t handle, struct cobalt_kqueues *q) { + struct cobalt_cond *cond; spl_t s; xnlock_get_irqsave(&nklock, s); + cond = xnregistry_fetch(handle); + if (!cobalt_obj_active(cond, COBALT_COND_MAGIC, typeof(*cond))) { + xnlock_put_irqrestore(&nklock, s); + return; + } + xnregistry_remove(handle); list_del(&cond->link); /* synchbase wait queue may not be empty only when this function is called from cobalt_cond_pkg_cleanup, hence the absence of xnsched_run(). */ xnsynch_destroy(&cond->synchbase); + cobalt_mark_deleted(cond); xnlock_put_irqrestore(&nklock, s); xnheap_free(&xnsys_ppd_get(cond->attr.pshared)->sem_heap, cond->pending_signals); @@ -99,9 +107,9 @@ static inline int pthread_cond_init(struct __shadow_cond *cnd, const pthread_condattr_t *attr) { int synch_flags = XNSYNCH_PRIO | XNSYNCH_NOPIP, err; - struct list_head *condq, *entry; + struct cobalt_cond *cond, *old_cond; + struct list_head *condq; struct xnsys_ppd *sys_ppd; - struct cobalt_cond *cond; spl_t s; if (attr == NULL) @@ -139,18 +147,23 @@ pthread_cond_init(struct __shadow_cond *cnd, const pthread_condattr_t *attr) if (cnd->magic != COBALT_COND_MAGIC || list_empty(condq)) goto do_init; - list_for_each(entry, condq) { - if (entry == &cnd->cond->link) { - if (attr->pshared) { - cond_destroy_internal(cnd->cond, - cobalt_kqueues(1)); - goto do_init; - } - err = -EBUSY; - goto err_free_pending_signals; - } + old_cond = xnregistry_fetch(cnd->handle); + if (!cobalt_obj_active(old_cond, COBALT_COND_MAGIC, typeof(*old_cond))) + goto do_init; + + if (attr->pshared == 0) { + err = -EBUSY; + goto err_free_pending_signals; } + xnlock_put_irqrestore(&nklock, s); + cond_destroy_internal(cnd->handle, cobalt_kqueues(1)); + xnlock_get_irqsave(&nklock, s); do_init: + err = xnregistry_enter("", cond, &cond->handle, NULL); + if (err < 0) + goto err_free_pending_signals; + + cnd->handle = cond->handle; cnd->attr = *attr; cnd->pending_signals_offset = xnheap_mapped_offset(&sys_ppd->sem_heap, @@ -158,7 +171,6 @@ do_init: cnd->mutex_datp = (struct mutex_dat *)~0UL; cnd->magic = COBALT_COND_MAGIC; - cnd->cond = cond; cond->magic = COBALT_COND_MAGIC; xnsynch_init(&cond->synchbase, synch_flags, NULL); @@ -205,11 +217,16 @@ do_init: static inline int pthread_cond_destroy(struct __shadow_cond *cnd) { struct cobalt_cond *cond; + int pshared; spl_t s; xnlock_get_irqsave(&nklock, s); - - cond = cnd->cond; + cond = xnregistry_fetch(cnd->handle); + if (cond == NULL) { + xnlock_put_irqrestore(&nklock, s); + return -EINVAL; + } + if (!cobalt_obj_active(cnd, COBALT_COND_MAGIC, struct __shadow_cond) || !cobalt_obj_active(cond, COBALT_COND_MAGIC, struct cobalt_cond)) { xnlock_put_irqrestore(&nklock, s); @@ -227,11 +244,10 @@ static inline int pthread_cond_destroy(struct __shadow_cond *cnd) } cobalt_mark_deleted(cnd); - cobalt_mark_deleted(cond); - + pshared = cond->attr.pshared; xnlock_put_irqrestore(&nklock, s); - cond_destroy_internal(cond, cobalt_kqueues(cond->attr.pshared)); + cond_destroy_internal(cnd->handle, cobalt_kqueues(pshared)); return 0; } @@ -403,7 +419,9 @@ int cobalt_cond_wait_prologue(struct __shadow_cond __user *u_cnd, xnhandle_t handle; int err, perr = 0; - __xn_get_user(cnd, &u_cnd->cond); + __xn_get_user(handle, &u_cnd->handle); + cnd = xnregistry_fetch(handle); + __xn_get_user(handle, &u_mx->handle); mx = xnregistry_fetch(handle); @@ -461,7 +479,9 @@ int cobalt_cond_wait_epilogue(struct __shadow_cond __user *u_cnd, xnhandle_t handle; int err; - __xn_get_user(cnd, &u_cnd->cond); + __xn_get_user(handle, &u_cnd->handle); + cnd = xnregistry_fetch(handle); + __xn_get_user(handle, &u_mx->handle); mx = xnregistry_fetch(handle); @@ -515,7 +535,7 @@ void cobalt_condq_cleanup(struct cobalt_kqueues *q) list_for_each_entry_safe(cond, tmp, &q->condq, link) { xnlock_put_irqrestore(&nklock, s); - cond_destroy_internal(cond, q); + cond_destroy_internal(cond->handle, q); #if XENO_DEBUG(COBALT) printk(XENO_INFO "deleting Cobalt condvar %p\n", cond); #endif /* XENO_DEBUG(COBALT) */ diff --git a/kernel/cobalt/posix/cond.h b/kernel/cobalt/posix/cond.h index 26f5544..84946df 100644 --- a/kernel/cobalt/posix/cond.h +++ b/kernel/cobalt/posix/cond.h @@ -39,6 +39,7 @@ struct cobalt_cond { pthread_condattr_t attr; struct cobalt_mutex *mutex; struct cobalt_kqueues *owningq; + xnhandle_t handle; }; extern const pthread_condattr_t cobalt_default_cond_attr; _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git