[Xenomai-git] Gilles Chanteperdrix : cobalt/sem: export through registry
Module: xenomai-forge Branch: master Commit: 07aab6ec30964b23a6a86b6be36360cabe8ec3de URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=07aab6ec30964b23a6a86b6be36360cabe8ec3de Author: Gilles Chanteperdrix Date: Sun Dec 15 17:09:32 2013 +0100 cobalt/sem: export through registry --- include/cobalt/uapi/sem.h|4 +- kernel/cobalt/posix/Makefile |1 + kernel/cobalt/posix/init.c |7 + kernel/cobalt/posix/nsem.c | 313 +++ kernel/cobalt/posix/sem.c| 574 +- kernel/cobalt/posix/sem.h| 33 ++- lib/cobalt/semaphore.c | 19 +- 7 files changed, 482 insertions(+), 469 deletions(-) diff --git a/include/cobalt/uapi/sem.h b/include/cobalt/uapi/sem.h index a1a9526..e011141 100644 --- a/include/cobalt/uapi/sem.h +++ b/include/cobalt/uapi/sem.h @@ -18,6 +18,8 @@ #ifndef _COBALT_UAPI_SEM_H #define _COBALT_UAPI_SEM_H +#include + #define COBALT_SEM_MAGIC (0x86860707) #define COBALT_NAMED_SEM_MAGIC (0x86860D0D) @@ -32,8 +34,8 @@ union cobalt_sem_union { sem_t native_sem; struct __shadow_sem { unsigned int magic; - struct cobalt_sem *sem; int datp_offset; + xnhandle_t handle; } shadow_sem; }; diff --git a/kernel/cobalt/posix/Makefile b/kernel/cobalt/posix/Makefile index d08442d..aad94a6 100644 --- a/kernel/cobalt/posix/Makefile +++ b/kernel/cobalt/posix/Makefile @@ -12,6 +12,7 @@ posix-y :=\ mutex_attr.o\ registry.o \ sem.o \ + nsem.o \ select.o\ signal.o\ syscall.o \ diff --git a/kernel/cobalt/posix/init.c b/kernel/cobalt/posix/init.c index 4676d27..02e0b08 100644 --- a/kernel/cobalt/posix/init.c +++ b/kernel/cobalt/posix/init.c @@ -64,6 +64,7 @@ MODULE_LICENSE("GPL"); void cobalt_cleanup(void) { cobalt_syscall_cleanup(); + cobalt_nsem_pkg_cleanup(); cobalt_timer_pkg_cleanup(); cobalt_monitor_pkg_cleanup(); cobalt_event_pkg_cleanup(); @@ -83,6 +84,12 @@ int __init cobalt_init(void) if (ret) return ret; + ret = cobalt_nsem_pkg_init(); + if (ret) { + cobalt_syscall_cleanup(); + return ret; + } + cobalt_reg_pkg_init(64, 128); /* FIXME: replace with compilation constants. */ cobalt_mutex_pkg_init(); cobalt_sem_pkg_init(); diff --git a/kernel/cobalt/posix/nsem.c b/kernel/cobalt/posix/nsem.c new file mode 100644 index 000..c19faaf --- /dev/null +++ b/kernel/cobalt/posix/nsem.c @@ -0,0 +1,313 @@ +/* + * Copyright (C) 2013 Gilles Chanteperdrix . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include "internal.h" +#include "sem.h" + +static struct hlist_head *nsem_hash; +DEFINE_XNLOCK(nsem_lock); +static unsigned mm_mult, mm_shift, nsem_hash_size; + +struct nsem { + struct cobalt_sem *sem; + struct mm_struct *mm; + struct __shadow_sem __user *usem; + unsigned refs; + struct hlist_node hlink; /* Link in global hash */ + struct list_head link; /* Link in per-process queue */ +}; + +static unsigned __attribute__((pure)) +nsem_hash_crunch(xnhandle_t handle, struct mm_struct *mm) +{ + unsigned long hash = (unsigned long)mm; + hash = handle + (((unsigned long long)hash * mm_mult) >> mm_shift); + return hash % nsem_hash_size; +} + +static struct nsem * +nsem_hash_search(xnhandle_t handle, struct mm_struct *mm) +{ + unsigned bucket = nsem_hash_crunch(handle, mm); + struct nsem *u; + + hlist_for_each_entry(u, &nsem_hash[bucket], hlink) + if (u->sem->handle == handle && u->mm == mm) + return u; + + return NULL; +} + +static void nsem_hash_enter(xnhandle_t handle, struct nsem *nsem) +{ + unsigned bucket = nsem_hash_crunch(handle, current->mm); + + hlist_add_head(&nsem->hlink, &nsem_hash[bucket]); +} + +static void nsem_hash_remove(struct nsem *u) +{ + hlist_del(&u->hlink); +} + +static struct __shadow_sem __user * +nsem_open(struct __shadow_sem __user *ushadow, const char *name, + int oflags, mode_t mode, unsigned va
[Xenomai-git] Gilles Chanteperdrix : cobalt/sem: export through registry
Module: xenomai-forge Branch: next Commit: 07aab6ec30964b23a6a86b6be36360cabe8ec3de URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=07aab6ec30964b23a6a86b6be36360cabe8ec3de Author: Gilles Chanteperdrix Date: Sun Dec 15 17:09:32 2013 +0100 cobalt/sem: export through registry --- include/cobalt/uapi/sem.h|4 +- kernel/cobalt/posix/Makefile |1 + kernel/cobalt/posix/init.c |7 + kernel/cobalt/posix/nsem.c | 313 +++ kernel/cobalt/posix/sem.c| 574 +- kernel/cobalt/posix/sem.h| 33 ++- lib/cobalt/semaphore.c | 19 +- 7 files changed, 482 insertions(+), 469 deletions(-) diff --git a/include/cobalt/uapi/sem.h b/include/cobalt/uapi/sem.h index a1a9526..e011141 100644 --- a/include/cobalt/uapi/sem.h +++ b/include/cobalt/uapi/sem.h @@ -18,6 +18,8 @@ #ifndef _COBALT_UAPI_SEM_H #define _COBALT_UAPI_SEM_H +#include + #define COBALT_SEM_MAGIC (0x86860707) #define COBALT_NAMED_SEM_MAGIC (0x86860D0D) @@ -32,8 +34,8 @@ union cobalt_sem_union { sem_t native_sem; struct __shadow_sem { unsigned int magic; - struct cobalt_sem *sem; int datp_offset; + xnhandle_t handle; } shadow_sem; }; diff --git a/kernel/cobalt/posix/Makefile b/kernel/cobalt/posix/Makefile index d08442d..aad94a6 100644 --- a/kernel/cobalt/posix/Makefile +++ b/kernel/cobalt/posix/Makefile @@ -12,6 +12,7 @@ posix-y :=\ mutex_attr.o\ registry.o \ sem.o \ + nsem.o \ select.o\ signal.o\ syscall.o \ diff --git a/kernel/cobalt/posix/init.c b/kernel/cobalt/posix/init.c index 4676d27..02e0b08 100644 --- a/kernel/cobalt/posix/init.c +++ b/kernel/cobalt/posix/init.c @@ -64,6 +64,7 @@ MODULE_LICENSE("GPL"); void cobalt_cleanup(void) { cobalt_syscall_cleanup(); + cobalt_nsem_pkg_cleanup(); cobalt_timer_pkg_cleanup(); cobalt_monitor_pkg_cleanup(); cobalt_event_pkg_cleanup(); @@ -83,6 +84,12 @@ int __init cobalt_init(void) if (ret) return ret; + ret = cobalt_nsem_pkg_init(); + if (ret) { + cobalt_syscall_cleanup(); + return ret; + } + cobalt_reg_pkg_init(64, 128); /* FIXME: replace with compilation constants. */ cobalt_mutex_pkg_init(); cobalt_sem_pkg_init(); diff --git a/kernel/cobalt/posix/nsem.c b/kernel/cobalt/posix/nsem.c new file mode 100644 index 000..c19faaf --- /dev/null +++ b/kernel/cobalt/posix/nsem.c @@ -0,0 +1,313 @@ +/* + * Copyright (C) 2013 Gilles Chanteperdrix . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include "internal.h" +#include "sem.h" + +static struct hlist_head *nsem_hash; +DEFINE_XNLOCK(nsem_lock); +static unsigned mm_mult, mm_shift, nsem_hash_size; + +struct nsem { + struct cobalt_sem *sem; + struct mm_struct *mm; + struct __shadow_sem __user *usem; + unsigned refs; + struct hlist_node hlink; /* Link in global hash */ + struct list_head link; /* Link in per-process queue */ +}; + +static unsigned __attribute__((pure)) +nsem_hash_crunch(xnhandle_t handle, struct mm_struct *mm) +{ + unsigned long hash = (unsigned long)mm; + hash = handle + (((unsigned long long)hash * mm_mult) >> mm_shift); + return hash % nsem_hash_size; +} + +static struct nsem * +nsem_hash_search(xnhandle_t handle, struct mm_struct *mm) +{ + unsigned bucket = nsem_hash_crunch(handle, mm); + struct nsem *u; + + hlist_for_each_entry(u, &nsem_hash[bucket], hlink) + if (u->sem->handle == handle && u->mm == mm) + return u; + + return NULL; +} + +static void nsem_hash_enter(xnhandle_t handle, struct nsem *nsem) +{ + unsigned bucket = nsem_hash_crunch(handle, current->mm); + + hlist_add_head(&nsem->hlink, &nsem_hash[bucket]); +} + +static void nsem_hash_remove(struct nsem *u) +{ + hlist_del(&u->hlink); +} + +static struct __shadow_sem __user * +nsem_open(struct __shadow_sem __user *ushadow, const char *name, + int oflags, mode_t mode, unsigned valu