Module: xenomai-3 Branch: next Commit: f42334abc373fd885dfeefe704aec9b026241800 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=f42334abc373fd885dfeefe704aec9b026241800
Author: Philippe Gerum <[email protected]> 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 <[email protected]>. + * + * 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 [email protected] http://xenomai.org/mailman/listinfo/xenomai-git
