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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Sat Jul 25 20:07:11 2015 +0200

lib/cobalt: turn environment variables into options

RT_PRINT_*_ENV variables are converted to command line base options,
with associated configuration tunables (include/cobalt/tunables.h).

RT_PRINT_BUFFER_ENV           =>    --print-buffer-size
RT_PRINT_BUFFERS_COUNT_ENV    =>    --print-buffer-count
RT_PRINT_PERIOD_ENV           =>    --print-sync-delay

---

 include/cobalt/Makefile.am  |    1 +
 include/cobalt/sys/cobalt.h |    4 --
 include/cobalt/tunables.h   |   80 +++++++++++++++++++++++++++++
 lib/cobalt/init.c           |   68 +++++++++++++++++++++++--
 lib/cobalt/printf.c         |  116 +++++++++++++++----------------------------
 5 files changed, 186 insertions(+), 83 deletions(-)

diff --git a/include/cobalt/Makefile.am b/include/cobalt/Makefile.am
index e2d7f87..19e9611 100644
--- a/include/cobalt/Makefile.am
+++ b/include/cobalt/Makefile.am
@@ -13,6 +13,7 @@ includesub_HEADERS =  \
        ticks.h         \
        time.h          \
        trace.h         \
+       tunables.h      \
        unistd.h        \
        wrappers.h
 
diff --git a/include/cobalt/sys/cobalt.h b/include/cobalt/sys/cobalt.h
index 22322c1..e80800b 100644
--- a/include/cobalt/sys/cobalt.h
+++ b/include/cobalt/sys/cobalt.h
@@ -132,10 +132,6 @@ void cobalt_register_tsd_hook(struct cobalt_tsd_hook *th);
 
 extern int __cobalt_control_bind;
 
-extern int __cobalt_main_prio;
-
-extern int __cobalt_print_bufsz;
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/cobalt/tunables.h b/include/cobalt/tunables.h
new file mode 100644
index 0000000..67953c2
--- /dev/null
+++ b/include/cobalt/tunables.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 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 _COBALT_TUNABLES_H
+#define _COBALT_TUNABLES_H
+
+#include <boilerplate/tunables.h>
+#include <sys/cobalt.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int __cobalt_main_prio;
+
+extern int __cobalt_print_bufsz;
+
+extern int __cobalt_print_bufcount;
+
+extern unsigned long long __cobalt_print_syncdelay;
+
+static inline define_config_tunable(main_prio, int, prio)
+{
+       __cobalt_main_prio = prio;
+}
+
+static inline read_config_tunable(main_prio, int)
+{
+       return __cobalt_main_prio;
+}
+
+static inline define_config_tunable(print_buffer_size, int, size)
+{
+       __cobalt_print_bufsz = size;
+}
+
+static inline read_config_tunable(print_buffer_size, int)
+{
+       return __cobalt_print_bufsz;
+}
+
+static inline define_config_tunable(print_buffer_count, int, count)
+{
+       __cobalt_print_bufcount = count;
+}
+
+static inline read_config_tunable(print_buffer_count, int)
+{
+       return __cobalt_print_bufcount;
+}
+
+static inline define_config_tunable(print_sync_delay, unsigned long long, 
delay)
+{
+       __cobalt_print_syncdelay = delay;
+}
+
+static inline read_config_tunable(print_sync_delay, unsigned long long)
+{
+       return __cobalt_print_syncdelay;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_COBALT_TUNABLES_H */
diff --git a/lib/cobalt/init.c b/lib/cobalt/init.c
index 3399329..85dd590 100644
--- a/lib/cobalt/init.c
+++ b/lib/cobalt/init.c
@@ -30,6 +30,7 @@
 #include <boilerplate/setup.h>
 #include <cobalt/uapi/kernel/heap.h>
 #include <cobalt/ticks.h>
+#include <cobalt/tunables.h>
 #include <asm/xenomai/syscall.h>
 #include <xenomai/init.h>
 #include "umm.h"
@@ -57,6 +58,21 @@ static const struct option cobalt_options[] = {
                .has_arg = 1,
        },
        {
+#define print_bufsz_opt        1
+               .name = "print-buffer-size",
+               .has_arg = 1,
+       },
+       {
+#define print_bufcnt_opt       2
+               .name = "print-buffer-count",
+               .has_arg = 1,
+       },
+       {
+#define print_syncdelay_opt    3
+               .name = "print-sync-delay",
+               .has_arg = 1,
+       },
+       {
                /* sentinel */
        }
 };
@@ -205,18 +221,61 @@ int cobalt_init(void)
 
        ret = __RT(pthread_setschedparam(ptid, policy, &parm));
        if (ret) {
-               early_warning("pthread_setschedparam failed");
+               early_warning("pthread_setschedparam failed (prio=%d)",
+                       __cobalt_main_prio);
                return ret;
        }
 
        return 0;
 }
 
+static int get_int_arg(const char *name, const char *arg,
+                      unsigned long long *valp)
+{
+       unsigned long long value;
+       char *p;
+       
+       errno = 0;
+       value = strtoll(arg, &p, 10);
+       if (errno || *p) {
+               early_warning("invalid value for %s: %s", name, arg);
+               return -errno;
+       }
+
+       *valp = value;
+
+       return 0;
+}
+
 static int cobalt_parse_option(int optnum, const char *optarg)
 {
+       unsigned long long value;
+       int ret;
+
        switch (optnum) {
        case main_prio_opt:
-               __cobalt_main_prio = atoi(optarg);
+               ret = get_int_arg("--main-prio", optarg, &value);
+               if (ret)
+                       return ret;
+               __cobalt_main_prio = (int)value;
+               break;
+       case print_bufsz_opt:
+               ret = get_int_arg("--print-buffer-size", optarg, &value);
+               if (ret)
+                       return ret;
+               __cobalt_print_bufsz = (int)value;
+               break;
+       case print_bufcnt_opt:
+               ret = get_int_arg("--print-buffer-count", optarg, &value);
+               if (ret)
+                       return ret;
+               __cobalt_print_bufcount = (int)value;
+               break;
+       case print_syncdelay_opt:
+               ret = get_int_arg("--print-sync-delay", optarg, &value);
+               if (ret)
+                       return ret;
+               __cobalt_print_syncdelay = value;
                break;
        default:
                /* Paranoid, can't happen. */
@@ -228,7 +287,10 @@ static int cobalt_parse_option(int optnum, const char 
*optarg)
 
 static void cobalt_help(void)
 {
-        fprintf(stderr, "--main-prio=<prio>            set main thread 
priority\n");
+        fprintf(stderr, "--main-prio=<prio>            main thread 
priority\n");
+        fprintf(stderr, "--print-buffer-size=<bytes>   size of a print relay 
buffer (16k)\n");
+        fprintf(stderr, "--print-buffer-count=<num>    number of print relay 
buffers (4)\n");
+        fprintf(stderr, "--print-buffer-syncdelay=<ms> max delay of output 
synchronization (100 ms)\n");
 }
 
 static struct setup_descriptor cobalt_interface = {
diff --git a/lib/cobalt/printf.c b/lib/cobalt/printf.c
index de8a91f..e7ff120 100644
--- a/lib/cobalt/printf.c
+++ b/lib/cobalt/printf.c
@@ -28,16 +28,12 @@
 #include <syslog.h>
 #include <boilerplate/atomic.h>
 #include <boilerplate/compiler.h>
+#include <cobalt/tunables.h>
 #include "current.h"
 #include "internal.h"
 
-#define RT_PRINT_BUFFER_ENV            "RT_PRINT_BUFFER"
 #define RT_PRINT_DEFAULT_BUFFER                16*1024
-
-#define RT_PRINT_PERIOD_ENV            "RT_PRINT_PERIOD"
-#define RT_PRINT_DEFAULT_PERIOD                100 /* ms */
-
-#define RT_PRINT_BUFFERS_COUNT_ENV      "RT_PRINT_BUFFERS_COUNT"
+#define RT_PRINT_DEFAULT_SYNCDELAY     100 /* ms */
 #define RT_PRINT_DEFAULT_BUFFERS_COUNT  4
 
 #define RT_PRINT_LINE_BREAK            256
@@ -74,10 +70,14 @@ struct print_buffer {
 
 __weak int __cobalt_print_bufsz = RT_PRINT_DEFAULT_BUFFER;
 
+__weak int __cobalt_print_bufcount = RT_PRINT_DEFAULT_BUFFERS_COUNT;
+
+__weak unsigned long long __cobalt_print_syncdelay = 
RT_PRINT_DEFAULT_SYNCDELAY;
+
 static struct print_buffer *first_buffer;
 static int buffers;
 static uint32_t seq_no;
-static struct timespec print_period;
+static struct timespec syncdelay;
 static pthread_mutex_t buffer_lock;
 static pthread_cond_t printer_wakeup;
 static pthread_key_t buffer_key;
@@ -641,7 +641,7 @@ static void *printer_loop(void *arg)
 
                pthread_mutex_unlock(&buffer_lock);
 
-               nanosleep(&print_period, NULL);
+               nanosleep(&syncdelay, NULL);
        }
 
        return NULL;
@@ -688,81 +688,45 @@ void cobalt_print_init_atfork(void)
 
 void cobalt_print_init(void)
 {
-       const char *value_str;
-       unsigned long long period;
+       unsigned int i;
 
        first_buffer = NULL;
        seq_no = 0;
 
-       value_str = getenv(RT_PRINT_BUFFER_ENV);
-       if (value_str) {
-               errno = 0;
-               __cobalt_print_bufsz = strtol(value_str, NULL, 10);
-               if (errno || __cobalt_print_bufsz < RT_PRINT_LINE_BREAK)
-                       early_panic("invalid %s=%s",
-                                   RT_PRINT_BUFFER_ENV, value_str);
-       }
-
-       period = RT_PRINT_DEFAULT_PERIOD;
-       value_str = getenv(RT_PRINT_PERIOD_ENV);
-       if (value_str) {
-               errno = 0;
-               period = strtoll(value_str, NULL, 10);
-               if (errno)
-                       early_panic("invalid %s=%s",
-                                   RT_PRINT_BUFFER_ENV, value_str);
-       }
-       print_period.tv_sec  = period / 1000;
-       print_period.tv_nsec = (period % 1000) * 1000000;
+       syncdelay.tv_sec  = __cobalt_print_syncdelay / 1000ULL;
+       syncdelay.tv_nsec = (__cobalt_print_syncdelay % 1000ULL) * 1000000;
 
        /* Fill the buffer pool */
-       {
-               unsigned buffers_count, i;
-
-               buffers_count = RT_PRINT_DEFAULT_BUFFERS_COUNT;
-
-               value_str = getenv(RT_PRINT_BUFFERS_COUNT_ENV);
-               if (value_str) {
-                       errno = 0;
-                       buffers_count = strtoul(value_str, NULL, 0);
-                       if (errno)
-                               early_panic("invalid %s=%s",
-                                           RT_PRINT_BUFFERS_COUNT_ENV, 
value_str);
-               }
-
-               pool_bitmap_len = (buffers_count + __WORDSIZE - 1)
-                       / __WORDSIZE;
-               if (!pool_bitmap_len)
-                       goto done;
-
-               pool_bitmap = malloc(pool_bitmap_len * sizeof(*pool_bitmap));
-               if (!pool_bitmap)
-                       early_panic("error allocating printf buffers");
-
-               pool_buf_size = sizeof(struct print_buffer) + 
__cobalt_print_bufsz;
-               pool_len = buffers_count * pool_buf_size;
-               pool_start = (unsigned long)malloc(pool_len);
-               if (!pool_start)
-                       early_panic("error allocating printf buffers");
-
-               for (i = 0; i < buffers_count / __WORDSIZE; i++)
-                       atomic_long_set(&pool_bitmap[i], ~0UL);
-               if (buffers_count % __WORDSIZE)
-                       atomic_long_set(&pool_bitmap[i],
-                                       (1UL << (buffers_count % __WORDSIZE)) - 
1);
-
-               for (i = 0; i < buffers_count; i++) {
-                       struct print_buffer *buffer =
-                               (struct print_buffer *)
-                               (pool_start + i * pool_buf_size);
-
-                       buffer->ring = (char *)(buffer + 1);
-
-                       rt_print_init_inner(buffer, __cobalt_print_bufsz);
-               }
+       pool_bitmap_len = (__cobalt_print_bufcount+__WORDSIZE-1)/__WORDSIZE;
+       if (!pool_bitmap_len)
+               goto done;
+
+       pool_bitmap = malloc(pool_bitmap_len * sizeof(*pool_bitmap));
+       if (!pool_bitmap)
+               early_panic("error allocating print relay buffers");
+
+       pool_buf_size = sizeof(struct print_buffer) + __cobalt_print_bufsz;
+       pool_len = __cobalt_print_bufcount * pool_buf_size;
+       pool_start = (unsigned long)malloc(pool_len);
+       if (!pool_start)
+               early_panic("error allocating print relay buffers");
+
+       for (i = 0; i < __cobalt_print_bufcount / __WORDSIZE; i++)
+               atomic_long_set(&pool_bitmap[i], ~0UL);
+       if (__cobalt_print_bufcount % __WORDSIZE)
+               atomic_long_set(&pool_bitmap[i],
+                               (1UL << (__cobalt_print_bufcount % __WORDSIZE)) 
- 1);
+
+       for (i = 0; i < __cobalt_print_bufcount; i++) {
+               struct print_buffer *buffer =
+                       (struct print_buffer *)
+                       (pool_start + i * pool_buf_size);
+               
+               buffer->ring = (char *)(buffer + 1);
+
+               rt_print_init_inner(buffer, __cobalt_print_bufsz);
        }
-  done:
-
+done:
        pthread_mutex_init(&buffer_lock, NULL);
        pthread_key_create(&buffer_key, (void (*)(void*))cleanup_buffer);
 


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

Reply via email to