Module: xenomai-forge Branch: next Commit: 0d506f94b0463ea80371784cffbff7f798074891 URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=0d506f94b0463ea80371784cffbff7f798074891
Author: Philippe Gerum <r...@xenomai.org> Date: Tue Feb 18 18:33:28 2014 +0100 copperplate/semobj: introduce semobj_inquire() --- include/copperplate/semobj.h | 9 +++++ lib/copperplate/semobj.c | 74 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/include/copperplate/semobj.h b/include/copperplate/semobj.h index d8928aa..f5de528 100644 --- a/include/copperplate/semobj.h +++ b/include/copperplate/semobj.h @@ -21,6 +21,11 @@ #include <copperplate/reference.h> +struct semobj_waitentry { + pid_t pid; + char name[32]; +}; + #ifdef CONFIG_XENO_COBALT #include <semaphore.h> @@ -69,6 +74,10 @@ int semobj_wait(struct semobj *smobj, int semobj_getvalue(struct semobj *smobj, int *sval); +int semobj_inquire(struct semobj *smobj, size_t waitsz, + struct semobj_waitentry *waitlist, + int *val_r); + #ifdef __cplusplus } #endif diff --git a/lib/copperplate/semobj.c b/lib/copperplate/semobj.c index 524d093..23e07a2 100644 --- a/lib/copperplate/semobj.c +++ b/lib/copperplate/semobj.c @@ -20,10 +20,13 @@ #include <errno.h> #include "copperplate/threadobj.h" #include "copperplate/semobj.h" +#include "copperplate/heapobj.h" #include "copperplate/debug.h" #ifdef CONFIG_XENO_COBALT +#include "cobalt/internal.h" + int semobj_init(struct semobj *smobj, int flags, int value, fnref_type(void (*)(struct semobj *smobj)) finalizer) { @@ -120,6 +123,49 @@ int semobj_getvalue(struct semobj *smobj, int *sval) return 0; } +int semobj_inquire(struct semobj *smobj, size_t waitsz, + struct semobj_waitentry *waitlist, + int *val_r) +{ + struct cobalt_threadstat stat; + struct cobalt_sem_info info; + int nrwait, pidsz, n, ret; + pid_t *pidlist = NULL; + + pidsz = sizeof(pid_t) * (waitsz / sizeof(*waitlist)); + if (pidsz > 0) { + pidlist = pvmalloc(pidsz); + if (pidlist == NULL) + return -ENOMEM; + } + + nrwait = cobalt_sem_inquire(&smobj->core.sem, &info, pidlist, pidsz); + if (nrwait < 0) + goto out; + + *val_r = info.value; + + if (pidlist == NULL) + return nrwait; + + for (n = 0; n < nrwait; n++, waitlist++) { + ret = __cobalt_thread_stat(pidlist[n], &stat); + /* If waiter disappeared, fill in a dummy entry. */ + if (ret) { + waitlist->pid = -1; + strcpy(waitlist->name, "???"); + } else { + waitlist->pid = pidlist[n]; + strcpy(waitlist->name, stat.name); + } + } +out: + if (pidlist) + pvfree(pidlist); + + return nrwait; +} + #else /* CONFIG_XENO_MERCURY */ static void semobj_finalize(struct syncobj *sobj) @@ -257,4 +303,32 @@ int semobj_getvalue(struct semobj *smobj, int *sval) return 0; } +int semobj_inquire(struct semobj *smobj, size_t waitsz, + struct semobj_waitentry *waitlist, + int *val_r) +{ + struct threadobj *thobj; + struct syncstate syns; + int ret, nrwait; + + ret = syncobj_lock(&smobj->core.sobj, &syns); + if (ret) + return ret; + + nrwait = syncobj_count_grant(&smobj->core.sobj); + if (nrwait > 0) { + syncobj_for_each_grant_waiter(&smobj->core.sobj, thobj) { + waitlist->pid = threadobj_get_pid(thobj); + strcpy(waitlist->name, threadobj_get_name(thobj)); + waitlist++; + } + } + + *val_r = smobj->core.value; + + syncobj_unlock(&smobj->core.sobj, &syns); + + return nrwait; +} + #endif /* CONFIG_XENO_MERCURY */ _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git