You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/12/14 03:21:28 UTC

[incubator-nuttx] branch master updated: sched note trace: and note dump

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new a32d14c  sched note trace: and note dump
a32d14c is described below

commit a32d14cb9c28fbea834b0b5a70d5ab2338496f6c
Author: zhanghu6 <zh...@xiaomi.com>
AuthorDate: Wed Nov 17 17:23:43 2021 +0800

    sched note trace: and note dump
    
    note_type NOTE_DUMP_STRING API:
    sched_note_string
    sched_note_vprintf
    sched_note_printf
    
    note_type NOTE_DUMP_BINARY API:
    sched_note_dump
    sched_note_vbprintf
    sched_note_bprintf
---
 include/nuttx/sched_note.h |  53 ++++++++
 sched/Kconfig              |  13 ++
 sched/sched/sched_note.c   | 333 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 399 insertions(+)

diff --git a/include/nuttx/sched_note.h b/include/nuttx/sched_note.h
index 1271ea5..f96901e 100644
--- a/include/nuttx/sched_note.h
+++ b/include/nuttx/sched_note.h
@@ -147,6 +147,11 @@ enum note_type_e
   NOTE_IRQ_ENTER       = 20,
   NOTE_IRQ_LEAVE       = 21
 #endif
+#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
+  ,
+  NOTE_DUMP_STRING     = 22,
+  NOTE_DUMP_BINARY     = 23
+#endif
 };
 
 /* This structure provides the common header of each note */
@@ -318,6 +323,29 @@ struct note_irqhandler_s
 };
 #endif /* CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER */
 
+#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
+struct note_string_s
+{
+  struct note_common_s nst_cmn; /* Common note parameters */
+  char nst_data[1];             /* String data terminated by '\0' */
+};
+
+#define SIZEOF_NOTE_STRING(n) (sizeof(struct note_string_s) + \
+                               (n) * sizeof(char))
+
+struct note_binary_s
+{
+  struct note_common_s nbi_cmn; /* Common note parameters */
+  uint32_t nbi_module;          /* Module number */
+  uint8_t  nbi_event;           /* Event number */
+  uint8_t  nbi_data[1];         /* Binary data */
+};
+
+#define SIZEOF_NOTE_BINARY(n) (sizeof(struct note_binary_s) + \
+                               ((n) - 1) * sizeof(uint8_t))
+
+#endif /* CONFIG_SCHED_INSTRUMENTATION_DUMP */
+
 #ifdef CONFIG_SCHED_INSTRUMENTATION_FILTER
 
 /* This is the type of the argument passed to the NOTECTL_GETMODE and
@@ -439,6 +467,25 @@ void sched_note_irqhandler(int irq, FAR void *handler, bool enter);
 #  define sched_note_irqhandler(i,h,e)
 #endif
 
+#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
+void sched_note_string(FAR const char *buf);
+void sched_note_dump(uint32_t module, uint8_t event,
+                     FAR const void *buf, size_t len);
+void sched_note_vprintf(FAR const char *fmt, va_list va) printflike(1, 0);
+void sched_note_vbprintf(uint32_t module, uint8_t event,
+                         FAR const char *fmt, va_list va) printflike(3, 0);
+void sched_note_printf(FAR const char *fmt, ...) printflike(1, 2);
+void sched_note_bprintf(uint32_t module, uint8_t event,
+                        FAR const char *fmt, ...) printflike(3, 4);
+#else
+#  define sched_note_string(b)
+#  define sched_note_dump(m,e,b,l)
+#  define sched_note_vprintf(f,v)
+#  define sched_note_vbprintf(m,e,f,v)
+#  define sched_note_printf(f...)
+#  define sched_note_bprintf(m,e,f...)
+#endif /* CONFIG_SCHED_INSTRUMENTATION_DUMP */
+
 #if defined(__KERNEL__) || defined(CONFIG_BUILD_FLAT)
 
 /****************************************************************************
@@ -561,6 +608,12 @@ void sched_note_filter_irq(struct note_filter_irq_s *oldf,
 #  define sched_note_syscall_enter(n,a...)
 #  define sched_note_syscall_leave(n,r)
 #  define sched_note_irqhandler(i,h,e)
+#  define sched_note_string(b)
+#  define sched_note_dump(m,e,b,l)
+#  define sched_note_vprintf(f,v)
+#  define sched_note_vbprintf(m,e,f,v)
+#  define sched_note_printf(f...)
+#  define sched_note_bprintf(m,e,f...)
 
 #endif /* CONFIG_SCHED_INSTRUMENTATION */
 #endif /* __INCLUDE_NUTTX_SCHED_NOTE_H */
diff --git a/sched/Kconfig b/sched/Kconfig
index 29761ac..bf111c5 100644
--- a/sched/Kconfig
+++ b/sched/Kconfig
@@ -1038,6 +1038,19 @@ config SCHED_INSTRUMENTATION_IRQHANDLER
 
 			void sched_note_irqhandler(int irq, FAR void *handler, bool enter);
 
+config SCHED_INSTRUMENTATION_DUMP
+	bool "Use note dump for instrumentation"
+	default n
+	---help---
+		Use note dump for instrumentation.
+
+			void sched_note_string(FAR const char *buf);
+			void sched_note_dump(uint32_t module, uint8_t event, FAR const void *buf, size_t len);
+			void sched_note_vprintf(FAR const char *fmt, va_list va);
+			void sched_note_vbprintf(uint32_t module, uint8_t event, FAR const char *fmt, va_list va);
+			void sched_note_printf(FAR const char *fmt, ...) printflike(1, 2);
+			void sched_note_bprintf(uint32_t module, uint8_t event, FAR const char *fmt, ...);
+
 config SCHED_INSTRUMENTATION_HIRES
 	bool "Use Hi-Res RTC for instrumentation"
 	default n
diff --git a/sched/sched/sched_note.c b/sched/sched/sched_note.c
index 59b7f7a..b40db72 100644
--- a/sched/sched/sched_note.c
+++ b/sched/sched/sched_note.c
@@ -24,6 +24,7 @@
 
 #include <nuttx/config.h>
 
+#include <stdio.h>
 #include <stdint.h>
 #include <stdarg.h>
 #include <string.h>
@@ -40,6 +41,18 @@
 #include "sched/sched.h"
 
 /****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* CONFIG_LIBC_LONG_LONG is not a valid selection of the compiler does not
+ * support long long types.
+ */
+
+#ifndef CONFIG_HAVE_LONG_LONG
+#  undef CONFIG_LIBC_LONG_LONG
+#endif
+
+/****************************************************************************
  * Private Types
  ****************************************************************************/
 
@@ -789,6 +802,326 @@ void sched_note_irqhandler(int irq, FAR void *handler, bool enter)
 }
 #endif
 
+#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
+void sched_note_string(FAR const char *buf)
+{
+  FAR struct note_string_s *note;
+  uint8_t data[255];
+  unsigned int length;
+  FAR struct tcb_s *tcb = this_task();
+
+  if (!note_isenabled())
+    {
+      return;
+    }
+
+  note = (FAR struct note_string_s *)data;
+  length = SIZEOF_NOTE_STRING(strlen(buf));
+  if (length > sizeof(data))
+    {
+      length = sizeof(data);
+    }
+
+  /* Format the note */
+
+  note_common(tcb, &note->nst_cmn, length,
+              NOTE_DUMP_STRING);
+
+  memcpy(note->nst_data, buf, length - sizeof(struct note_string_s));
+  data[length - 1] = '\0';
+
+  /* Add the note to circular buffer */
+
+  sched_note_add(note, length);
+}
+
+void sched_note_dump(uint32_t module, uint8_t event,
+                     FAR const void *buf, size_t len)
+{
+  FAR struct note_binary_s *note;
+  char data[255];
+  unsigned int length;
+  FAR struct tcb_s *tcb = this_task();
+
+  if (!note_isenabled())
+    {
+      return;
+    }
+
+  note = (FAR struct note_binary_s *)data;
+  length = SIZEOF_NOTE_BINARY(len);
+  if (length > sizeof(data))
+    {
+      length = sizeof(data);
+    }
+
+  /* Format the note */
+
+  note_common(tcb, &note->nbi_cmn, length,
+              NOTE_DUMP_BINARY);
+
+  note->nbi_module = module;
+  note->nbi_event = event;
+  memcpy(note->nbi_data, buf, length - sizeof(struct note_binary_s) + 1);
+
+  /* Add the note to circular buffer */
+
+  sched_note_add(note, length);
+}
+
+void sched_note_vprintf(FAR const char *fmt, va_list va)
+{
+  FAR struct note_string_s *note;
+  uint8_t data[255];
+  unsigned int length;
+  FAR struct tcb_s *tcb = this_task();
+
+  if (!note_isenabled())
+    {
+      return;
+    }
+
+  note = (FAR struct note_string_s *)data;
+  length = vsnprintf(note->nst_data,
+                     sizeof(data) - sizeof(struct note_string_s),
+                     fmt,
+                     va);
+  length = SIZEOF_NOTE_STRING(length);
+  if (length > sizeof(data))
+    {
+      length = sizeof(data);
+    }
+
+  /* Format the note */
+
+  note_common(tcb, &note->nst_cmn, length,
+              NOTE_DUMP_STRING);
+
+  /* Add the note to circular buffer */
+
+  sched_note_add(note, length);
+}
+
+void sched_note_vbprintf(uint32_t module, uint8_t event,
+                         FAR const char *fmt, va_list va)
+{
+  FAR struct note_binary_s *note;
+  uint8_t data[255];
+  begin_packed_struct union
+    {
+      char c;
+      short s;
+      int i;
+      long l;
+#ifdef CONFIG_LIBC_LONG_LONG
+      long long ll;
+#endif
+      intmax_t im;
+      size_t sz;
+      ptrdiff_t ptr;
+#ifdef CONFIG_HAVE_FLOAT
+      float f;
+#endif
+#ifdef CONFIG_HAVE_DOUBLE
+      double d;
+#endif
+#ifdef CONFIG_HAVE_LONG_DOUBLE
+      long double ld;
+#endif
+    }
+
+  end_packed_struct *var;
+
+  char c;
+  int length;
+  bool search_fmt = 0;
+  int next = 0;
+  FAR struct tcb_s *tcb = this_task();
+
+  if (!note_isenabled())
+    {
+      return;
+    }
+
+  note = (FAR struct note_binary_s *)data;
+  length = sizeof(data) - sizeof(struct note_binary_s) + 1;
+
+  while ((c = *fmt++) != '\0')
+    {
+      if (c != '%' && search_fmt == 0)
+        {
+          continue;
+        }
+
+      search_fmt = 1;
+      var = (FAR void *)&note->nbi_data[next];
+
+      if (c == 'd' || c == 'i' || c == 'u' ||
+          c == 'o' || c == 'x' || c == 'X')
+        {
+          if (*(fmt - 2) == 'h' && *(fmt - 3) == 'h')
+            {
+              if (next + sizeof(var->c) > length)
+                {
+                  break;
+                }
+
+              var->c = va_arg(va, int);
+              next += sizeof(var->c);
+            }
+          else if (*(fmt - 2) == 'h')
+            {
+              if (next + sizeof(var->s) > length)
+                {
+                  break;
+                }
+
+              var->s = va_arg(va, int);
+              next += sizeof(var->s);
+            }
+          else if (*(fmt - 2) == 'j')
+            {
+              if (next + sizeof(var->im) > length)
+                {
+                  break;
+                }
+
+              var->im = va_arg(va, intmax_t);
+              next += sizeof(var->im);
+            }
+#ifdef CONFIG_LIBC_LONG_LONG
+          else if (*(fmt - 2) == 'l' && *(fmt - 3) == 'l')
+            {
+              if (next + sizeof(var->ll) > length)
+                {
+                  break;
+                }
+
+              var->ll = va_arg(va, long long);
+              next += sizeof(var->ll);
+            }
+#endif
+          else if (*(fmt - 2) == 'l')
+            {
+              if (next + sizeof(var->l) > length)
+                {
+                  break;
+                }
+
+              var->l = va_arg(va, long);
+              next += sizeof(var->l);
+            }
+          else if (*(fmt - 2) == 'z')
+            {
+              if (next + sizeof(var->sz) > length)
+                {
+                  break;
+                }
+
+              var->sz = va_arg(va, size_t);
+              next += sizeof(var->sz);
+            }
+          else if (*(fmt - 2) == 't')
+            {
+              if (next + sizeof(var->ptr) > length)
+                {
+                  break;
+                }
+
+              var->ptr = va_arg(va, ptrdiff_t);
+              next += sizeof(var->ptr);
+            }
+          else
+            {
+              if (next + sizeof(var->i) > length)
+                {
+                  break;
+                }
+
+              var->i = va_arg(va, int);
+              next += sizeof(var->i);
+            }
+
+          search_fmt = 0;
+        }
+
+      if (c == 'e' || c == 'f' || c == 'g' ||
+          c == 'E' || c == 'F' || c == 'G')
+        {
+          if (*(fmt - 2) == 'L')
+            {
+#ifdef CONFIG_HAVE_LONG_DOUBLE
+              if (next + sizeof(var->ld) > length)
+                {
+                  break;
+                }
+
+              var->ld = va_arg(va, long double);
+              next += sizeof(var->ld);
+#endif
+            }
+          else if (*(fmt - 2) == 'l')
+            {
+#ifdef CONFIG_HAVE_DOUBLE
+              if (next + sizeof(var->d) > length)
+                {
+                  break;
+                }
+
+              var->d = va_arg(va, double);
+              next += sizeof(var->d);
+#endif
+            }
+          else
+#ifdef CONFIG_HAVE_FLOAT
+            {
+              if (next + sizeof(var->l) > length)
+                {
+                  break;
+                }
+
+              var->l = va_arg(va, double);
+              next += sizeof(var->l);
+#endif
+            }
+
+          search_fmt = 0;
+        }
+    }
+
+  length = SIZEOF_NOTE_BINARY(next);
+
+  /* Format the note */
+
+  note_common(tcb, &note->nbi_cmn, length,
+              NOTE_DUMP_BINARY);
+
+  note->nbi_module = module;
+  note->nbi_event = event;
+
+  /* Add the note to circular buffer */
+
+  sched_note_add(note, length);
+}
+
+void sched_note_printf(FAR const char *fmt, ...)
+{
+  va_list va;
+  va_start(va, fmt);
+  sched_note_vprintf(fmt, va);
+  va_end(va);
+}
+
+void sched_note_bprintf(uint32_t module, uint8_t event,
+                        FAR const char *fmt, ...)
+{
+  va_list va;
+  va_start(va, fmt);
+  sched_note_vbprintf(module, event, fmt, va);
+  va_end(va);
+}
+#endif /* CONFIG_SCHED_INSTRUMENTATION_DUMP */
+
 #ifdef CONFIG_SCHED_INSTRUMENTATION_FILTER
 
 /****************************************************************************