summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2019-03-06 15:01:10 +0100
committerMaria Matejka <mq@ucw.cz>2019-03-06 15:01:39 +0100
commite1ac6f1e301416037725b631fd6529a805e65d51 (patch)
treed0fd92b70e047a7e97f2f5fc4ca9c719a2f6c140 /filter
parenta68442e0563f5b756f9a7323cea44a25ce048738 (diff)
Faster filters: documentation on what is happening there
Diffstat (limited to 'filter')
-rw-r--r--filter/f-inst.c37
-rw-r--r--filter/f-inst.h35
2 files changed, 72 insertions, 0 deletions
diff --git a/filter/f-inst.c b/filter/f-inst.c
index 8505534a..6f031782 100644
--- a/filter/f-inst.c
+++ b/filter/f-inst.c
@@ -7,6 +7,43 @@
*
* Can be freely distributed and used under the terms of the GNU GPL.
*
+ * Filter instructions. You shall define your instruction only here
+ * and nowhere else.
+ *
+ * Beware. This file is interpreted by M4 macros. These macros
+ * may be more stupid than you could imagine. If something strange
+ * happens after changing this file, compare the results before and
+ * after your change (see the Makefile to find out where the results are)
+ * and see what really happened.
+ *
+ * This file is not directly a C source code -> it is a generator input
+ * for several C sources; every instruction block gets expanded into many
+ * different places.
+ *
+ * What is the syntax here?
+ * m4_dnl INST(FI_NOP, in, out) { enum value, input args, output args
+ * m4_dnl ARG(num, type); argument, its id (in data fields) and type
+ * m4_dnl ARG_ANY(num); argument with no type check
+ * m4_dnl LINE(num, unused); this argument has to be converted to its own f_line
+ * m4_dnl ECS; extended community subtype
+ * m4_dnl COUNT(unused); simply a uint
+ * m4_dnl SYMBOL(unused); symbol handed from config
+ * m4_dnl FRET(unused); filter return value
+ * m4_dnl STATIC_ATTR; static attribute definition
+ * m4_dnl DYNAMIC_ATTR; dynamic attribute definition
+ * m4_dnl RTC; route table config
+ * m4_dnl TREE; a tree
+ * m4_dnl ACCESS_RTE; this instruction needs route
+ * m4_dnl ACCESS_EATTRS; this instruction needs extended attributes
+ * m4_dnl RESULT(type, union-field, value); putting this on value stack
+ * m4_dnl RESULT_OK; legalize what already is on the value stack
+ * m4_dnl }
+ *
+ * Other code is just copied into the interpreter part.
+ *
+ * If you want to write something really special, see FI_CALL
+ * or FI_CONSTANT or whatever else to see how to use the FID_*
+ * macros.
*/
/* Binary operators */
diff --git a/filter/f-inst.h b/filter/f-inst.h
index 4b42c57c..1e2d63a2 100644
--- a/filter/f-inst.h
+++ b/filter/f-inst.h
@@ -5,6 +5,41 @@
* (c) 2018--2019 Maria Matejka <mq@jmq.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
+ *
+ * Filter interpreter data structures and internal API.
+ * The filter code goes through several phases:
+ *
+ * 1 Parsing
+ * Flex- and Bison-generated parser decodes the human-readable data into
+ * a struct f_inst tree. This is an infix tree that was interpreted by
+ * depth-first search execution in previous versions of the interpreter.
+ * All instructions have their constructor: f_new_inst(FI_code, ...)
+ * translates into f_new_inst_FI_code(...) and the types are checked in
+ * compile time.
+ *
+ * 2 Postfixify before interpreting
+ * The infix tree is always interpreted in the same order. Therefore we
+ * sort the instructions one after another into struct f_line. Results
+ * and arguments of these instructions are implicitly put on a value
+ * stack; e.g. the + operation just takes two arguments from the value
+ * stack and puts the result on there.
+ *
+ * 3 Interpret
+ * The given line is put on a custom execution stack. If needed (FI_CALL,
+ * FI_SWITCH, FI_AND, FI_OR, FI_CONDITION, ...), another line is put on top
+ * of the stack; when that line finishes, the execution continues on the
+ * older lines on the stack where it stopped before.
+ *
+ * 4 Same
+ * On config reload, the filters have to be compared whether channel
+ * reload is needed or not. The comparison is done by comparing the
+ * struct f_line's recursively.
+ *
+ * The main purpose of this rework was to improve filter performance
+ * by making the interpreter non-recursive.
+ *
+ * The other outcome is concentration of instruction definitions to
+ * one place -- filter/f-inst.c
*/
#ifndef _BIRD_F_INST_H_