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, ¬e->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, ¬e->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, ¬e->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 *)¬e->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, ¬e->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
/****************************************************************************