[PATCH] dogs -
Jim Cromie
jim.cromie at gmail.com
Wed Mar 16 03:36:06 EDT 2022
In an attempt to solve frictions in:
https://lore.kernel.org/lkml/20220311044756.425777-3-jim.cromie@gmail.com/
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 at gmail.com>
---
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
More information about the Kernelnewbies
mailing list