From e1ac6f1e301416037725b631fd6529a805e65d51 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Wed, 6 Mar 2019 15:01:10 +0100 Subject: [PATCH] Faster filters: documentation on what is happening there --- filter/f-inst.c | 37 +++++++++++++++++++++++++++++++++++++ filter/f-inst.h | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) 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 * * 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_