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(¶m, 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, ¶m); - 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, ¶m_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, ¶m); + 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(¶m, 0, sizeof(param)); - param.sched_priority = threadobj_irq_prio; - pthread_attr_setschedparam(&thattr, ¶m); - 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(¶m, 0, sizeof(param)); - param.sched_priority = cprio; - pthread_attr_setinheritsched(&thattr, PTHREAD_EXPLICIT_SCHED); - pthread_attr_setschedpolicy(&thattr, SCHED_RT); - pthread_attr_setschedparam(&thattr, ¶m); - 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(¶m, 0, sizeof(param)); - param.sched_priority = cprio; - pthread_attr_setinheritsched(&thattr, PTHREAD_EXPLICIT_SCHED); - pthread_attr_setschedpolicy(&thattr, SCHED_RT); - pthread_attr_setschedparam(&thattr, ¶m); - 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, ®istry_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