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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Tue Aug  6 17:00:05 2013 +0200

lib/cobalt: extend control over library init procedure

__cobalt_defer_init is a weak boolean variable which may be overriden
by any external compilation unit for preventing the library
constructor from running the initialization code, including binding
the process to the real-time system.

In deferred init mode, __libcobalt_init() may be called later for
running the real-time init code, which will NOT include the
auto-shadowing procedure for the calling thread though.

CAUTION: upon fork(), the parent's setting for init deferral is
inherited by the child process. This means that a forkee shall call
__libcobalt_init() for binding to the real-time system, if forked from
a parent which previosuly asked for a deferred init.

In addition, __cobalt_main_prio is a weak integer value which may be
overriden by any external compilation unit for selecting the
scheduling policy and priority, to be set when auto-shadowing the main
thread. For this reason, this setting only applies when
__cobalt_defer_init is unset.

__cobalt_main_prio == 0, forces [SCHED_OTHER, 0]
__cobalt_main_prio > 0, forces  [SCHED_FIFO, __cobalt_main_prio]
__cobalt_main_prio < 0, reuses the current scheduling parameters.

---

 lib/cobalt/Makefile.am |    1 +
 lib/cobalt/Makefile.in |    1 +
 lib/cobalt/init.c      |  111 +++++++++++++++++++++++++++++-------------------
 lib/cobalt/internal.h  |   17 +++++++
 lib/cobalt/linkage.h   |   36 +++++++++++++++
 5 files changed, 122 insertions(+), 44 deletions(-)

diff --git a/lib/cobalt/Makefile.am b/lib/cobalt/Makefile.am
index b7259e4..3364479 100644
--- a/lib/cobalt/Makefile.am
+++ b/lib/cobalt/Makefile.am
@@ -2,6 +2,7 @@ pkgconfigdir = $(libdir)/pkgconfig
 
 noinst_HEADERS =       \
        current.h       \
+       linkage.h       \
        sem_heap.h      \
        internal.h
 
diff --git a/lib/cobalt/Makefile.in b/lib/cobalt/Makefile.in
index 93c1e20..755e00e 100644
--- a/lib/cobalt/Makefile.in
+++ b/lib/cobalt/Makefile.in
@@ -345,6 +345,7 @@ top_srcdir = @top_srcdir@
 pkgconfigdir = $(libdir)/pkgconfig
 noinst_HEADERS = \
        current.h       \
+       linkage.h       \
        sem_heap.h      \
        internal.h
 
diff --git a/lib/cobalt/init.c b/lib/cobalt/init.c
index 6070555..0e539af 100644
--- a/lib/cobalt/init.c
+++ b/lib/cobalt/init.c
@@ -31,6 +31,13 @@
 #include <asm/xenomai/syscall.h>
 #include "sem_heap.h"
 #include "internal.h"
+#include "linkage.h"
+
+__attribute__ ((weak))
+int __cobalt_defer_init = 0;
+
+__attribute__ ((weak))
+int __cobalt_main_prio = -1;
 
 int __cobalt_muxid = -1;
 
@@ -42,11 +49,9 @@ int __rtdm_muxid = -1;
 
 int __rtdm_fd_start = INT_MAX;
 
-static int fork_handler_registered;
-
 static void sigill_handler(int sig)
 {
-       const char m[] = "Xenomai disabled in kernel?\n";
+       const char m[] = "no Xenomai support in kernel?\n";
        write(2, m, sizeof(m) - 1);
        exit(EXIT_FAILURE);
 }
@@ -114,29 +119,18 @@ static int bind_interface(void)
 
        cobalt_init_current_keys();
 
-       __cobalt_main_tid = pthread_self();
-
        cobalt_ticks_init(sysinfo.clockfreq);
 
        return muxid;
 }
 
-/*
- * We give the Cobalt library constructor a high priority, so that
- * extension libraries may assume the core services are available when
- * their own constructor runs. Priorities 0-100 may be reserved by the
- * implementation on some platforms, and we may want to keep some
- * levels free for very high priority inits, so pick 200.
- */
-static __attribute__ ((constructor(200)))
-void __init_cobalt_interface(void)
+static void __init_cobalt(void);
+
+void __libcobalt_init(void)
 {
-       pthread_t tid = pthread_self();
-       struct sched_param parm;
-       int policy, muxid, ret;
        struct xnbindreq breq;
        struct sigaction sa;
-       const char *p;
+       int muxid, ret;
 
        muxid = bind_interface();
        if (muxid < 0) {
@@ -160,14 +154,46 @@ void __init_cobalt_interface(void)
                                                                 
sc_rtdm_fdcount);
        }
 
+       /*
+        * Upon fork, in case the parent required init deferral, this
+        * is the forkee's responsibility to call __libcobalt_init()
+        * for bootstrapping the services the same way.
+        */
+       ret = pthread_atfork(NULL, NULL, __init_cobalt);
+       if (ret) {
+               report_error("pthread_atfork: %s", strerror(ret));
+               exit(EXIT_FAILURE);
+       }
+
+       if (sizeof(struct __shadow_mutex) > sizeof(pthread_mutex_t)) {
+               report_error("sizeof(pthread_mutex_t): %d <"
+                            " sizeof(shadow_mutex): %d !",
+                            (int) sizeof(pthread_mutex_t),
+                            (int) sizeof(struct __shadow_mutex));
+               exit(EXIT_FAILURE);
+       }
+
+       cobalt_print_init();
+}
+
+static __libcobalt_ctor void __init_cobalt(void)
+{
+       pthread_t tid = pthread_self();
+       struct sched_param parm;
+       int policy, ret;
+       const char *p;
+
+       __cobalt_main_tid = tid;
+
+       if (__cobalt_defer_init)
+               return;
+
+       __libcobalt_init();
+
        p = getenv("XENO_NOSHADOW");
        if (p && *p)
-               goto no_shadow;
+               return;
 
-       /*
-        * Auto-shadow the current context if we can't be invoked from
-        * dlopen.
-        */
        if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
                report_error("mlockall: %s", strerror(errno));
                exit(EXIT_FAILURE);
@@ -179,30 +205,27 @@ void __init_cobalt_interface(void)
                exit(EXIT_FAILURE);
        }
 
+       /*
+        * Switch the main thread to a Xenomai shadow.
+        * __cobalt_main_prio might have been overriden by
+        * some compilation unit which has been linked in, to force
+        * the scheduling parameters. Otherwise, the current policy
+        * and priority are reused, for declaring the thread to the
+        * Xenomai scheduler.
+        *
+        * SCHED_FIFO is assumed for __cobalt_main_prio > 0.
+        */
+       if (__cobalt_main_prio > 0) {
+               policy = SCHED_FIFO;
+               parm.sched_priority = __cobalt_main_prio;
+       } else if (__cobalt_main_prio == 0) {
+               policy = SCHED_OTHER;
+               parm.sched_priority = 0;
+       }
+       
        ret = __RT(pthread_setschedparam(tid, policy, &parm));
        if (ret) {
                report_error("pthread_setschedparam: %s", strerror(ret));
                exit(EXIT_FAILURE);
        }
-
-no_shadow:
-       if (fork_handler_registered)
-               return;
-
-       ret = pthread_atfork(NULL, NULL, &__init_cobalt_interface);
-       if (ret) {
-               report_error("pthread_atfork: %s", strerror(ret));
-               exit(EXIT_FAILURE);
-       }
-       fork_handler_registered = 1;
-
-       if (sizeof(struct __shadow_mutex) > sizeof(pthread_mutex_t)) {
-               report_error("sizeof(pthread_mutex_t): %d <"
-                            " sizeof(shadow_mutex): %d !",
-                            (int) sizeof(pthread_mutex_t),
-                            (int) sizeof(struct __shadow_mutex));
-               exit(EXIT_FAILURE);
-       }
-
-       cobalt_print_init();
 }
diff --git a/lib/cobalt/internal.h b/lib/cobalt/internal.h
index e812e3f..75ce011 100644
--- a/lib/cobalt/internal.h
+++ b/lib/cobalt/internal.h
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2008 Philippe Gerum <r...@xenomai.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
 #ifndef _LIB_COBALT_INTERNAL_H
 #define _LIB_COBALT_INTERNAL_H
 
diff --git a/lib/cobalt/linkage.h b/lib/cobalt/linkage.h
new file mode 100644
index 0000000..f650bf5
--- /dev/null
+++ b/lib/cobalt/linkage.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2013 Philippe Gerum <r...@xenomai.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+#ifndef _LIB_COBALT_LINKAGE_H
+#define _LIB_COBALT_LINKAGE_H
+
+/*
+ * We give the Cobalt library constructor a high priority, so that
+ * extension libraries may assume the core services are available when
+ * their own constructor runs. Priorities 0-100 may be reserved by the
+ * implementation on some platforms, and we may want to keep some
+ * levels free for very high priority inits, so pick 200.
+ */
+#define __LIBCOBALT_CTOR_PRIO  200
+
+#define __libcobalt_ctor  __attribute__ ((constructor(__LIBCOBALT_CTOR_PRIO)))
+
+void __libcobalt_init(void);
+
+extern int __cobalt_defer_init;
+
+#endif /* _LIB_COBALT_LINKAGE_H */


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

Reply via email to