summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Maria Matejka <mq@ucw.cz>2019-05-23 11:27:24 +0000
committerJan Maria Matejka <mq@ucw.cz>2019-05-23 11:27:24 +0000
commit6479e403ef7398f48c0e1c0f1a71aa112938a357 (patch)
tree1f8d85be642df05ad5cbbaa80a9fc27b289f7ba3
parent23e3b1e6652bac4a003a7eb1e074bdaf7ebb4900 (diff)
Filters: If somebody doesn't like _Thread_local, don't fail for now, just be a little slower.
When the parallel execution comes into place, we'll likely enforce this C11 feature. It's much simpler and also faster than pthread_[sg]etspecific().
-rw-r--r--aclocal.m421
-rw-r--r--configure.ac5
-rw-r--r--filter/filter.c41
-rw-r--r--lib/birdlib.h6
4 files changed, 55 insertions, 18 deletions
diff --git a/aclocal.m4 b/aclocal.m4
index 0044adf9..746d5df5 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,6 +1,25 @@
dnl ** Additional Autoconf tests for BIRD configure script
dnl ** (c) 1999 Martin Mares <mj@ucw.cz>
+AC_DEFUN([BIRD_CHECK_THREAD_LOCAL],
+[
+ AC_CACHE_CHECK(
+ [whether _Thread_local is known],
+ [bird_cv_thread_local],
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM(
+ [
+ _Thread_local static int x = 42;
+ ],
+ []
+ )
+ ],
+ [bird_cv_thread_local=yes],
+ [bird_cv_thread_local=no]
+ )
+ )
+])
+
AC_DEFUN([BIRD_CHECK_PTHREADS],
[
bird_tmp_cflags="$CFLAGS"
@@ -134,7 +153,7 @@ AC_DEFUN([BIRD_CHECK_ANDROID_LOG],
AC_DEFUN([BIRD_CHECK_LTO],
[
bird_tmp_cflags="$CFLAGS"
- bird_tmp_ldflags="$CFLAGS"
+ bird_tmp_ldflags="$LDFLAGS"
CFLAGS="-flto"
LDFLAGS="-flto"
diff --git a/configure.ac b/configure.ac
index 58fdc7fe..5ec75359 100644
--- a/configure.ac
+++ b/configure.ac
@@ -115,6 +115,11 @@ if test -z "$GCC" ; then
AC_MSG_ERROR([This program requires the GNU C Compiler.])
fi
+BIRD_CHECK_THREAD_LOCAL
+if test "$bird_cv_thread_local" = yes ; then
+ AC_DEFINE([HAVE_THREAD_LOCAL], [1], [Define to 1 if _Thread_local is available])
+fi
+
if test "$enable_pthreads" != no ; then
BIRD_CHECK_PTHREADS
diff --git a/filter/filter.c b/filter/filter.c
index dbc2376b..65572583 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -51,7 +51,7 @@
#include "filter/data.h"
/* Internal filter state, to be allocated on stack when executing filters */
-_Thread_local struct filter_state {
+struct filter_state {
/* The route we are processing. This may be NULL to indicate no route available. */
struct rte **rte;
@@ -63,7 +63,14 @@ _Thread_local struct filter_state {
struct linpool *pool;
struct buffer buf;
int flags;
-} filter_state;
+};
+
+#if HAVE_THREAD_LOCAL
+_Thread_local static struct filter_state filter_state;
+#define FS_INIT(...) filter_state = (struct filter_state) { __VA_ARGS__ }
+#else
+#define FS_INIT(...) struct filter_state filter_state = { __VA_ARGS__ }
+#endif
void (*bt_assert_hook)(int result, const struct f_line_item *assert);
@@ -275,11 +282,11 @@ f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, i
DBG( "Running filter `%s'...", filter->name );
/* Initialize the filter state */
- filter_state = (struct filter_state) {
- .rte = rte,
- .pool = tmp_pool,
- .flags = flags,
- };
+ FS_INIT(
+ .rte = rte,
+ .pool = tmp_pool,
+ .flags = flags,
+ );
LOG_BUFFER_INIT(filter_state.buf);
@@ -338,10 +345,10 @@ f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, i
enum filter_return
f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool)
{
- filter_state = (struct filter_state) {
- .rte = rte,
- .pool = tmp_pool,
- };
+ FS_INIT(
+ .rte = rte,
+ .pool = tmp_pool,
+ );
LOG_BUFFER_INIT(filter_state.buf);
@@ -360,9 +367,9 @@ f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool
enum filter_return
f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres)
{
- filter_state = (struct filter_state) {
- .pool = tmp_pool,
- };
+ FS_INIT(
+ .pool = tmp_pool,
+ );
LOG_BUFFER_INIT(filter_state.buf);
@@ -379,9 +386,9 @@ uint
f_eval_int(const struct f_line *expr)
{
/* Called independently in parse-time to eval expressions */
- filter_state = (struct filter_state) {
- .pool = cfg_mem,
- };
+ FS_INIT(
+ .pool = cfg_mem,
+ );
struct f_val val;
diff --git a/lib/birdlib.h b/lib/birdlib.h
index 6fcc202f..9743da32 100644
--- a/lib/birdlib.h
+++ b/lib/birdlib.h
@@ -73,6 +73,12 @@ static inline int u64_cmp(u64 i1, u64 i2)
#define UNUSED __attribute__((unused))
#define PACKED __attribute__((packed))
+#ifdef HAVE_THREAD_LOCAL
+#define THREAD_LOCAL _Thread_local
+#else
+#define THREAD_LOCAL
+#endif
+
/* Microsecond time */
typedef s64 btime;