]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
tvhlog: optimize subsystem checks using bit-array
authorJaroslav Kysela <perex@perex.cz>
Tue, 30 Aug 2016 17:40:59 +0000 (19:40 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 30 Aug 2016 17:42:02 +0000 (19:42 +0200)
configure
src/bitops.h [new file with mode: 0644]
src/tvhlog.c
src/tvhlog.h

index 17230991f3e2ef0c77eb5f9c126e147273dcbdc7..97385764b5eaf4833124c9ee007e9097f1ed2317 100755 (executable)
--- 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 <stdint.h>
+int test(void){
+  int l = sizeof(long);
+  return l == 8 ? 0 : 1;
+}'
+
 check_cc_snippet lockowner '
 #include <sys/syscall.h>
 #include <unistd.h>
diff --git a/src/bitops.h b/src/bitops.h
new file mode 100644 (file)
index 0000000..a231364
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#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)));
+}
index 38df3c8740b19e9cb3ba6686774397e47c862133..eb3d545e6169f97d9e26ffb6d31447464adba7e0 100644 (file)
 #include <execinfo.h>
 #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();
 }
 
index dc07d841f2240e6c63d97f21214a427cde4b048b..f41c2c02b55285ec250fd27c0a2a39ab7a85b28b 100644 (file)
@@ -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;