[Xenomai-git] Gilles Chanteperdrix : cobalt: use registry for mutexes
Module: xenomai-gch Branch: for-forge Commit: f8cb05152e77d6d81ec320127df6c58913c46486 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=f8cb05152e77d6d81ec320127df6c58913c46486 Author: Gilles Chanteperdrix gilles.chanteperd...@xenomai.org Date: Thu Dec 5 22:07:48 2013 +0100 cobalt: use registry for mutexes --- include/cobalt/uapi/mutex.h |2 +- kernel/cobalt/posix/cond.c |8 ++- kernel/cobalt/posix/mutex.c | 127 +-- kernel/cobalt/posix/mutex.h |1 + 4 files changed, 94 insertions(+), 44 deletions(-) diff --git a/include/cobalt/uapi/mutex.h b/include/cobalt/uapi/mutex.h index dec09e2..88c95e7 100644 --- a/include/cobalt/uapi/mutex.h +++ b/include/cobalt/uapi/mutex.h @@ -32,7 +32,7 @@ union cobalt_mutex_union { struct __shadow_mutex { unsigned int magic; unsigned int lockcnt; - struct cobalt_mutex *mutex; + xnhandle_t handle; union { unsigned int dat_offset; struct mutex_dat *dat; diff --git a/kernel/cobalt/posix/cond.c b/kernel/cobalt/posix/cond.c index 571bdc7..5572431 100644 --- a/kernel/cobalt/posix/cond.c +++ b/kernel/cobalt/posix/cond.c @@ -400,10 +400,12 @@ int cobalt_cond_wait_prologue(struct __shadow_cond __user *u_cnd, struct mutex_dat *datp; struct us_cond_data d; struct timespec ts; + xnhandle_t handle; int err, perr = 0; __xn_get_user(cnd, u_cnd-cond); - __xn_get_user(mx, u_mx-mutex); + __xn_get_user(handle, u_mx-handle); + mx = xnregistry_fetch(handle); if (!cnd-mutex) { __xn_get_user(datp, u_mx-dat); @@ -456,10 +458,12 @@ int cobalt_cond_wait_epilogue(struct __shadow_cond __user *u_cnd, xnthread_t *cur = xnshadow_current(); struct cobalt_cond *cnd; struct cobalt_mutex *mx; + xnhandle_t handle; int err; __xn_get_user(cnd, u_cnd-cond); - __xn_get_user(mx, u_mx-mutex); + __xn_get_user(handle, u_mx-handle); + mx = xnregistry_fetch(handle); err = cobalt_cond_timedwait_epilogue(cur, cnd, mx); diff --git a/kernel/cobalt/posix/mutex.c b/kernel/cobalt/posix/mutex.c index 2b1c515..c94ed79 100644 --- a/kernel/cobalt/posix/mutex.c +++ b/kernel/cobalt/posix/mutex.c @@ -62,6 +62,7 @@ static int cobalt_mutex_init_inner(struct __shadow_mutex *shadow, struct xnsys_ppd *sys_ppd; struct cobalt_kqueues *kq; spl_t s; + int err; if (!attr) attr = cobalt_default_mutex_attr; @@ -71,9 +72,12 @@ static int cobalt_mutex_init_inner(struct __shadow_mutex *shadow, kq = cobalt_kqueues(attr-pshared); sys_ppd = xnsys_ppd_get(attr-pshared); + err = xnregistry_enter(, mutex, shadow-handle, NULL); + if (err 0) + return err; + mutex-handle = shadow-handle; shadow-magic = COBALT_MUTEX_MAGIC; - shadow-mutex = mutex; shadow-lockcnt = 0; shadow-attr = *attr; @@ -97,12 +101,21 @@ static int cobalt_mutex_init_inner(struct __shadow_mutex *shadow, return 0; } -static void cobalt_mutex_destroy_inner(struct cobalt_mutex *mutex, - struct cobalt_kqueues *q) +static void +cobalt_mutex_destroy_inner(xnhandle_t handle, struct cobalt_kqueues *q) { + struct cobalt_mutex *mutex; spl_t s; xnlock_get_irqsave(nklock, s); + mutex = xnregistry_fetch(handle); + if (!cobalt_obj_active(mutex, COBALT_MUTEX_MAGIC, typeof(*mutex))) { + xnlock_put_irqrestore(nklock, s); + printk(mutex_destroy: invalid mutex %x\n, + mutex ? mutex-magic : ~0); + return; + } + xnregistry_remove(handle); list_del(mutex-link); /* * synchbase wait queue may not be empty only when this @@ -110,6 +123,7 @@ static void cobalt_mutex_destroy_inner(struct cobalt_mutex *mutex, * absence of xnsched_run(). */ xnsynch_destroy(mutex-synchbase); + cobalt_mark_deleted(mutex); xnlock_put_irqrestore(nklock, s); xnheap_free(xnsys_ppd_get(mutex-attr.pshared)-sem_heap, @@ -240,30 +254,23 @@ int cobalt_mutex_timedlock_break(struct cobalt_mutex *mutex, int cobalt_mutex_check_init(struct __shadow_mutex __user *u_mx) { - struct list_head *mutexq, *entry; struct cobalt_mutex *mutex; - int qnr; + xnhandle_t handle; + int err; spl_t s; - __xn_get_user(mutex, u_mx-mutex); + __xn_get_user(handle, u_mx-handle); - for (qnr = 0; qnr 2; qnr++) { - mutexq = cobalt_kqueues(qnr)-mutexq; - xnlock_get_irqsave(nklock, s); - if (!list_empty(mutexq)) { - list_for_each(entry, mutexq) { - if (entry == mutex-link)
[Xenomai-git] Gilles Chanteperdrix : cobalt: use registry for condvars
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); -
[Xenomai-git] Gilles Chanteperdrix : cobalt/registry: convert open coded single-linked list to hlist
Module: xenomai-gch Branch: for-forge Commit: f6bd635cb96a99084bd0f9f45bfa8c231c38a6de URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=f6bd635cb96a99084bd0f9f45bfa8c231c38a6de Author: Gilles Chanteperdrix gilles.chanteperd...@xenomai.org Date: Sun Dec 15 21:02:55 2013 +0100 cobalt/registry: convert open coded single-linked list to hlist --- include/cobalt/kernel/registry.h |2 +- kernel/cobalt/registry.c | 38 +++--- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/include/cobalt/kernel/registry.h b/include/cobalt/kernel/registry.h index 5197542..7bbb99d 100644 --- a/include/cobalt/kernel/registry.h +++ b/include/cobalt/kernel/registry.h @@ -50,7 +50,7 @@ struct xnobject { } vfile_u; struct xnvfile *vfilp; #endif /* CONFIG_XENO_OPT_VFILE */ - struct xnobject *hnext; /* ! Next in h-table */ + struct hlist_node hlink; /* ! Link in h-table */ struct list_head link; }; diff --git a/kernel/cobalt/registry.c b/kernel/cobalt/registry.c index 004bc96..794a27e 100644 --- a/kernel/cobalt/registry.c +++ b/kernel/cobalt/registry.c @@ -53,7 +53,7 @@ static unsigned int nr_active_objects; static unsigned long next_object_stamp; -static struct xnobject **object_index; +static struct hlist_head *object_index; static int nr_object_entries; @@ -145,7 +145,7 @@ int xnregistry_init(void) nr_object_entries = primes[obj_hash_max(CONFIG_XENO_OPT_REGISTRY_NRSLOTS / 100)]; - object_index = kmalloc(sizeof(struct xnobject *) * + object_index = kmalloc(sizeof(*object_index) * nr_object_entries, GFP_KERNEL); if (object_index == NULL) { @@ -158,7 +158,7 @@ int xnregistry_init(void) } for (n = 0; n nr_object_entries; n++) - object_index[n] = NULL; + INIT_HLIST_HEAD(object_index[n]); xnsynch_init(register_synch, XNSYNCH_FIFO, NULL); @@ -168,15 +168,16 @@ int xnregistry_init(void) void xnregistry_cleanup(void) { #ifdef CONFIG_XENO_OPT_VFILE - struct xnobject *ecurr, *enext; + struct hlist_node *enext; + struct xnobject *ecurr; struct xnpnode *pnode; int n; flush_scheduled_work(); for (n = 0; n nr_object_entries; n++) - for (ecurr = object_index[n]; ecurr; ecurr = enext) { - enext = ecurr-hnext; + hlist_for_each_entry_safe(ecurr, enext, + object_index[n], hlink) { pnode = ecurr-pnode; if (pnode == NULL) continue; @@ -190,7 +191,7 @@ void xnregistry_cleanup(void) if (--pnode-root-entries == 0) xnvfile_destroy_dir(pnode-root-vdir); - } + } #endif /* CONFIG_XENO_OPT_VFILE */ kfree(object_index); @@ -522,13 +523,11 @@ static inline int registry_hash_enter(const char *key, struct xnobject *object) object-key = key; s = registry_hash_crunch(key); - for (ecurr = object_index[s]; ecurr != NULL; ecurr = ecurr-hnext) { + hlist_for_each_entry(ecurr, object_index[s], hlink) if (ecurr == object || strcmp(key, ecurr-key) == 0) return -EEXIST; - } - object-hnext = object_index[s]; - object_index[s] = object; + hlist_add_head(object-hlink, object_index[s]); return 0; } @@ -536,19 +535,13 @@ static inline int registry_hash_enter(const char *key, struct xnobject *object) static inline int registry_hash_remove(struct xnobject *object) { unsigned int s = registry_hash_crunch(object-key); - struct xnobject *ecurr, *eprev; + struct xnobject *ecurr; - for (ecurr = object_index[s], eprev = NULL; -ecurr != NULL; eprev = ecurr, ecurr = ecurr-hnext) { + hlist_for_each_entry(ecurr, object_index[s], hlink) if (ecurr == object) { - if (eprev) - eprev-hnext = ecurr-hnext; - else - object_index[s] = ecurr-hnext; - + hlist_del(ecurr-hlink); return 0; } - } return -ESRCH; } @@ -557,11 +550,10 @@ static struct xnobject *registry_hash_find(const char *key) { struct xnobject *ecurr; - for (ecurr = object_index[registry_hash_crunch(key)]; -ecurr != NULL; ecurr = ecurr-hnext) { + hlist_for_each_entry(ecurr, + object_index[registry_hash_crunch(key)], hlink) if (strcmp(key, ecurr-key) == 0) return ecurr; - } return NULL; } ___ Xenomai-git mailing list Xenomai-git@xenomai.org
[Xenomai-git] Gilles Chanteperdrix : cobalt/registry: add unlink service
Module: xenomai-gch Branch: for-forge Commit: f470bba259308633cdab24c257a522069767f7a8 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=f470bba259308633cdab24c257a522069767f7a8 Author: Gilles Chanteperdrix gilles.chanteperd...@xenomai.org Date: Mon Dec 9 22:04:38 2013 +0100 cobalt/registry: add unlink service --- include/cobalt/kernel/registry.h |2 ++ kernel/cobalt/registry.c | 43 ++ 2 files changed, 45 insertions(+) diff --git a/include/cobalt/kernel/registry.h b/include/cobalt/kernel/registry.h index d2906db..6c25eee 100644 --- a/include/cobalt/kernel/registry.h +++ b/include/cobalt/kernel/registry.h @@ -184,6 +184,8 @@ void *xnregistry_fetch(xnhandle_t handle); unsigned long xnregistry_put(xnhandle_t handle); +int xnregistry_unlink(const char *key); + extern struct xnpnode_ops xnregistry_vfsnap_ops; extern struct xnpnode_ops xnregistry_vlink_ops; diff --git a/kernel/cobalt/registry.c b/kernel/cobalt/registry.c index cebd5f0..004bc96 100644 --- a/kernel/cobalt/registry.c +++ b/kernel/cobalt/registry.c @@ -881,6 +881,49 @@ unlock_and_exit: EXPORT_SYMBOL_GPL(xnregistry_remove); /** + * Turn a named object into an anonymous object + */ +int xnregistry_unlink(const char *key) +{ + struct xnobject *object; + int ret = 0; + spl_t s; + + xnlock_get_irqsave(nklock, s); + + object = registry_hash_find(key); + if (object == NULL) { + ret = -ESRCH; + goto unlock_and_exit; + } + + ret = registry_hash_remove(object); + if (ret 0) + goto unlock_and_exit; + +#ifdef CONFIG_XENO_OPT_VFILE + if (object-pnode) { + registry_unexport_pnode(object); + /* +* Leave the update of the object queues to +* the work callback if it has been kicked. +*/ + if (object-pnode) + goto unlock_and_exit; + } +#endif /* CONFIG_XENO_OPT_VFILE */ + + list_del(object-link); + + object-key = NULL; + +unlock_and_exit: + xnlock_put_irqrestore(nklock, s); + + return ret; +} + +/** * @fn int xnregistry_remove_safe(xnhandle_t handle,xnticks_t timeout) * @brief Unregister an idle real-time object. * ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Gilles Chanteperdrix : cobalt/registry: allow to retrieve an object key from its handle
Module: xenomai-gch Branch: for-forge Commit: 0ba78c15f892e5fab25b8a83521fbbb26b0749b9 URL: http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=0ba78c15f892e5fab25b8a83521fbbb26b0749b9 Author: Gilles Chanteperdrix gilles.chanteperd...@xenomai.org Date: Sun Dec 15 17:08:54 2013 +0100 cobalt/registry: allow to retrieve an object key from its handle --- include/cobalt/kernel/registry.h |6 ++ 1 file changed, 6 insertions(+) diff --git a/include/cobalt/kernel/registry.h b/include/cobalt/kernel/registry.h index 6c25eee..5197542 100644 --- a/include/cobalt/kernel/registry.h +++ b/include/cobalt/kernel/registry.h @@ -163,6 +163,12 @@ static inline void *xnregistry_lookup(xnhandle_t handle) return object ? object-objaddr : NULL; } +static inline const char *xnregistry_key(xnhandle_t handle) +{ + struct xnobject *object = xnregistry_validate(handle); + return object ? object-key : NULL; +} + int xnregistry_enter(const char *key, void *objaddr, xnhandle_t *phandle, ___ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git