From 6ee756a829ef6ce2e89daa7dd1737164a6697e29 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 30 Aug 2016 19:40:59 +0200 Subject: [PATCH] tvhlog: optimize subsystem checks using bit-array --- configure | 6 ++++ src/bitops.h | 49 +++++++++++++++++++++++++++ src/tvhlog.c | 96 +++++++++++++++++++++++++--------------------------- src/tvhlog.h | 2 -- 4 files changed, 101 insertions(+), 52 deletions(-) create mode 100644 src/bitops.h diff --git a/configure b/configure index 17230991f..97385764b 100755 --- a/configure +++ b/configure @@ -165,6 +165,12 @@ uint64_t test(time_t *ptr){ return __sync_fetch_and_add(ptr, 1); }' +check_cc_snippet bitops64 '#include +int test(void){ + int l = sizeof(long); + return l == 8 ? 0 : 1; +}' + check_cc_snippet lockowner ' #include #include diff --git a/src/bitops.h b/src/bitops.h new file mode 100644 index 000000000..a2313647f --- /dev/null +++ b/src/bitops.h @@ -0,0 +1,49 @@ +/* + * Bit ops + * Copyright (C) 2008 Andreas Öman + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include + +#if ENABLE_BITOPS64 +#define BITS_PER_LONG 64 +typedef uint64_t bitops_ulong_t; +#else +#define BITS_PER_LONG 32 +typedef uint32_t bitops_ulong_t; +#endif + +#define BIT_WORD(bit) ((bit) / BITS_PER_LONG) +#define BIT_MASK(bit) (1UL << ((bit) % BITS_PER_LONG)) + +static inline void set_bit(int bit, void *addr) +{ + bitops_ulong_t *p = ((unsigned long *)addr) + BIT_WORD(bit); + *p |= BIT_MASK(bit); +} + +static inline void clear_bit(int bit, void *addr) +{ + bitops_ulong_t *p = ((unsigned long *)addr) + BIT_WORD(bit); + *p &= BIT_MASK(bit); +} + +static inline int test_bit(int bit, void *addr) +{ + return 1UL & (((bitops_ulong_t *)addr)[BIT_WORD(bit)] >> (bit & (BITS_PER_LONG-1))); +} diff --git a/src/tvhlog.c b/src/tvhlog.c index 38df3c874..eb3d545e6 100644 --- a/src/tvhlog.c +++ b/src/tvhlog.c @@ -27,15 +27,18 @@ #include #endif +#include "bitops.h" #include "libav.h" #include "webui/webui.h" +#define TVHLOG_BITARRAY ((LS_LAST + (BITS_PER_LONG - 1)) / BITS_PER_LONG) + int tvhlog_run; int tvhlog_level; int tvhlog_options; char *tvhlog_path; -htsmsg_t *tvhlog_debug; -htsmsg_t *tvhlog_trace; +bitops_ulong_t tvhlog_debug[TVHLOG_BITARRAY]; +bitops_ulong_t tvhlog_trace[TVHLOG_BITARRAY]; pthread_t tvhlog_tid; pthread_mutex_t tvhlog_mutex; tvh_cond_t tvhlog_cond; @@ -163,34 +166,34 @@ tvhlog_subsys_t tvhlog_subsystems[] = { }; static void -tvhlog_get_subsys ( htsmsg_t *ss, char *subsys, size_t len ) +tvhlog_get_subsys ( bitops_ulong_t *ss, char *subsys, size_t len ) { size_t c = 0; - int first = 1; - htsmsg_field_t *f; + uint_fast32_t first = 1, i; *subsys = '\0'; - if (ss) { - HTSMSG_FOREACH(f, ss) { - if (f->hmf_type != HMF_S64) continue; - tvh_strlcatf(subsys, len, c, "%s%c%s", - first ? "" : ",", - f->hmf_s64 ? '+' : '-', - f->hmf_name); - first = 0; - } + for (i = 0; i < LS_LAST; i++) + if (!test_bit(i, ss)) break; + if (i >= LS_LAST) { + tvh_strlcatf(subsys, len, c, "all"); + return; + } + for (i = 0; i < LS_LAST; i++) { + if (!test_bit(i, ss)) continue; + tvh_strlcatf(subsys, len, c, "%s%s", + first ? "" : ",", + tvhlog_subsystems[i].name); + first = 0; } } /* Set subsys */ static void -tvhlog_set_subsys ( htsmsg_t **c, const char *subsys ) +tvhlog_set_subsys ( bitops_ulong_t *c, const char *subsys ) { - uint32_t a; + uint_fast32_t a, i; char *s, *t, *r = NULL; - if (*c) - htsmsg_destroy(*c); - *c = NULL; + memset(c, 0, TVHLOG_BITARRAY * sizeof(bitops_ulong_t)); if (!subsys) return; @@ -207,13 +210,16 @@ tvhlog_set_subsys ( htsmsg_t **c, const char *subsys ) } if (!*t) goto next; if (!strcmp(t, "all")) { - if (*c) - htsmsg_destroy(*c); - *c = NULL; + memset(c, a ? 0xff : 0, TVHLOG_BITARRAY * sizeof(bitops_ulong_t)); + } else { + for (i = 0; i < LS_LAST; i++) + if (!strcmp(tvhlog_subsystems[i].name, t)) { + if (a) set_bit(i, c); else clear_bit(i, c); + break; + } + if (i >= LS_LAST) + tvherror(LS_CONFIG, "uknown subsystem '%s'", t); } - if (!*c) - *c = htsmsg_create_map(); - htsmsg_set_u32(*c, t, a); next: t = strtok_r(NULL, ",", &r); } @@ -223,13 +229,13 @@ next: void tvhlog_set_debug ( const char *subsys ) { - tvhlog_set_subsys(&tvhlog_debug, subsys); + tvhlog_set_subsys(tvhlog_debug, subsys); } void tvhlog_set_trace ( const char *subsys ) { - tvhlog_set_subsys(&tvhlog_trace, subsys); + tvhlog_set_subsys(tvhlog_trace, subsys); } void @@ -368,34 +374,25 @@ void tvhlogv ( const char *file, int line, int severity, notify = (severity & LOG_TVH_NOTIFY) ? 1 : 0; severity &= ~LOG_TVH_NOTIFY; - pthread_mutex_lock(&tvhlog_mutex); - - /* Check for full */ - if (tvhlog_queue_full) { - pthread_mutex_unlock(&tvhlog_mutex); - return; - } - - /* Check debug enabled (and cache config) */ - options = tvhlog_options; if (severity >= LOG_DEBUG) { ok = 0; if (severity <= atomic_get(&tvhlog_level)) { - if (tvhlog_trace) { - ok = htsmsg_get_u32_or_default(tvhlog_trace, "all", 0); - ok = htsmsg_get_u32_or_default(tvhlog_trace, tvhlog_subsystems[subsys].name, ok); - } - if (!ok && severity == LOG_DEBUG && tvhlog_debug) { - ok = htsmsg_get_u32_or_default(tvhlog_debug, "all", 0); - ok = htsmsg_get_u32_or_default(tvhlog_debug, tvhlog_subsystems[subsys].name, ok); - } + ok = test_bit(subsys, tvhlog_trace); + if (!ok && severity == LOG_DEBUG) + ok = test_bit(subsys, tvhlog_debug); } } else { ok = 1; } /* Ignore */ - if (!ok) { + if (!ok) + return; + + pthread_mutex_lock(&tvhlog_mutex); + + /* Check for full */ + if (tvhlog_queue_full) { pthread_mutex_unlock(&tvhlog_mutex); return; } @@ -409,6 +406,7 @@ void tvhlogv ( const char *file, int line, int severity, } /* Basic message */ + options = tvhlog_options; l = 0; if (options & TVHLOG_OPT_THREAD) { tvh_strlcatf(buf, sizeof(buf), l, "tid %ld: ", (long)pthread_self()); @@ -525,8 +523,8 @@ tvhlog_init ( int level, int options, const char *path ) tvhlog_level = level; tvhlog_options = options; tvhlog_path = path ? strdup(path) : NULL; - tvhlog_trace = NULL; - tvhlog_debug = NULL; + memset(tvhlog_trace, 0, sizeof(tvhlog_trace)); + memset(tvhlog_debug, 0, sizeof(tvhlog_debug)); tvhlog_run = 1; openlog("tvheadend", LOG_PID, LOG_DAEMON); pthread_mutex_init(&tvhlog_mutex, NULL); @@ -561,8 +559,6 @@ tvhlog_end ( void ) if (fp) fclose(fp); free(tvhlog_path); - htsmsg_destroy(tvhlog_debug); - htsmsg_destroy(tvhlog_trace); closelog(); } diff --git a/src/tvhlog.h b/src/tvhlog.h index dc07d841f..f41c2c02b 100644 --- a/src/tvhlog.h +++ b/src/tvhlog.h @@ -45,8 +45,6 @@ typedef struct { /* Config */ extern int tvhlog_level; -extern htsmsg_t *tvhlog_debug; -extern htsmsg_t *tvhlog_trace; extern char *tvhlog_path; extern int tvhlog_options; extern pthread_mutex_t tvhlog_mutex; -- 2.47.3