In an attempt to solve frictions in: https://lore.kernel.org/lkml/20220311044756.425777-3-jim.cromie@xxxxxxxxx/ And inspired by https://lwn.net/Articles/383362/ defines DOGS macro - an initialization expression, ie list of breeds, each contained by C, an inner macro, undefd when DOGS is defined. C gets 2 defs for 2 tasks: (each with preceding undef to reinforce the pattern) - initialize enum dog_enums = DOGS: C(a) DRM_UT_##a (must form a real token) - stringify each dog in DOGS: C(a) #a Then tries to repeat this macro-pattern in DEFINE_DYNAMIC_DEBUG_CLASSBITS. DOGS --> DRM_DEBUG_CATS C -> C reused for clarity Its close, but not quite right: - want to pass in init-construct once - expand it 2x, with 2 different defs for C() - cant nest #defines, cant redef for 2nd expansion. Is there a way to do this ? theres also some aspirational stuff in there, maybe it communicates / explains things better than this commit msg. Signed-off-by: Jim Cromie <jim.cromie@xxxxxxxxx> --- play/c-code/dogs.c | 149 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 play/c-code/dogs.c diff --git a/play/c-code/dogs.c b/play/c-code/dogs.c new file mode 100644 index 0000000..7094982 --- /dev/null +++ b/play/c-code/dogs.c @@ -0,0 +1,149 @@ + +// see https://lwn.net/Articles/383362/ + +#define DOGS { C(JACK_RUSSELL), C(BULL_TERRIER), C(ITALIAN_GREYHOUND) } + +#undef C +#define C(a) ENUM_##a +enum dog_enums DOGS; + +#undef C +#define C(a) #a + +char *dog_strings[] = DOGS; +char *dog_to_string(enum dog_enums dog) +{ + return dog_strings[dog]; +} + + +// self-documenting help composition +#define DOCS { \ + _doc_( CORE, "extra core info"), \ + _doc_( DRIVER, "extra driver info"), \ + _doc_( KMS, "extra kms"), \ + } + +// 2 decomposers +#define _sym_(_sym, _help) DRM_synth_##_sym +#define _help_(_sym, _help) "enables " #_sym " messages - " _help + +// use sym to enumerate the symbols into the enum +#undef _doc_ +#define _doc_ _sym_ +enum cat_enums DOCS; + +// use -help- to initialize the doc-strings +#undef _doc_ +#define _doc_ _help_ +char *doc_helps[] = DOCS; +char *doc_to_string(enum cat_enums cat) +{ + return doc_helps[cat]; +} + +#define FLAGS_LEN 8 +struct dyndbg_classbits_param { + unsigned long *bits; /* ref to shared state */ + const char flags[FLAGS_LEN]; /* toggle these flags on bit-changes */ + const int classes[]; /* indexed by bitpos */ +}; + +#define _DPRINTK_SITE_UNCLASSED 15 + +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/seq/fold_left.hpp> + +#define OP(s, state, x) BOOST_PP_CAT(state, x) +#define SEQ (b)(o)(o)(s)(t) + +enum foo { + BOOST_PP_SEQ_FOLD_LEFT(OP, BOOST_PP_SEQ_HEAD(SEQ), BOOST_PP_SEQ_TAIL(SEQ)) +}; + +// local copy +enum drm_debug_category { + DRM_UT_CORE, + DRM_UT_DRIVER, + DRM_UT_KMS, + DRM_UT_PRIME, + DRM_UT_ATOMIC, + DRM_UT_VBL, + DRM_UT_STATE, + DRM_UT_LEASE, + DRM_UT_DP, + DRM_UT_DRMRES, + DRM_UT_DEFAULT +}; + +#define DRM_UT_DEFAULT 15 +#define DRM_DEBUG_CATS { \ + C(_CORE), \ + C(_DRIVER), \ + C(_KMS), \ + C(_PRIME), \ + C(_ATOMIC), \ + C(_VBL), \ + C(_STATE), \ + C(_LEASE), \ + C(_DP), \ + C(_DRMRES), \ + C(_DEFAULT) \ + } + +#undef C +#define C(_cat) DRM_UT_##_cat // wo _ after UT get 2x decl on local copy +enum drm_dogs DRM_DEBUG_CATS; + + +/** + * DEFINE_DYNAMIC_DEBUG_CLASSBITS() - bitmap control of classed pr_debugs + * @sysname: sysfs-node name + * @_var: C-identifier of ulong holding bit-vector (Bits 0-14 are usable) + * @_flgs: string with dyndbg flags: 'p' and/or 'T', and maybe "fmlt" also. + * @desc: string summarizing the controls provided + * @classes: vector of callsite.class_id's (uint:4, 15 is reserved) + * + * This macro implements a DRM.debug API style bitmap, mapping bits + * 0-14 to classes of prdbg's, as initialized in their .class_id fields. + * @_flgs chooses the debug recipient; p - syslog, T - tracefs, and + * can include log decorations; m - module, f - function, l - line_num + */ + +#define DEFINE_DYNAMIC_DEBUG_CLASSBITS(fsname, _var, _flgs, desc, ...) \ + static struct dyndbg_classbits_param ddcats_##_var = { \ + .bits = &(_var), \ + .flags = _flgs, \ + .classes = { __VA_ARGS__ } \ + } + +#undef C +#define C(_cls) DRM_UT##_cls + +unsigned long __drm_debug; +DEFINE_DYNAMIC_DEBUG_CLASSBITS(debug, __drm_debug, "p", + "enable drm.debug categories - 1 bit per category", + DRM_DEBUG_CATS); + +#include <stdio.h> +#define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0])) + +int main(int argc, char* argv) { + int i; + + printf("hello world: %s\n", + "" //BOOST_PP_SEQ_FOLD_LEFT(OP, BOOST_PP_SEQ_HEAD(SEQ), BOOST_PP_SEQ_TAIL(SEQ)) + ); + + for (i = 0; i < ARRAY_LEN(dog_strings); i++) { + printf("%d: %s %s\n", i, dog_strings[i], dog_to_string(i)); + } + + for (i = 0; i < ARRAY_LEN(doc_helps); i++) { + printf("%d: %s\n", i, doc_helps[i]); + } + + for (i = DRM_UT_CORE; i < DRM_UT_DEFAULT; i++) { + printf("%d: %s\n", i, ddcats___drm_debug.classes[i]); + } +} -- 2.35.1 _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies