MEDIUM: filters: Use macros to call filters callbacks to speed-up processing
When no filter is attached to the stream, the CPU footprint due to the calls to
filters_* functions is huge, especially for chunk-encoded messages. Using macros
to check if we have some filters or not is a great improvement.
Furthermore, instead of checking the filter list emptiness, we introduce a flag
to know if filters are attached or not to a stream.
diff --git a/include/proto/filters.h b/include/proto/filters.h
index 2e21577..0e0eb5f 100644
--- a/include/proto/filters.h
+++ b/include/proto/filters.h
@@ -35,6 +35,50 @@
#define FLT_NXT(flt, chn) ((flt)->next[CHN_IDX(chn)])
#define FLT_FWD(flt, chn) ((flt)->fwd[CHN_IDX(chn)])
+#define HAS_FILTERS(strm) ((strm)->strm_flt.has_filters)
+
+#define FLT_STRM_CB_IMPL_0(strm, call) \
+ do { \
+ if (HAS_FILTERS(strm)) { call; } \
+ } while (0)
+#define FLT_STRM_CB_IMPL_1(strm, call, default_ret, ...) \
+ (HAS_FILTERS(strm) ? call : default_ret)
+#define FLT_STRM_CB_IMPL_2(strm, call, default_ret, on_error) \
+ ({ \
+ int _ret; \
+ if (HAS_FILTERS(strm)) { \
+ _ret = call; \
+ if (_ret < 0) { on_error; } \
+ } \
+ else \
+ _ret = default_ret; \
+ _ret; \
+ })
+#define FLT_STRM_CB_IMPL_3(strm, call, default_ret, on_error, on_wait) \
+ ({ \
+ int _ret; \
+ if (HAS_FILTERS(strm)) { \
+ _ret = call; \
+ if (_ret < 0) { on_error; } \
+ if (!_ret) { on_wait; } \
+ } \
+ else \
+ _ret = default_ret; \
+ _ret; \
+ })
+
+#define FLT_STRM_CB_IMPL_X(strm, call, A, B, C, CB_IMPL, ...) CB_IMPL
+
+#define FLT_STRM_CB(strm, call, ...) \
+ FLT_STRM_CB_IMPL_X(strm, call, ##__VA_ARGS__, \
+ FLT_STRM_CB_IMPL_3(strm, call, ##__VA_ARGS__), \
+ FLT_STRM_CB_IMPL_2(strm, call, ##__VA_ARGS__), \
+ FLT_STRM_CB_IMPL_1(strm, call, ##__VA_ARGS__), \
+ FLT_STRM_CB_IMPL_0(strm, call))
+
+#define CALL_FILTER_ANALYZER(analyzer, strm, chn, bit) \
+ if (!HAS_FILTERS(strm) || analyzer((strm), (chn), bit)) ; else break
+
extern struct pool_head *pool2_filter;
int flt_init(struct proxy *p);
diff --git a/include/types/stream.h b/include/types/stream.h
index d6e05e4..e2efc93 100644
--- a/include/types/stream.h
+++ b/include/types/stream.h
@@ -128,6 +128,7 @@
struct {
struct list filters;
struct filter *current[2]; /* 0: request, 1: response */
+ char has_filters;
} strm_flt;
struct task *task; /* the task associated with this stream */