--- /dev/null
+/*
+ * 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)));
+}
#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;
};
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;
}
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);
}
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
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;
}
}
/* Basic message */
+ options = tvhlog_options;
l = 0;
if (options & TVHLOG_OPT_THREAD) {
tvh_strlcatf(buf, sizeof(buf), l, "tid %ld: ", (long)pthread_self());
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);
if (fp)
fclose(fp);
free(tvhlog_path);
- htsmsg_destroy(tvhlog_debug);
- htsmsg_destroy(tvhlog_trace);
closelog();
}