[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