Module: xenomai-gch
Branch: for-forge
Commit: 1031cd2be9e79e03ba858b5c4afcac35a7fac30a
URL:    
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=1031cd2be9e79e03ba858b5c4afcac35a7fac30a

Author: Philippe Gerum <r...@xenomai.org>
Date:   Thu Nov 10 17:46:38 2011 +0100

copperplate, lib: introduce thread creation wrapper

We need to create threads abiding by the SCHED_COBALT extended policy
when running over the Cobalt core, which won't be allowed via the
regular pthread_create() call. Conversely, client libraries may only
request to create threads into the SCHED_FIFO, SCHED_RR or SCHED_OTHER
classes, using the common POSIX interface.

To solve this, we introduce the copperplate_create_thread() wrapper,
with a core-specific implementation.

---

 lib/alchemy/Makefile.am           |    3 +-
 lib/alchemy/Makefile.in           |    3 +-
 lib/alchemy/task.c                |   28 +++---------------
 lib/copperplate/internal.c        |   55 +++++++++++++++++++++++++++++++++++++
 lib/copperplate/internal.h        |    4 +++
 lib/copperplate/timerobj-cobalt.c |   15 ++++------
 lib/psos/Makefile.am              |    3 +-
 lib/psos/Makefile.in              |    3 +-
 lib/psos/task.c                   |   39 +++++++-------------------
 lib/vxworks/Makefile.am           |    3 +-
 lib/vxworks/Makefile.in           |    3 +-
 lib/vxworks/taskLib.c             |   37 ++++++-------------------
 12 files changed, 101 insertions(+), 95 deletions(-)

diff --git a/lib/alchemy/Makefile.am b/lib/alchemy/Makefile.am
index 096953f..4632394 100644
--- a/lib/alchemy/Makefile.am
+++ b/lib/alchemy/Makefile.am
@@ -30,7 +30,8 @@ libalchemy_la_SOURCES =       \
 
 libalchemy_la_CPPFLAGS = \
        @XENO_USER_CFLAGS@ \
-       -I$(top_srcdir)/include
+       -I$(top_srcdir)/include \
+       -I$(top_srcdir)/lib
 
 EXTRA_DIST = testsuite
 
diff --git a/lib/alchemy/Makefile.in b/lib/alchemy/Makefile.in
index f1a5a4e..43be5b4 100644
--- a/lib/alchemy/Makefile.in
+++ b/lib/alchemy/Makefile.in
@@ -292,7 +292,8 @@ libalchemy_la_SOURCES = \
 
 libalchemy_la_CPPFLAGS = \
        @XENO_USER_CFLAGS@ \
-       -I$(top_srcdir)/include
+       -I$(top_srcdir)/include \
+       -I$(top_srcdir)/lib
 
 EXTRA_DIST = testsuite
 SPARSE = sparse
diff --git a/lib/alchemy/task.c b/lib/alchemy/task.c
index c2a7a2b..8d4b921 100644
--- a/lib/alchemy/task.c
+++ b/lib/alchemy/task.c
@@ -19,11 +19,11 @@
 #include <assert.h>
 #include <sched.h>
 #include <pthread.h>
-#include <limits.h>
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
-#include <copperplate/heapobj.h>
+#include "copperplate/heapobj.h"
+#include "copperplate/internal.h"
 #include "internal.h"
 #include "task.h"
 #include "buffer.h"
@@ -278,10 +278,8 @@ int rt_task_create(RT_TASK *task, const char *name,
                   int stksize, int prio, int mode)
 {
        struct alchemy_task *tcb;
-       struct sched_param param;
-       pthread_attr_t thattr;
        struct service svc;
-       int policy, ret;
+       int ret;
 
        COPPERPLATE_PROTECT(svc);
 
@@ -293,24 +291,8 @@ int rt_task_create(RT_TASK *task, const char *name,
        task->handle = mainheap_ref(tcb, uintptr_t);
        tcb->self = *task;
 
-       pthread_attr_init(&thattr);
-
-       if (stksize < PTHREAD_STACK_MIN * 4)
-               stksize = PTHREAD_STACK_MIN * 4;
-
-       memset(&param, 0, sizeof(param));
-       param.sched_priority = prio;
-       policy = prio ? SCHED_RT : SCHED_OTHER;
-       pthread_attr_setinheritsched(&thattr, PTHREAD_EXPLICIT_SCHED);
-       pthread_attr_setschedpolicy(&thattr, policy);
-       pthread_attr_setschedparam(&thattr, &param);
-       pthread_attr_setstacksize(&thattr, stksize);
-       pthread_attr_setscope(&thattr, thread_scope_attribute);
-       pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
-
-       ret = __bt(-__RT(pthread_create(&tcb->thobj.tid, &thattr,
-                                       task_trampoline, tcb)));
-       pthread_attr_destroy(&thattr);
+       ret = __bt(copperplate_create_thread(prio, task_trampoline, tcb,
+                                            stksize, &tcb->thobj.tid));
        if (ret)
                delete_tcb(tcb);
 out:
diff --git a/lib/copperplate/internal.c b/lib/copperplate/internal.c
index 4d4cf45..0f69610 100644
--- a/lib/copperplate/internal.c
+++ b/lib/copperplate/internal.c
@@ -24,6 +24,7 @@
 #include <unistd.h>
 #include <signal.h>
 #include <errno.h>
+#include <limits.h>
 #include <linux/unistd.h>
 #include <copperplate/clockobj.h>
 #include <copperplate/threadobj.h>
@@ -64,6 +65,33 @@ int copperplate_probe_node(unsigned int id)
        return pthread_probe_np((pid_t)id) == 0;
 }
 
+int copperplate_create_thread(int prio,
+                             void *(*start)(void *arg), void *arg,
+                             size_t stacksize,
+                             pthread_t *tid)
+{
+       struct sched_param_ex param_ex;
+       pthread_attr_ex_t attr_ex;
+       int policy, ret;
+
+       if (stacksize < PTHREAD_STACK_MIN * 4)
+               stacksize = PTHREAD_STACK_MIN * 4;
+
+       param_ex.sched_priority = prio;
+       policy = prio ? SCHED_RT : SCHED_OTHER;
+       pthread_attr_init_ex(&attr_ex);
+       pthread_attr_setinheritsched_ex(&attr_ex, PTHREAD_EXPLICIT_SCHED);
+       pthread_attr_setschedpolicy_ex(&attr_ex, policy);
+       pthread_attr_setschedparam_ex(&attr_ex, &param_ex);
+       pthread_attr_setstacksize_ex(&attr_ex, stacksize);
+       pthread_attr_setscope_ex(&attr_ex, thread_scope_attribute);
+       pthread_attr_setdetachstate_ex(&attr_ex, PTHREAD_CREATE_JOINABLE);
+       ret = __bt(-pthread_create_ex(tid, &attr_ex, start, arg));
+       pthread_attr_destroy_ex(&attr_ex);
+
+       return ret;
+}
+
 #else /* CONFIG_XENO_MERCURY */
 
 int copperplate_probe_node(unsigned int id)
@@ -71,6 +99,33 @@ int copperplate_probe_node(unsigned int id)
        return kill((pid_t)id, 0) == 0;
 }
 
+int copperplate_create_thread(int prio,
+                             void *(*start)(void *arg), void *arg,
+                             size_t stacksize,
+                             pthread_t *tid)
+{
+       struct sched_param param;
+       pthread_attr_t attr;
+       int policy, ret;
+
+       if (stacksize < PTHREAD_STACK_MIN * 4)
+               stacksize = PTHREAD_STACK_MIN * 4;
+
+       param.sched_priority = prio;
+       policy = prio ? SCHED_RT : SCHED_OTHER;
+       pthread_attr_init(&attr);
+       pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+       pthread_attr_setschedpolicy(&attr, policy);
+       pthread_attr_setschedparam(&attr, &param);
+       pthread_attr_setstacksize(&attr, stacksize);
+       pthread_attr_setscope(&attr, thread_scope_attribute);
+       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+       ret = __bt(-pthread_create(tid, &attr, start, arg));
+       pthread_attr_destroy(&attr);
+
+       return ret;
+}
+
 #endif  /* CONFIG_XENO_MERCURY */
 
 void __printout(struct threadobj *thobj,
diff --git a/lib/copperplate/internal.h b/lib/copperplate/internal.h
index 1954d5f..8168310 100644
--- a/lib/copperplate/internal.h
+++ b/lib/copperplate/internal.h
@@ -69,6 +69,10 @@ pid_t copperplate_get_tid(void);
 
 int copperplate_probe_node(unsigned int id);
 
+int copperplate_create_thread(int prio,
+                             void *(*start)(void *arg), void *arg,
+                             size_t stacksize,
+                             pthread_t *tid);
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/copperplate/timerobj-cobalt.c 
b/lib/copperplate/timerobj-cobalt.c
index d3c956f..772dea7 100644
--- a/lib/copperplate/timerobj-cobalt.c
+++ b/lib/copperplate/timerobj-cobalt.c
@@ -31,6 +31,7 @@
 #include "copperplate/timerobj.h"
 #include "copperplate/clockobj.h"
 #include "copperplate/debug.h"
+#include "internal.h"
 
 static sem_t svsem;
 
@@ -132,8 +133,6 @@ static void *timerobj_server(void *arg)
 
 static int timerobj_spawn_server(void)
 {
-       struct sched_param param;
-       pthread_attr_t thattr;
        int ret = 0;
 
        push_cleanup_lock(&svlock);
@@ -142,17 +141,15 @@ static int timerobj_spawn_server(void)
        if (svthread)
                goto out;
 
-       pthread_attr_init(&thattr);
-       pthread_attr_setschedpolicy(&thattr, SCHED_RT);
-       memset(&param, 0, sizeof(param));
-       param.sched_priority = threadobj_irq_prio;
-       pthread_attr_setschedparam(&thattr, &param);
-       ret = __RT(pthread_create(&svthread, &thattr, timerobj_server, NULL));
+       ret = __bt(copperplate_create_thread(threadobj_irq_prio,
+                                            timerobj_server, NULL,
+                                            PTHREAD_STACK_MIN * 16,
+                                            &svthread));
 out:
        read_unlock(&svlock);
        pop_cleanup_lock(&svlock);
 
-       return __bt(ret);
+       return ret;
 }
 
 int timerobj_init(struct timerobj *tmobj)
diff --git a/lib/psos/Makefile.am b/lib/psos/Makefile.am
index 1081c6e..ce6a9ee 100644
--- a/lib/psos/Makefile.am
+++ b/lib/psos/Makefile.am
@@ -21,7 +21,8 @@ libpsos_la_SOURCES =  \
 
 libpsos_la_CPPFLAGS = \
        @XENO_USER_CFLAGS@ \
-       -I$(top_srcdir)/include
+       -I$(top_srcdir)/include \
+       -I$(top_srcdir)/lib
 
 EXTRA_DIST = testsuite
 
diff --git a/lib/psos/Makefile.in b/lib/psos/Makefile.in
index e9e2090..29ea257 100644
--- a/lib/psos/Makefile.in
+++ b/lib/psos/Makefile.in
@@ -280,7 +280,8 @@ libpsos_la_SOURCES = \
 
 libpsos_la_CPPFLAGS = \
        @XENO_USER_CFLAGS@ \
-       -I$(top_srcdir)/include
+       -I$(top_srcdir)/include \
+       -I$(top_srcdir)/lib
 
 EXTRA_DIST = testsuite
 SPARSE = sparse
diff --git a/lib/psos/task.c b/lib/psos/task.c
index 88b87be..734a9fd 100644
--- a/lib/psos/task.c
+++ b/lib/psos/task.c
@@ -25,14 +25,14 @@
 #include <pthread.h>
 #include <assert.h>
 #include <sched.h>
-#include <limits.h>
-#include <copperplate/init.h>
-#include <copperplate/heapobj.h>
-#include <copperplate/threadobj.h>
-#include <copperplate/syncobj.h>
-#include <copperplate/clockobj.h>
-#include <copperplate/cluster.h>
-#include <psos/psos.h>
+#include "copperplate/init.h"
+#include "copperplate/heapobj.h"
+#include "copperplate/threadobj.h"
+#include "copperplate/syncobj.h"
+#include "copperplate/clockobj.h"
+#include "copperplate/cluster.h"
+#include "copperplate/internal.h"
+#include "psos/psos.h"
 #include "internal.h"
 #include "task.h"
 #include "tm.h"
@@ -247,9 +247,7 @@ u_long t_create(const char *name, u_long prio,
                u_long sstack, u_long ustack, u_long flags, u_long *tid_r)
 {
        struct threadobj_init_data idata;
-       struct sched_param param;
        struct psos_task *task;
-       pthread_attr_t thattr;
        struct syncstate syns;
        struct service svc;
        int ret, cprio = 1;
@@ -304,22 +302,6 @@ u_long t_create(const char *name, u_long prio,
                goto fail;
        }
 
-       pthread_attr_init(&thattr);
-
-       if (ustack == 0)
-               ustack = PTHREAD_STACK_MIN * 4;
-       else if (ustack < PTHREAD_STACK_MIN)
-               ustack = PTHREAD_STACK_MIN;
-
-       memset(&param, 0, sizeof(param));
-       param.sched_priority = cprio;
-       pthread_attr_setinheritsched(&thattr, PTHREAD_EXPLICIT_SCHED);
-       pthread_attr_setschedpolicy(&thattr, SCHED_RT);
-       pthread_attr_setschedparam(&thattr, &param);
-       pthread_attr_setstacksize(&thattr, ustack);
-       pthread_attr_setscope(&thattr, thread_scope_attribute);
-       pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
-
        idata.magic = task_magic;
        idata.wait_hook = NULL;
        idata.suspend_hook = NULL;
@@ -327,9 +309,8 @@ u_long t_create(const char *name, u_long prio,
        idata.priority = cprio;
        threadobj_init(&task->thobj, &idata);
 
-       ret = __bt(-__RT(pthread_create(&task->thobj.tid, &thattr,
-                                       &task_trampoline, task)));
-       pthread_attr_destroy(&thattr);
+       ret = __bt(copperplate_create_thread(cprio, task_trampoline, task,
+                                            ustack, &task->thobj.tid));
        if (ret) {
                cluster_delobj(&psos_task_table, &task->cobj);
                threadobj_destroy(&task->thobj);
diff --git a/lib/vxworks/Makefile.am b/lib/vxworks/Makefile.am
index 549d578..bec9d93 100644
--- a/lib/vxworks/Makefile.am
+++ b/lib/vxworks/Makefile.am
@@ -27,7 +27,8 @@ libvxworks_la_SOURCES = \
 
 libvxworks_la_CPPFLAGS = \
        @XENO_USER_CFLAGS@ \
-       -I$(top_srcdir)/include
+       -I$(top_srcdir)/include \
+       -I$(top_srcdir)/lib
 
 EXTRA_DIST = testsuite
 
diff --git a/lib/vxworks/Makefile.in b/lib/vxworks/Makefile.in
index bf6c4a4..c9c14bb 100644
--- a/lib/vxworks/Makefile.in
+++ b/lib/vxworks/Makefile.in
@@ -290,7 +290,8 @@ libvxworks_la_SOURCES = \
 
 libvxworks_la_CPPFLAGS = \
        @XENO_USER_CFLAGS@ \
-       -I$(top_srcdir)/include
+       -I$(top_srcdir)/include \
+       -I$(top_srcdir)/lib
 
 EXTRA_DIST = testsuite
 SPARSE = sparse
diff --git a/lib/vxworks/taskLib.c b/lib/vxworks/taskLib.c
index f7ab858..71771b5 100644
--- a/lib/vxworks/taskLib.c
+++ b/lib/vxworks/taskLib.c
@@ -26,15 +26,15 @@
 #include <assert.h>
 #include <fcntl.h>
 #include <sched.h>
-#include <limits.h>
 #include "taskLib.h"
 #include "tickLib.h"
-#include <copperplate/init.h>
-#include <copperplate/heapobj.h>
-#include <copperplate/threadobj.h>
-#include <copperplate/syncobj.h>
-#include <copperplate/cluster.h>
-#include <vxworks/errnoLib.h>
+#include "copperplate/init.h"
+#include "copperplate/heapobj.h"
+#include "copperplate/threadobj.h"
+#include "copperplate/syncobj.h"
+#include "copperplate/cluster.h"
+#include "copperplate/internal.h"
+#include "vxworks/errnoLib.h"
 
 union wind_wait_union {
 };
@@ -312,8 +312,6 @@ static STATUS __taskInit(struct wind_task *task,
 {
        struct threadobj_init_data idata;
        pthread_mutexattr_t mattr;
-       struct sched_param param;
-       pthread_attr_t thattr;
        int ret, cprio;
 
        ret = check_task_priority(prio, &cprio);
@@ -352,22 +350,6 @@ static STATUS __taskInit(struct wind_task *task,
        tcb->flags = flags;
        tcb->entry = entry;
 
-       pthread_attr_init(&thattr);
-
-       if (stacksize == 0)
-               stacksize = PTHREAD_STACK_MIN * 4;
-       else if (stacksize < PTHREAD_STACK_MIN)
-               stacksize = PTHREAD_STACK_MIN;
-
-       memset(&param, 0, sizeof(param));
-       param.sched_priority = cprio;
-       pthread_attr_setinheritsched(&thattr, PTHREAD_EXPLICIT_SCHED);
-       pthread_attr_setschedpolicy(&thattr, SCHED_RT);
-       pthread_attr_setschedparam(&thattr, &param);
-       pthread_attr_setstacksize(&thattr, stacksize);
-       pthread_attr_setscope(&thattr, thread_scope_attribute);
-       pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
-
        idata.magic = task_magic;
        idata.wait_hook = task_wait_hook;
        idata.suspend_hook = task_suspend_hook;
@@ -386,9 +368,8 @@ static STATUS __taskInit(struct wind_task *task,
 
        registry_init_file(&task->fsobj, &registry_ops);
 
-       ret = __bt(-__RT(pthread_create(&task->thobj.tid, &thattr,
-                                       &task_trampoline, task)));
-       pthread_attr_destroy(&thattr);
+       ret = __bt(copperplate_create_thread(cprio, task_trampoline, task,
+                                            stacksize, &task->thobj.tid));
        if (ret) {
                registry_destroy_file(&task->fsobj);
                cluster_delobj(&wind_task_table, &task->cobj);


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to