Module: xenomai-3
Branch: next
Commit: f72256ffc5c4b525749f7940119b42289565a9e0
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=f72256ffc5c4b525749f7940119b42289565a9e0

Author: Philippe Gerum <r...@xenomai.org>
Date:   Wed Mar 18 11:52:46 2015 +0100

cobalt/posix/process: introduce resource management API

We depart from POSIX with respect to the lifetime of pshared objects:
those will be automatically reclaimed by Cobalt upon exit from the
processes which created them.

---

 kernel/cobalt/posix/internal.h |   10 ---------
 kernel/cobalt/posix/process.c  |   48 +++++++++++++++++++++++++++++++++++-----
 kernel/cobalt/posix/process.h  |   43 ++++++++++++++++++++++++++++++++---
 3 files changed, 83 insertions(+), 18 deletions(-)

diff --git a/kernel/cobalt/posix/internal.h b/kernel/cobalt/posix/internal.h
index dd20972..ba33ebe 100644
--- a/kernel/cobalt/posix/internal.h
+++ b/kernel/cobalt/posix/internal.h
@@ -47,16 +47,6 @@
 
 #define cobalt_mark_deleted(t) ((t)->magic = ~(t)->magic)
 
-static inline struct cobalt_resources *cobalt_current_resources(int pshared)
-{
-       struct cobalt_process *process;
-
-       if (pshared || (process = cobalt_current_process()) == NULL)
-               return &cobalt_global_resources;
-
-       return &process->resources;
-}
-
 static inline xnhandle_t cobalt_get_handle_from_user(xnhandle_t *u_h)
 {
        xnhandle_t handle;
diff --git a/kernel/cobalt/posix/process.c b/kernel/cobalt/posix/process.c
index 9d93e43..15fae37 100644
--- a/kernel/cobalt/posix/process.c
+++ b/kernel/cobalt/posix/process.c
@@ -1362,19 +1362,57 @@ static void detach_process(struct cobalt_process 
*process)
        cobalt_umm_destroy(&p->umm);
 }
 
+static void __reclaim_resource(struct cobalt_process *process,
+                              void (*reclaim)(struct cobalt_resnode *node, 
spl_t s),
+                              struct list_head *local,
+                              struct list_head *global)
+{
+       struct cobalt_resnode *node, *tmp;
+       spl_t s;
+       
+       xnlock_get_irqsave(&nklock, s);
+
+       if (list_empty(global))
+               goto flush_local;
+
+       list_for_each_entry_safe(node, tmp, global, next) {
+               if (node->owner == process) {
+                       reclaim(node, s); /* drops lock */
+                       xnlock_get_irqsave(&nklock, s);
+               }
+       }
+               
+flush_local:
+       if (list_empty(local))
+               goto out;
+
+       list_for_each_entry_safe(node, tmp, local, next) {
+               reclaim(node, s); /* drops lock */
+               xnlock_get_irqsave(&nklock, s);
+       }
+out:
+       xnsched_run();
+       xnlock_put_irqrestore(&nklock, s);
+}
+
+#define cobalt_reclaim_resource(__process, __reclaim, __type)          \
+       __reclaim_resource(__process, __reclaim,                        \
+                          &(__process)->resources.__type ## q,         \
+                          &cobalt_global_resources.__type ## q)
+
 static void cobalt_process_detach(void *arg)
 {
        struct cobalt_process *process = arg;
 
        cobalt_nsem_reclaim(process);
-       cobalt_timer_reclaim(process);
+       cobalt_timer_reclaim(process);
        cobalt_cond_reclaim(process);
        cobalt_mutex_reclaim(process);
-       cobalt_sem_reclaim(process);
-       cobalt_monitor_reclaim(process);
+       cobalt_sem_reclaim(process);
+       cobalt_monitor_reclaim(process);
        cobalt_event_reclaim(process);
-       cobalt_sched_reclaim(process);
-       detach_process(process);
+       cobalt_sched_reclaim(process);
+       detach_process(process);
        /*
         * The cobalt_process descriptor release may be deferred until
         * the last mapping on the private heap is gone. However, this
diff --git a/kernel/cobalt/posix/process.h b/kernel/cobalt/posix/process.h
index 5891559..ee4b225 100644
--- a/kernel/cobalt/posix/process.h
+++ b/kernel/cobalt/posix/process.h
@@ -56,9 +56,12 @@ struct cobalt_process {
        void *priv[NR_PERSONALITIES];
 };
 
-extern struct list_head cobalt_thread_list;
-
-extern struct cobalt_resources cobalt_global_resources;
+struct cobalt_resnode {
+       struct cobalt_resources *scope;
+       struct cobalt_process *owner;
+       struct list_head next;
+       xnhandle_t handle;
+};
 
 int cobalt_register_personality(struct xnthread_personality *personality);
 
@@ -82,6 +85,10 @@ int cobalt_yield(xnticks_t min, xnticks_t max);
 
 int cobalt_process_init(void);
 
+extern struct list_head cobalt_thread_list;
+
+extern struct cobalt_resources cobalt_global_resources;
+
 static inline struct cobalt_process *cobalt_current_process(void)
 {
        return ipipe_current_threadinfo()->process;
@@ -109,6 +116,36 @@ static inline struct cobalt_ppd *cobalt_ppd_get(int global)
        return &process->sys_ppd;
 }
 
+static inline struct cobalt_resources *cobalt_current_resources(int pshared)
+{
+       struct cobalt_process *process;
+
+       if (pshared || (process = cobalt_current_process()) == NULL)
+               return &cobalt_global_resources;
+
+       return &process->resources;
+}
+
+static inline
+void __cobalt_add_resource(struct cobalt_resnode *node, int pshared)
+{
+       node->owner = cobalt_current_process();
+       node->scope = cobalt_current_resources(pshared);
+}
+
+#define cobalt_add_resource(__node, __type, __pshared)                 \
+       do {                                                            \
+               __cobalt_add_resource(__node, __pshared);               \
+               list_add_tail(&(__node)->next,                          \
+                             &((__node)->scope)->__type ## q);         \
+       } while (0)
+
+static inline
+void cobalt_del_resource(struct cobalt_resnode *node)
+{
+       list_del(&node->next);
+}
+
 extern struct xnthread_personality *cobalt_personalities[];
 
 extern struct xnthread_personality cobalt_personality;


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to