gote: implement asynchronous printf formatting
Do not format immediately when calling sched_note_printf, but delay formatting until dump trace. After turning on SYSTEM_NOTE, similar asynchronous syslog functions can be achieved. Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
This commit is contained in:
parent
c87454220d
commit
57a385a994
@ -96,14 +96,10 @@
|
|||||||
((drv)->ops->heap && ((drv)->ops->heap(drv, event, data, mem, size, used), true))
|
((drv)->ops->heap && ((drv)->ops->heap(drv, event, data, mem, size, used), true))
|
||||||
#define note_wdog(drv, event, handler, arg) \
|
#define note_wdog(drv, event, handler, arg) \
|
||||||
((drv)->ops->wdog && ((drv)->ops->wdog(drv, event, handler, arg), true))
|
((drv)->ops->wdog && ((drv)->ops->wdog(drv, event, handler, arg), true))
|
||||||
#define note_string(drv, ip, buf) \
|
|
||||||
((drv)->ops->string && ((drv)->ops->string(drv, ip, buf), true))
|
|
||||||
#define note_event(drv, ip, event, buf, len) \
|
#define note_event(drv, ip, event, buf, len) \
|
||||||
((drv)->ops->event && ((drv)->ops->event(drv, ip, event, buf, len), true))
|
((drv)->ops->event && ((drv)->ops->event(drv, ip, event, buf, len), true))
|
||||||
#define note_vprintf(drv, ip, fmt, va) \
|
#define note_vprintf(drv, ip, fmt, va) \
|
||||||
((drv)->ops->vprintf && ((drv)->ops->vprintf(drv, ip, fmt, va), true))
|
((drv)->ops->vprintf && ((drv)->ops->vprintf(drv, ip, fmt, va), true))
|
||||||
#define note_vbprintf(drv, ip, fmt, va) \
|
|
||||||
((drv)->ops->vbprintf && ((drv)->ops->vbprintf(drv, ip, fmt, va), true))
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
@ -1437,60 +1433,10 @@ void sched_note_heap(uint8_t event, FAR void *heap, FAR void *mem,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
|
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
|
||||||
void sched_note_string_ip(uint32_t tag, uintptr_t ip, FAR const char *buf)
|
|
||||||
{
|
|
||||||
FAR struct note_string_s *note;
|
|
||||||
uint8_t data[255];
|
|
||||||
unsigned int length;
|
|
||||||
FAR struct note_driver_s **driver;
|
|
||||||
bool formatted = false;
|
|
||||||
FAR struct tcb_s *tcb = this_task();
|
|
||||||
|
|
||||||
if (!note_isenabled_dump(tag))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (driver = g_note_drivers; *driver; driver++)
|
|
||||||
{
|
|
||||||
if (note_string(*driver, ip, buf))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*driver)->ops->add == NULL)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Format the note */
|
|
||||||
|
|
||||||
if (!formatted)
|
|
||||||
{
|
|
||||||
formatted = true;
|
|
||||||
note = (FAR struct note_string_s *)data;
|
|
||||||
length = SIZEOF_NOTE_STRING(strlen(buf));
|
|
||||||
if (length > sizeof(data))
|
|
||||||
{
|
|
||||||
length = sizeof(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
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';
|
|
||||||
note->nst_ip = ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the note to circular buffer */
|
|
||||||
|
|
||||||
note_add(*driver, note, length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sched_note_event_ip(uint32_t tag, uintptr_t ip, uint8_t event,
|
void sched_note_event_ip(uint32_t tag, uintptr_t ip, uint8_t event,
|
||||||
FAR const void *buf, size_t len)
|
FAR const void *buf, size_t len)
|
||||||
{
|
{
|
||||||
FAR struct note_binary_s *note;
|
FAR struct note_event_s *note;
|
||||||
FAR struct note_driver_s **driver;
|
FAR struct note_driver_s **driver;
|
||||||
bool formatted = false;
|
bool formatted = false;
|
||||||
char data[255];
|
char data[255];
|
||||||
@ -1519,17 +1465,16 @@ void sched_note_event_ip(uint32_t tag, uintptr_t ip, uint8_t event,
|
|||||||
if (!formatted)
|
if (!formatted)
|
||||||
{
|
{
|
||||||
formatted = true;
|
formatted = true;
|
||||||
note = (FAR struct note_binary_s *)data;
|
note = (FAR struct note_event_s *)data;
|
||||||
length = SIZEOF_NOTE_BINARY(len);
|
length = SIZEOF_NOTE_EVENT(len);
|
||||||
if (length > sizeof(data))
|
if (length > sizeof(data))
|
||||||
{
|
{
|
||||||
length = sizeof(data);
|
length = sizeof(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
note_common(tcb, ¬e->nbi_cmn, length, event);
|
note_common(tcb, ¬e->nev_cmn, length, event);
|
||||||
memcpy(note->nbi_data, buf,
|
note->nev_ip = ip;
|
||||||
length - sizeof(struct note_binary_s) + 1);
|
memcpy(note->nev_data, buf, length - SIZEOF_NOTE_EVENT(0));
|
||||||
note->nbi_ip = ip;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the note to circular buffer */
|
/* Add the note to circular buffer */
|
||||||
@ -1541,11 +1486,36 @@ void sched_note_event_ip(uint32_t tag, uintptr_t ip, uint8_t event,
|
|||||||
void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip,
|
void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip,
|
||||||
FAR const char *fmt, va_list va)
|
FAR const char *fmt, va_list va)
|
||||||
{
|
{
|
||||||
FAR struct note_string_s *note;
|
FAR struct note_printf_s *note;
|
||||||
uint8_t data[255];
|
|
||||||
unsigned int length;
|
|
||||||
FAR struct note_driver_s **driver;
|
FAR struct note_driver_s **driver;
|
||||||
bool formatted = false;
|
bool formatted = false;
|
||||||
|
uint8_t data[255];
|
||||||
|
begin_packed_struct union
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
long l;
|
||||||
|
#ifdef CONFIG_HAVE_LONG_LONG
|
||||||
|
long long ll;
|
||||||
|
#endif
|
||||||
|
intmax_t im;
|
||||||
|
size_t sz;
|
||||||
|
ptrdiff_t ptr;
|
||||||
|
FAR void *p;
|
||||||
|
#ifdef CONFIG_HAVE_DOUBLE
|
||||||
|
double d;
|
||||||
|
# ifdef CONFIG_HAVE_LONG_DOUBLE
|
||||||
|
long double ld;
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
end_packed_struct *var;
|
||||||
|
|
||||||
|
char c;
|
||||||
|
size_t length;
|
||||||
|
size_t next = 0;
|
||||||
|
bool infmt = false;
|
||||||
|
FAR const char *p = fmt;
|
||||||
FAR struct tcb_s *tcb = this_task();
|
FAR struct tcb_s *tcb = this_task();
|
||||||
|
|
||||||
if (!note_isenabled_dump(tag))
|
if (!note_isenabled_dump(tag))
|
||||||
@ -1570,91 +1540,10 @@ void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip,
|
|||||||
if (!formatted)
|
if (!formatted)
|
||||||
{
|
{
|
||||||
formatted = true;
|
formatted = true;
|
||||||
note = (FAR struct note_string_s *)data;
|
note = (FAR struct note_printf_s *)data;
|
||||||
length = vsnprintf(note->nst_data,
|
length = sizeof(data) - SIZEOF_NOTE_PRINTF(0);
|
||||||
sizeof(data) - sizeof(struct note_string_s),
|
|
||||||
fmt,
|
|
||||||
va);
|
|
||||||
length = SIZEOF_NOTE_STRING(length);
|
|
||||||
if (length > sizeof(data))
|
|
||||||
{
|
|
||||||
length = sizeof(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
note_common(tcb, ¬e->nst_cmn, length, NOTE_DUMP_STRING);
|
while ((c = *p++) != '\0')
|
||||||
note->nst_ip = ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the note to circular buffer */
|
|
||||||
|
|
||||||
note_add(*driver, note, length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip,
|
|
||||||
FAR const char *fmt, va_list va)
|
|
||||||
{
|
|
||||||
FAR struct note_binary_s *note;
|
|
||||||
FAR struct note_driver_s **driver;
|
|
||||||
bool formatted = false;
|
|
||||||
uint8_t data[255];
|
|
||||||
begin_packed_struct union
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
short s;
|
|
||||||
int i;
|
|
||||||
long l;
|
|
||||||
#ifdef CONFIG_HAVE_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 infmt = false;
|
|
||||||
int next = 0;
|
|
||||||
FAR struct tcb_s *tcb = this_task();
|
|
||||||
|
|
||||||
if (!note_isenabled_dump(tag))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (driver = g_note_drivers; *driver; driver++)
|
|
||||||
{
|
|
||||||
if (note_vbprintf(*driver, ip, fmt, va))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*driver)->ops->add == NULL)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Format the note */
|
|
||||||
|
|
||||||
if (!formatted)
|
|
||||||
{
|
|
||||||
formatted = true;
|
|
||||||
note = (FAR struct note_binary_s *)data;
|
|
||||||
length = sizeof(data) - sizeof(struct note_binary_s) + 1;
|
|
||||||
|
|
||||||
while ((c = *fmt++) != '\0')
|
|
||||||
{
|
{
|
||||||
if (c != '%' && !infmt)
|
if (c != '%' && !infmt)
|
||||||
{
|
{
|
||||||
@ -1662,32 +1551,12 @@ void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip,
|
|||||||
}
|
}
|
||||||
|
|
||||||
infmt = true;
|
infmt = true;
|
||||||
var = (FAR void *)¬e->nbi_data[next];
|
var = (FAR void *)¬e->npt_data[next];
|
||||||
|
|
||||||
if (c == 'd' || c == 'i' || c == 'u' ||
|
if (c == 'c' || c == 'd' || c == 'i' || c == 'u' ||
|
||||||
c == 'o' || c == 'x' || c == 'X')
|
c == 'o' || c == 'x' || c == 'X')
|
||||||
{
|
{
|
||||||
if (*(fmt - 2) == 'h' && *(fmt - 3) == 'h')
|
if (*(p - 2) == 'j')
|
||||||
{
|
|
||||||
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)
|
if (next + sizeof(var->im) > length)
|
||||||
{
|
{
|
||||||
@ -1698,7 +1567,7 @@ void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip,
|
|||||||
next += sizeof(var->im);
|
next += sizeof(var->im);
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_HAVE_LONG_LONG
|
#ifdef CONFIG_HAVE_LONG_LONG
|
||||||
else if (*(fmt - 2) == 'l' && *(fmt - 3) == 'l')
|
else if (*(p - 2) == 'l' && *(p - 3) == 'l')
|
||||||
{
|
{
|
||||||
if (next + sizeof(var->ll) > length)
|
if (next + sizeof(var->ll) > length)
|
||||||
{
|
{
|
||||||
@ -1709,7 +1578,7 @@ void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip,
|
|||||||
next += sizeof(var->ll);
|
next += sizeof(var->ll);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (*(fmt - 2) == 'l')
|
else if (*(p - 2) == 'l')
|
||||||
{
|
{
|
||||||
if (next + sizeof(var->l) > length)
|
if (next + sizeof(var->l) > length)
|
||||||
{
|
{
|
||||||
@ -1719,7 +1588,7 @@ void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip,
|
|||||||
var->l = va_arg(va, long);
|
var->l = va_arg(va, long);
|
||||||
next += sizeof(var->l);
|
next += sizeof(var->l);
|
||||||
}
|
}
|
||||||
else if (*(fmt - 2) == 'z')
|
else if (*(p - 2) == 'z')
|
||||||
{
|
{
|
||||||
if (next + sizeof(var->sz) > length)
|
if (next + sizeof(var->sz) > length)
|
||||||
{
|
{
|
||||||
@ -1729,7 +1598,7 @@ void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip,
|
|||||||
var->sz = va_arg(va, size_t);
|
var->sz = va_arg(va, size_t);
|
||||||
next += sizeof(var->sz);
|
next += sizeof(var->sz);
|
||||||
}
|
}
|
||||||
else if (*(fmt - 2) == 't')
|
else if (*(p - 2) == 't')
|
||||||
{
|
{
|
||||||
if (next + sizeof(var->ptr) > length)
|
if (next + sizeof(var->ptr) > length)
|
||||||
{
|
{
|
||||||
@ -1752,13 +1621,13 @@ void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip,
|
|||||||
|
|
||||||
infmt = false;
|
infmt = false;
|
||||||
}
|
}
|
||||||
|
else if (c == 'e' || c == 'f' || c == 'g' || c == 'a' ||
|
||||||
if (c == 'e' || c == 'f' || c == 'g' ||
|
c == 'A' || c == 'E' || c == 'F' || c == 'G')
|
||||||
c == 'E' || c == 'F' || c == 'G')
|
|
||||||
{
|
{
|
||||||
if (*(fmt - 2) == 'L')
|
#ifdef CONFIG_HAVE_DOUBLE
|
||||||
|
# ifdef CONFIG_HAVE_LONG_DOUBLE
|
||||||
|
if (*(p - 2) == 'L')
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_HAVE_LONG_DOUBLE
|
|
||||||
if (next + sizeof(var->ld) > length)
|
if (next + sizeof(var->ld) > length)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@ -1766,11 +1635,10 @@ void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip,
|
|||||||
|
|
||||||
var->ld = va_arg(va, long double);
|
var->ld = va_arg(va, long double);
|
||||||
next += sizeof(var->ld);
|
next += sizeof(var->ld);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if (*(fmt - 2) == 'l')
|
else
|
||||||
|
# endif
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_HAVE_DOUBLE
|
|
||||||
if (next + sizeof(var->d) > length)
|
if (next + sizeof(var->d) > length)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@ -1778,28 +1646,46 @@ void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip,
|
|||||||
|
|
||||||
var->d = va_arg(va, double);
|
var->d = va_arg(va, double);
|
||||||
next += sizeof(var->d);
|
next += sizeof(var->d);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
#endif
|
||||||
#ifdef CONFIG_HAVE_FLOAT
|
|
||||||
|
infmt = false;
|
||||||
|
}
|
||||||
|
else if (c == '*')
|
||||||
|
{
|
||||||
|
var->i = va_arg(va, int);
|
||||||
|
next += sizeof(var->i);
|
||||||
|
}
|
||||||
|
else if (c == 's')
|
||||||
|
{
|
||||||
|
FAR char *str = (FAR char *)va_arg(va, FAR char *);
|
||||||
|
size_t len = strlen(str) + 1;
|
||||||
|
if (next + len > length)
|
||||||
{
|
{
|
||||||
if (next + sizeof(var->l) > length)
|
len = length - next;
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var->l = va_arg(va, double);
|
|
||||||
next += sizeof(var->l);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strlcpy(¬e->npt_data[next], str, len);
|
||||||
|
next += len;
|
||||||
|
infmt = false;
|
||||||
|
}
|
||||||
|
else if (c == 'p')
|
||||||
|
{
|
||||||
|
if (next + sizeof(var->p) > length)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var->p = va_arg(va, FAR void *);
|
||||||
|
next += sizeof(var->p);
|
||||||
infmt = false;
|
infmt = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
length = SIZEOF_NOTE_BINARY(next);
|
length = SIZEOF_NOTE_PRINTF(next);
|
||||||
note_common(tcb, ¬e->nbi_cmn, length, NOTE_DUMP_BINARY);
|
note_common(tcb, ¬e->npt_cmn, length, NOTE_DUMP_PRINTF);
|
||||||
note->nbi_ip = ip;
|
note->npt_ip = ip;
|
||||||
|
note->npt_fmt = fmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the note to circular buffer */
|
/* Add the note to circular buffer */
|
||||||
@ -1817,14 +1703,6 @@ void sched_note_printf_ip(uint32_t tag, uintptr_t ip,
|
|||||||
va_end(va);
|
va_end(va);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sched_note_bprintf_ip(uint32_t tag, uintptr_t ip,
|
|
||||||
FAR const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list va;
|
|
||||||
va_start(va, fmt);
|
|
||||||
sched_note_vbprintf_ip(tag, ip, fmt, va);
|
|
||||||
va_end(va);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_SCHED_INSTRUMENTATION_DUMP */
|
#endif /* CONFIG_SCHED_INSTRUMENTATION_DUMP */
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_FILTER
|
#ifdef CONFIG_SCHED_INSTRUMENTATION_FILTER
|
||||||
@ -2051,14 +1929,16 @@ static void note_driver_instrument_enter(FAR void *this_fn,
|
|||||||
FAR void *call_site,
|
FAR void *call_site,
|
||||||
FAR void *arg)
|
FAR void *arg)
|
||||||
{
|
{
|
||||||
sched_note_string_ip(NOTE_TAG_ALWAYS, (uintptr_t)this_fn, "B");
|
sched_note_event_ip(NOTE_TAG_ALWAYS, (uintptr_t)this_fn,
|
||||||
|
NOTE_DUMP_BEGIN, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void note_driver_instrument_leave(FAR void *this_fn,
|
static void note_driver_instrument_leave(FAR void *this_fn,
|
||||||
FAR void *call_site,
|
FAR void *call_site,
|
||||||
FAR void *arg)
|
FAR void *arg)
|
||||||
{
|
{
|
||||||
sched_note_string_ip(NOTE_TAG_ALWAYS, (uintptr_t)this_fn, "E");
|
sched_note_event_ip(NOTE_TAG_ALWAYS, (uintptr_t)this_fn,
|
||||||
|
NOTE_DUMP_END, NULL, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -710,6 +710,151 @@ static int noteram_dump_sched_switch(FAR struct lib_outstream_s *s,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: noteram_dump_printf
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
|
||||||
|
static int noteram_dump_printf(FAR struct lib_outstream_s *s,
|
||||||
|
FAR struct note_printf_s *note)
|
||||||
|
{
|
||||||
|
begin_packed_struct union
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
long l;
|
||||||
|
#ifdef CONFIG_HAVE_LONG_LONG
|
||||||
|
long long ll;
|
||||||
|
#endif
|
||||||
|
intmax_t im;
|
||||||
|
size_t sz;
|
||||||
|
ptrdiff_t pd;
|
||||||
|
uintptr_t p;
|
||||||
|
#ifdef CONFIG_HAVE_DOUBLE
|
||||||
|
double d;
|
||||||
|
# ifdef CONFIG_HAVE_LONG_DOUBLE
|
||||||
|
long double ld;
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
end_packed_struct *var;
|
||||||
|
FAR const char *p = note->npt_fmt;
|
||||||
|
FAR char *data = note->npt_data;
|
||||||
|
char fmtstr[64];
|
||||||
|
bool infmt = false;
|
||||||
|
size_t offset = 0;
|
||||||
|
size_t ret = 0;
|
||||||
|
size_t len = 0;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
while ((c = *p++) != '\0')
|
||||||
|
{
|
||||||
|
if (c != '%' && !infmt)
|
||||||
|
{
|
||||||
|
lib_stream_putc(s, c);
|
||||||
|
ret++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!infmt)
|
||||||
|
{
|
||||||
|
len = 0;
|
||||||
|
infmt = true;
|
||||||
|
memset(fmtstr, 0, sizeof(fmtstr));
|
||||||
|
}
|
||||||
|
|
||||||
|
var = (FAR void *)(note->npt_data + offset);
|
||||||
|
fmtstr[len++] = c;
|
||||||
|
|
||||||
|
if (c == 'c' || c == 'd' || c == 'i' || c == 'u' ||
|
||||||
|
c == 'o' || c == 'x' || c == 'X')
|
||||||
|
{
|
||||||
|
if (*(p - 2) == 'j')
|
||||||
|
{
|
||||||
|
offset += sizeof(var->im);
|
||||||
|
ret += lib_sprintf(s, fmtstr, var->im);
|
||||||
|
}
|
||||||
|
#ifdef CONFIG_HAVE_LONG_LONG
|
||||||
|
else if (*(p - 2) == 'l' && *(p - 3) == 'l')
|
||||||
|
{
|
||||||
|
offset += sizeof(var->ll);
|
||||||
|
ret += lib_sprintf(s, fmtstr, var->ll);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (*(p - 2) == 'l')
|
||||||
|
{
|
||||||
|
offset += sizeof(var->l);
|
||||||
|
ret += lib_sprintf(s, fmtstr, var->l);
|
||||||
|
}
|
||||||
|
else if (*(p - 2) == 'z')
|
||||||
|
{
|
||||||
|
offset += sizeof(var->sz);
|
||||||
|
ret += lib_sprintf(s, fmtstr, var->sz);
|
||||||
|
}
|
||||||
|
else if (*(p - 2) == 't')
|
||||||
|
{
|
||||||
|
offset += sizeof(var->pd);
|
||||||
|
ret += lib_sprintf(s, fmtstr, var->pd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
offset += sizeof(var->i);
|
||||||
|
ret += lib_sprintf(s, fmtstr, var->i);
|
||||||
|
}
|
||||||
|
|
||||||
|
infmt = false;
|
||||||
|
}
|
||||||
|
else if (c == 'e' || c == 'f' || c == 'g' || c == 'a' ||
|
||||||
|
c == 'A' || c == 'E' || c == 'F' || c == 'G')
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_HAVE_DOUBLE
|
||||||
|
# ifdef CONFIG_HAVE_LONG_DOUBLE
|
||||||
|
if (*(p - 2) == 'L')
|
||||||
|
{
|
||||||
|
offset += sizeof(var->ld);
|
||||||
|
ret += lib_sprintf(s, fmtstr, var->ld);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
offset += sizeof(var->d);
|
||||||
|
ret += lib_sprintf(s, fmtstr, var->d);
|
||||||
|
}
|
||||||
|
|
||||||
|
infmt = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (c == '*')
|
||||||
|
{
|
||||||
|
itoa(var->i, fmtstr + len - 1, 10);
|
||||||
|
len = strlen(fmtstr);
|
||||||
|
offset += sizeof(var->i);
|
||||||
|
}
|
||||||
|
else if (c == 's')
|
||||||
|
{
|
||||||
|
FAR const char *value = data + offset;
|
||||||
|
offset += strlen(value) + 1;
|
||||||
|
ret += lib_sprintf(s, fmtstr, value);
|
||||||
|
infmt = false;
|
||||||
|
}
|
||||||
|
else if (c == 'p')
|
||||||
|
{
|
||||||
|
offset += sizeof(var->p);
|
||||||
|
ret += lib_sprintf(s, fmtstr, var->p);
|
||||||
|
infmt = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*(p - 2) != '\n')
|
||||||
|
{
|
||||||
|
lib_stream_putc(s, '\n');
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: noteram_dump_one
|
* Name: noteram_dump_one
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -954,42 +1099,30 @@ static int noteram_dump_one(FAR uint8_t *p, FAR struct lib_outstream_s *s,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
|
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
|
||||||
case NOTE_DUMP_STRING:
|
case NOTE_DUMP_PRINTF:
|
||||||
{
|
{
|
||||||
FAR struct note_string_s *nst;
|
FAR struct note_printf_s *npt;
|
||||||
uintptr_t ip;
|
|
||||||
|
|
||||||
nst = (FAR struct note_string_s *)p;
|
npt = (FAR struct note_printf_s *)p;
|
||||||
ret += noteram_dump_header(s, note, ctx);
|
ret += noteram_dump_header(s, &npt->npt_cmn, ctx);
|
||||||
ip = nst->nst_ip;
|
ret += lib_sprintf(s, "tracing_mark_write: ");
|
||||||
|
ret += noteram_dump_printf(s, npt);
|
||||||
if (nst->nst_data[1] == '\0' &&
|
|
||||||
(nst->nst_data[0] == 'B' || nst->nst_data[0] == 'E'))
|
|
||||||
{
|
|
||||||
ret += lib_sprintf(s, "tracing_mark_write: %c|%d|%pS\n",
|
|
||||||
nst->nst_data[0], pid, (FAR void *)ip);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret += lib_sprintf(s, "tracing_mark_write: %s\n",
|
|
||||||
nst->nst_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NOTE_DUMP_BEGIN:
|
case NOTE_DUMP_BEGIN:
|
||||||
case NOTE_DUMP_END:
|
case NOTE_DUMP_END:
|
||||||
{
|
{
|
||||||
FAR struct note_binary_s *nbi = (FAR struct note_binary_s *)p;
|
FAR struct note_event_s *nbi = (FAR struct note_event_s *)p;
|
||||||
char c = note->nc_type == NOTE_DUMP_BEGIN ? 'B' : 'E';
|
char c = note->nc_type == NOTE_DUMP_BEGIN ? 'B' : 'E';
|
||||||
int len = note->nc_length - SIZEOF_NOTE_EVENT(0);
|
int len = note->nc_length - SIZEOF_NOTE_EVENT(0);
|
||||||
uintptr_t ip;
|
uintptr_t ip;
|
||||||
|
|
||||||
ip = nbi->nbi_ip;
|
ip = nbi->nev_ip;
|
||||||
ret += noteram_dump_header(s, &nbi->nbi_cmn, ctx);
|
ret += noteram_dump_header(s, &nbi->nev_cmn, ctx);
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
ret += lib_sprintf(s, "tracing_mark_write: %c|%d|%.*s\n",
|
ret += lib_sprintf(s, "tracing_mark_write: %c|%d|%.*s\n",
|
||||||
c, pid, len, (FAR const char *)nbi->nbi_data);
|
c, pid, len, (FAR const char *)nbi->nev_data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1000,45 +1133,23 @@ static int noteram_dump_one(FAR uint8_t *p, FAR struct lib_outstream_s *s,
|
|||||||
break;
|
break;
|
||||||
case NOTE_DUMP_MARK:
|
case NOTE_DUMP_MARK:
|
||||||
{
|
{
|
||||||
int len = note->nc_length - sizeof(struct note_binary_s);
|
int len = note->nc_length - sizeof(struct note_event_s);
|
||||||
FAR struct note_binary_s *nbi = (FAR struct note_binary_s *)p;
|
FAR struct note_event_s *nbi = (FAR struct note_event_s *)p;
|
||||||
ret += noteram_dump_header(s, &nbi->nbi_cmn, ctx);
|
ret += noteram_dump_header(s, &nbi->nev_cmn, ctx);
|
||||||
ret += lib_sprintf(s, "tracing_mark_write: I|%d|%.*s\n",
|
ret += lib_sprintf(s, "tracing_mark_write: I|%d|%.*s\n",
|
||||||
pid, len, (FAR const char *)nbi->nbi_data);
|
pid, len, (FAR const char *)nbi->nev_data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NOTE_DUMP_COUNTER:
|
case NOTE_DUMP_COUNTER:
|
||||||
{
|
{
|
||||||
FAR struct note_binary_s *nbi = (FAR struct note_binary_s *)p;
|
FAR struct note_event_s *nbi = (FAR struct note_event_s *)p;
|
||||||
FAR struct note_counter_s *counter;
|
FAR struct note_counter_s *counter;
|
||||||
counter = (FAR struct note_counter_s *)nbi->nbi_data;
|
counter = (FAR struct note_counter_s *)nbi->nev_data;
|
||||||
ret += noteram_dump_header(s, &nbi->nbi_cmn, ctx);
|
ret += noteram_dump_header(s, &nbi->nev_cmn, ctx);
|
||||||
ret += lib_sprintf(s, "tracing_mark_write: C|%d|%s|%ld\n",
|
ret += lib_sprintf(s, "tracing_mark_write: C|%d|%s|%ld\n",
|
||||||
pid, counter->name, counter->value);
|
pid, counter->name, counter->value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NOTE_DUMP_BINARY:
|
|
||||||
{
|
|
||||||
FAR struct note_binary_s *nbi;
|
|
||||||
uint8_t count;
|
|
||||||
uintptr_t ip;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
nbi = (FAR struct note_binary_s *)p;
|
|
||||||
ret += noteram_dump_header(s, note, ctx);
|
|
||||||
count = note->nc_length - sizeof(struct note_binary_s) + 1;
|
|
||||||
ip = nbi->nbi_ip;
|
|
||||||
|
|
||||||
ret += lib_sprintf(s, "tracing_mark_write: %pS: count=%u",
|
|
||||||
(FAR void *)ip, count);
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
ret += lib_sprintf(s, " 0x%x", nbi->nbi_data[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret += lib_sprintf(s, "\n");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_HEAP
|
#ifdef CONFIG_SCHED_INSTRUMENTATION_HEAP
|
||||||
case NOTE_HEAP_ADD:
|
case NOTE_HEAP_ADD:
|
||||||
|
@ -99,14 +99,10 @@ struct note_driver_ops_s
|
|||||||
size_t curused);
|
size_t curused);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
|
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
|
||||||
CODE void (*string)(FAR struct note_driver_s *drv, uintptr_t ip,
|
|
||||||
FAR const char *buf);
|
|
||||||
CODE void (*event)(FAR struct note_driver_s *drv, uintptr_t ip,
|
CODE void (*event)(FAR struct note_driver_s *drv, uintptr_t ip,
|
||||||
uint8_t event, FAR const void *buf, size_t len);
|
uint8_t event, FAR const void *buf, size_t len);
|
||||||
CODE void (*vprintf)(FAR struct note_driver_s *drv, uintptr_t ip,
|
CODE void (*vprintf)(FAR struct note_driver_s *drv, uintptr_t ip,
|
||||||
FAR const char *fmt, va_list va) printf_like(3, 0);
|
FAR const char *fmt, va_list va) printf_like(3, 0);
|
||||||
CODE void (*vbprintf)(FAR struct note_driver_s *drv, uintptr_t ip,
|
|
||||||
FAR const char *fmt, va_list va) printf_like(3, 0);
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -128,20 +128,12 @@
|
|||||||
#define SCHED_NOTE_IP \
|
#define SCHED_NOTE_IP \
|
||||||
({ __label__ __here; __here: (unsigned long)&&__here; })
|
({ __label__ __here; __here: (unsigned long)&&__here; })
|
||||||
|
|
||||||
#define sched_note_string(tag, buf) \
|
|
||||||
sched_note_string_ip(tag, SCHED_NOTE_IP, buf)
|
|
||||||
#define sched_note_event(tag, event, buf, len) \
|
#define sched_note_event(tag, event, buf, len) \
|
||||||
sched_note_event_ip(tag, SCHED_NOTE_IP, event, buf, len)
|
sched_note_event_ip(tag, SCHED_NOTE_IP, event, buf, len)
|
||||||
#define sched_note_dump(tag, buf, len) \
|
|
||||||
sched_note_event_ip(tag, SCHED_NOTE_IP, NOTE_DUMP_BINARY, buf, len)
|
|
||||||
#define sched_note_vprintf(tag, fmt, va) \
|
#define sched_note_vprintf(tag, fmt, va) \
|
||||||
sched_note_vprintf_ip(tag, SCHED_NOTE_IP, fmt, va)
|
sched_note_vprintf_ip(tag, SCHED_NOTE_IP, fmt, va)
|
||||||
#define sched_note_vbprintf(tag, fmt, va) \
|
|
||||||
sched_note_vbprintf_ip(tag, SCHED_NOTE_IP, fmt, va)
|
|
||||||
#define sched_note_printf(tag, fmt, ...) \
|
#define sched_note_printf(tag, fmt, ...) \
|
||||||
sched_note_printf_ip(tag, SCHED_NOTE_IP, fmt, ##__VA_ARGS__)
|
sched_note_printf_ip(tag, SCHED_NOTE_IP, fmt, ##__VA_ARGS__)
|
||||||
#define sched_note_bprintf(tag, fmt, ...) \
|
|
||||||
sched_note_bprintf_ip(tag, SCHED_NOTE_IP, fmt, ##__VA_ARGS__)
|
|
||||||
|
|
||||||
#define sched_note_begin(tag) \
|
#define sched_note_begin(tag) \
|
||||||
sched_note_event(tag, NOTE_DUMP_BEGIN, NULL, 0)
|
sched_note_event(tag, NOTE_DUMP_BEGIN, NULL, 0)
|
||||||
@ -203,8 +195,8 @@ enum note_type_e
|
|||||||
NOTE_HEAP_REMOVE,
|
NOTE_HEAP_REMOVE,
|
||||||
NOTE_HEAP_ALLOC,
|
NOTE_HEAP_ALLOC,
|
||||||
NOTE_HEAP_FREE,
|
NOTE_HEAP_FREE,
|
||||||
NOTE_DUMP_STRING,
|
NOTE_DUMP_PRINTF,
|
||||||
NOTE_DUMP_BINARY,
|
|
||||||
NOTE_DUMP_BEGIN,
|
NOTE_DUMP_BEGIN,
|
||||||
NOTE_DUMP_END,
|
NOTE_DUMP_END,
|
||||||
NOTE_DUMP_MARK,
|
NOTE_DUMP_MARK,
|
||||||
@ -413,25 +405,26 @@ struct note_heap_s
|
|||||||
size_t used;
|
size_t used;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct note_string_s
|
struct note_printf_s
|
||||||
{
|
{
|
||||||
struct note_common_s nst_cmn; /* Common note parameters */
|
struct note_common_s npt_cmn; /* Common note parameters */
|
||||||
uintptr_t nst_ip; /* Instruction pointer called from */
|
uintptr_t npt_ip; /* Instruction pointer called from */
|
||||||
char nst_data[1]; /* String data terminated by '\0' */
|
FAR const char *npt_fmt; /* Printf format string */
|
||||||
|
char npt_data[1]; /* Print arguments */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SIZEOF_NOTE_STRING(n) (sizeof(struct note_string_s) + \
|
#define SIZEOF_NOTE_PRINTF(n) (sizeof(struct note_printf_s) + \
|
||||||
(n) * sizeof(char))
|
((n) - 1) * sizeof(uint8_t))
|
||||||
|
|
||||||
struct note_binary_s
|
struct note_event_s
|
||||||
{
|
{
|
||||||
struct note_common_s nbi_cmn; /* Common note parameters */
|
struct note_common_s nev_cmn; /* Common note parameters */
|
||||||
uintptr_t nbi_ip; /* Instruction pointer called from */
|
uintptr_t nev_ip; /* Instruction pointer called from */
|
||||||
uint8_t nbi_data[1]; /* Binary data */
|
uint8_t nev_data[1]; /* Event data */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SIZEOF_NOTE_BINARY(n) (sizeof(struct note_binary_s) + \
|
#define SIZEOF_NOTE_EVENT(n) (sizeof(struct note_event_s) + \
|
||||||
((n) - 1) * sizeof(uint8_t))
|
((n)) * sizeof(uint8_t))
|
||||||
|
|
||||||
struct note_counter_s
|
struct note_counter_s
|
||||||
{
|
{
|
||||||
@ -589,24 +582,16 @@ void sched_note_heap(uint8_t event, FAR void *heap, FAR void *mem,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
|
#ifdef CONFIG_SCHED_INSTRUMENTATION_DUMP
|
||||||
void sched_note_string_ip(uint32_t tag, uintptr_t ip, FAR const char *buf);
|
|
||||||
void sched_note_event_ip(uint32_t tag, uintptr_t ip, uint8_t event,
|
void sched_note_event_ip(uint32_t tag, uintptr_t ip, uint8_t event,
|
||||||
FAR const void *buf, size_t len);
|
FAR const void *buf, size_t len);
|
||||||
void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt,
|
void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt,
|
||||||
va_list va) printf_like(3, 0);
|
va_list va) printf_like(3, 0);
|
||||||
void sched_note_vbprintf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt,
|
|
||||||
va_list va) printf_like(3, 0);
|
|
||||||
void sched_note_printf_ip(uint32_t tag, uintptr_t ip,
|
void sched_note_printf_ip(uint32_t tag, uintptr_t ip,
|
||||||
FAR const char *fmt, ...) printf_like(3, 4);
|
FAR const char *fmt, ...) printf_like(3, 4);
|
||||||
void sched_note_bprintf_ip(uint32_t tag, uintptr_t ip,
|
|
||||||
FAR const char *fmt, ...) printf_like(3, 4);
|
|
||||||
#else
|
#else
|
||||||
# define sched_note_string_ip(t,ip,b)
|
|
||||||
# define sched_note_event_ip(t,ip,e,b,l)
|
# define sched_note_event_ip(t,ip,e,b,l)
|
||||||
# define sched_note_vprintf_ip(t,ip,f,v)
|
# define sched_note_vprintf_ip(t,ip,f,v)
|
||||||
# define sched_note_vbprintf_ip(t,ip,f,v)
|
|
||||||
# define sched_note_printf_ip(t,ip,f,...)
|
# define sched_note_printf_ip(t,ip,f,...)
|
||||||
# define sched_note_bprintf_ip(t,ip,f,...)
|
|
||||||
#endif /* CONFIG_SCHED_INSTRUMENTATION_DUMP */
|
#endif /* CONFIG_SCHED_INSTRUMENTATION_DUMP */
|
||||||
|
|
||||||
#if defined(__KERNEL__) || defined(CONFIG_BUILD_FLAT)
|
#if defined(__KERNEL__) || defined(CONFIG_BUILD_FLAT)
|
||||||
|
@ -1306,12 +1306,9 @@ config SCHED_INSTRUMENTATION_DUMP
|
|||||||
---help---
|
---help---
|
||||||
Use note dump for instrumentation.
|
Use note dump for instrumentation.
|
||||||
|
|
||||||
void sched_note_string(FAR const char *buf);
|
void sched_note_event_ip(uint32_t tag, uintptr_t ip, uint8_t event, FAR const void *buf, size_t len);
|
||||||
void sched_note_dump(uint32_t module, uint8_t event, FAR const void *buf, size_t len);
|
void sched_note_vprintf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt, va_list va) printf_like(3, 0);
|
||||||
void sched_note_vprintf(FAR const char *fmt, va_list va);
|
void sched_note_printf_ip(uint32_t tag, uintptr_t ip, FAR const char *fmt, ...) printf_like(3, 4);
|
||||||
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, ...) printf_like(1, 2);
|
|
||||||
void sched_note_bprintf(uint32_t module, uint8_t event, FAR const char *fmt, ...);
|
|
||||||
|
|
||||||
config SCHED_INSTRUMENTATION_FUNCTION
|
config SCHED_INSTRUMENTATION_FUNCTION
|
||||||
bool "Enable function auto-tracing"
|
bool "Enable function auto-tracing"
|
||||||
|
Loading…
Reference in New Issue
Block a user