Module: xenomai-3 Branch: next Commit: 8c1b05986fd49f2b0a0d10756e17cbb78a2eeb8e URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=8c1b05986fd49f2b0a0d10756e17cbb78a2eeb8e
Author: Philippe Gerum <r...@xenomai.org> Date: Wed Mar 18 18:17:08 2015 +0100 cobalt/posix/mutex: use resource management API --- kernel/cobalt/posix/mutex.c | 112 ++++++++++++++--------------------------- kernel/cobalt/posix/mutex.h | 8 +-- kernel/cobalt/posix/process.c | 2 +- 3 files changed, 44 insertions(+), 78 deletions(-) diff --git a/kernel/cobalt/posix/mutex.c b/kernel/cobalt/posix/mutex.c index 78fba35..0a21b36 100644 --- a/kernel/cobalt/posix/mutex.c +++ b/kernel/cobalt/posix/mutex.c @@ -28,21 +28,18 @@ static int cobalt_mutex_init_inner(struct cobalt_mutex_shadow *shadow, const struct cobalt_mutexattr *attr) { int synch_flags = XNSYNCH_PRIO | XNSYNCH_OWNER; - struct cobalt_resources *rs; struct cobalt_ppd *sys_ppd; spl_t s; int err; - rs = cobalt_current_resources(attr->pshared); - sys_ppd = cobalt_ppd_get(attr->pshared); - err = xnregistry_enter_anon(mutex, &shadow->handle); + err = xnregistry_enter_anon(mutex, &mutex->resnode.handle); if (err < 0) return err; - mutex->handle = shadow->handle; + sys_ppd = cobalt_ppd_get(attr->pshared); + shadow->handle = mutex->resnode.handle; shadow->magic = COBALT_MUTEX_MAGIC; shadow->lockcnt = 0; - shadow->attr = *attr; shadow->state_offset = cobalt_umm_offset(&sys_ppd->umm, state); @@ -54,45 +51,15 @@ static int cobalt_mutex_init_inner(struct cobalt_mutex_shadow *shadow, state->flags = (attr->type == PTHREAD_MUTEX_ERRORCHECK ? COBALT_MUTEX_ERRORCHECK : 0); mutex->attr = *attr; - mutex->scope = rs; INIT_LIST_HEAD(&mutex->conds); xnlock_get_irqsave(&nklock, s); - list_add_tail(&mutex->link, &rs->mutexq); + cobalt_add_resource(&mutex->resnode, mutex, attr->pshared); xnlock_put_irqrestore(&nklock, s); return 0; } -static void -cobalt_mutex_destroy_inner(xnhandle_t handle) -{ - struct cobalt_mutex *mutex; - spl_t s; - - xnlock_get_irqsave(&nklock, s); - mutex = xnregistry_lookup(handle, NULL); - if (!cobalt_obj_active(mutex, COBALT_MUTEX_MAGIC, typeof(*mutex))) { - xnlock_put_irqrestore(&nklock, s); - printk(XENO_WARNING "%s: invalid mutex %x\n", - __func__, mutex ? mutex->magic : ~0); - return; - } - xnregistry_remove(handle); - list_del(&mutex->link); - /* - * At this point, synchbase wait queue must be empty, so we - * don't need to reschedule. - */ - xnsynch_destroy(&mutex->synchbase); - cobalt_mark_deleted(mutex); - xnlock_put_irqrestore(&nklock, s); - - cobalt_umm_free(&cobalt_ppd_get(mutex->attr.pshared)->umm, - mutex->synchbase.fastlock); - xnfree(mutex); -} - /* must be called with nklock locked, interrupts off. */ int __cobalt_mutex_acquire_unchecked(struct xnthread *cur, struct cobalt_mutex *mutex, @@ -129,7 +96,8 @@ int cobalt_mutex_release(struct xnthread *cur, return -EINVAL; #if XENO_DEBUG(USER) - if (mutex->scope != cobalt_current_resources(mutex->attr.pshared)) + if (mutex->resnode.scope != + cobalt_current_resources(mutex->attr.pshared)) return -EPERM; #endif state = container_of(mutex->synchbase.fastlock, struct cobalt_mutex_state, owner); @@ -175,7 +143,8 @@ redo: goto out; } #if XENO_DEBUG(USER) - if (mutex->scope != cobalt_current_resources(mutex->attr.pshared)) { + if (mutex->resnode.scope != + cobalt_current_resources(mutex->attr.pshared)) { ret = -EPERM; goto out; } @@ -288,43 +257,42 @@ COBALT_SYSCALL(mutex_init, current, COBALT_SYSCALL(mutex_destroy, current, (struct cobalt_mutex_shadow __user *u_mx)) { - struct cobalt_mutex *mutex; struct cobalt_mutex_shadow mx; + struct cobalt_mutex *mutex; spl_t s; - int err; + int ret; if (cobalt_copy_from_user(&mx, u_mx, sizeof(mx))) return -EFAULT; xnlock_get_irqsave(&nklock, s); + mutex = xnregistry_lookup(mx.handle, NULL); if (!cobalt_obj_active(mutex, COBALT_MUTEX_MAGIC, typeof(*mutex))) { - err = -EINVAL; - goto err_unlock; + ret = -EINVAL; + goto fail; } - if (cobalt_current_resources(mutex->attr.pshared) != mutex->scope) { - err = -EPERM; - goto err_unlock; + if (cobalt_current_resources(mutex->attr.pshared) != + mutex->resnode.scope) { + ret = -EPERM; + goto fail; } - if (xnsynch_fast_owner_check(mutex->synchbase.fastlock, - XN_NO_HANDLE) != 0) { - err = -EBUSY; - goto err_unlock; + XN_NO_HANDLE) != 0 || + !list_empty(&mutex->conds)) { + ret = -EBUSY; + goto fail; } - if (!list_empty(&mutex->conds)) { - err = -EBUSY; - err_unlock: - xnlock_put_irqrestore(&nklock, s); - return err; - } + cobalt_mutex_reclaim(&mutex->resnode, s); /* drops lock */ cobalt_mark_deleted(&mx); - xnlock_put_irqrestore(&nklock, s); - cobalt_mutex_destroy_inner(mx.handle); return cobalt_copy_to_user(u_mx, &mx, sizeof(*u_mx)); +fail: + xnlock_put_irqrestore(&nklock, s); + + return ret; } COBALT_SYSCALL(mutex_trylock, primary, @@ -416,22 +384,20 @@ COBALT_SYSCALL(mutex_unlock, nonrestartable, return err; } -void cobalt_mutex_reclaim(struct cobalt_process *process) +void cobalt_mutex_reclaim(struct cobalt_resnode *node, spl_t s) { - struct cobalt_resources *p = &process->resources; - struct cobalt_mutex *mutex, *tmp; - spl_t s; - - xnlock_get_irqsave(&nklock, s); - - if (list_empty(&p->mutexq)) - goto out; + struct cobalt_mutex *mutex; + int pshared; - list_for_each_entry_safe(mutex, tmp, &p->mutexq, link) { - xnlock_put_irqrestore(&nklock, s); - cobalt_mutex_destroy_inner(mutex->handle); - xnlock_get_irqsave(&nklock, s); - } -out: + mutex = container_of(node, struct cobalt_mutex, resnode); + pshared = mutex->attr.pshared; + xnregistry_remove(node->handle); + cobalt_del_resource(node); + xnsynch_destroy(&mutex->synchbase); + cobalt_mark_deleted(mutex); xnlock_put_irqrestore(&nklock, s); + + cobalt_umm_free(&cobalt_ppd_get(pshared)->umm, + mutex->synchbase.fastlock); + xnfree(mutex); } diff --git a/kernel/cobalt/posix/mutex.h b/kernel/cobalt/posix/mutex.h index df1a537..ac1c502 100644 --- a/kernel/cobalt/posix/mutex.h +++ b/kernel/cobalt/posix/mutex.h @@ -22,6 +22,7 @@ #include "thread.h" #include <cobalt/uapi/mutex.h> #include <xenomai/posix/syscall.h> +#include <xenomai/posix/process.h> struct cobalt_process; @@ -29,11 +30,9 @@ struct cobalt_mutex { unsigned int magic; struct xnsynch synchbase; /** cobalt_mutexq */ - struct list_head link; struct list_head conds; struct cobalt_mutexattr attr; - struct cobalt_resources *scope; - xnhandle_t handle; + struct cobalt_resnode resnode; }; int __cobalt_mutex_timedlock_break(struct cobalt_mutex_shadow __user *u_mx, @@ -71,6 +70,7 @@ COBALT_SYSCALL_DECL(mutex_unlock, int cobalt_mutex_release(struct xnthread *cur, struct cobalt_mutex *mutex); -void cobalt_mutex_reclaim(struct cobalt_process *process); +void cobalt_mutex_reclaim(struct cobalt_resnode *node, + spl_t s); #endif /* !_COBALT_POSIX_MUTEX_H */ diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c index d29c7d4..15250dd 100644 --- a/kernel/cobalt/posix/process.c +++ b/kernel/cobalt/posix/process.c @@ -1405,9 +1405,9 @@ static void cobalt_process_detach(void *arg) struct cobalt_process *process = arg; cobalt_reclaim_resource(process, cobalt_cond_reclaim, cond); + cobalt_reclaim_resource(process, cobalt_mutex_reclaim, mutex); cobalt_nsem_reclaim(process); cobalt_timer_reclaim(process); - cobalt_mutex_reclaim(process); cobalt_sem_reclaim(process); cobalt_monitor_reclaim(process); cobalt_event_reclaim(process); _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git